docs: add comprehensive WebFinger documentation

Updated README with complete WebFinger section:

## Overview & Features
- Updated tagline to include WebFinger
- Added 🔍 WebFinger to feature list with use cases

## API Reference - webfinger section

### Complete TypeScript Interfaces
- WebFingerConfig with enabled, resources, collections
- WebFingerResource (JRD structure)
- WebFingerLink (rel, href, type, titles, properties)

### Static Resources Example
- Shows simple acct: URI configuration
- ActivityPub/Mastodon integration example
- Profile page and avatar links

### Content Collection Example
- Team members as discoverable resources
- Template URI patterns: acct:{slug}@example.com
- Builder functions for links and properties
- Schema.org property integration

### Common Use Cases
- ActivityPub/Mastodon federation
- OpenID Connect issuer discovery
- Team profile discovery
- Blog author linking

### Query Format Documentation
- Required resource parameter
- Optional rel filtering
- Example queries

### Technical Notes
- Dynamic route (not prerendered)
- CORS enabled per RFC 7033
- Media type: application/jrd+json
- Template variable reference

## Caching Section
- Added webfinger: 3600 (1 hour) to defaults table

Documentation now covers all 7 discovery mechanisms with examples and best practices.
This commit is contained in:
Ryan Malloy 2025-11-03 09:08:09 -07:00
parent 25ad52e68b
commit cfe3946ca2

133
README.md
View File

@ -1,10 +1,10 @@
# @astrojs/discovery # @astrojs/discovery
> Comprehensive discovery integration for Astro - handles robots.txt, llms.txt, humans.txt, security.txt, canary.txt, and sitemap generation > Comprehensive discovery integration for Astro - handles robots.txt, llms.txt, humans.txt, security.txt, canary.txt, WebFinger, and sitemap generation
## Overview ## Overview
This integration provides automatic generation of all standard discovery files for your Astro site, making it easily discoverable by search engines, LLMs, and humans, while providing security contact information and transparency mechanisms. This integration provides automatic generation of all standard discovery files for your Astro site, making it easily discoverable by search engines, LLMs, humans, and federated services, while providing security contact information and transparency mechanisms.
## Features ## Features
@ -13,6 +13,7 @@ This integration provides automatic generation of all standard discovery files f
- 👥 **humans.txt** - Human-readable credits and tech stack - 👥 **humans.txt** - Human-readable credits and tech stack
- 🔒 **security.txt** - RFC 9116 compliant security contact info - 🔒 **security.txt** - RFC 9116 compliant security contact info
- 🐦 **canary.txt** - Warrant canary for transparency - 🐦 **canary.txt** - Warrant canary for transparency
- 🔍 **WebFinger** - RFC 7033 resource discovery (ActivityPub, OpenID)
- 🗺️ **sitemap.xml** - Automatic sitemap generation - 🗺️ **sitemap.xml** - Automatic sitemap generation
- ⚡ **Dynamic URLs** - Adapts to your `site` config - ⚡ **Dynamic URLs** - Adapts to your `site` config
- 🎯 **Smart Caching** - Optimized cache headers - 🎯 **Smart Caching** - Optimized cache headers
@ -450,6 +451,118 @@ discovery({
- Generates at `/.well-known/canary.txt` - Generates at `/.well-known/canary.txt`
- See [CANARY_SPEC.md](./CANARY_SPEC.md) for full specification - See [CANARY_SPEC.md](./CANARY_SPEC.md) for full specification
##### `webfinger`
Configuration for WebFinger resource discovery (RFC 7033).
**Type:**
```typescript
interface WebFingerConfig {
enabled?: boolean; // Opt-in (default: false)
resources?: WebFingerResource[]; // Static resources
collections?: { // Content collection integration
name: string; // Collection name (e.g., 'team')
resourceTemplate: string; // URI template: 'acct:{slug}@example.com'
subjectTemplate?: string; // Defaults to resourceTemplate
linksBuilder?: (entry: any) => WebFingerLink[];
aliasesBuilder?: (entry: any) => string[];
propertiesBuilder?: (entry: any) => Record<string, string | null>;
}[];
}
interface WebFingerResource {
resource: string; // Resource URI (acct:, https://, etc.)
subject?: string; // Subject (defaults to resource)
aliases?: string[]; // Alternative URIs
properties?: Record<string, string | null>; // URI-based properties
links?: WebFingerLink[]; // Related links
}
interface WebFingerLink {
rel: string; // Link relation (URI or IANA type)
href?: string; // Target URI
type?: string; // Media type
titles?: Record<string, string>; // Titles with language tags
properties?: Record<string, string | null>;
}
```
**Example (Static Resources):**
```typescript
discovery({
webfinger: {
enabled: true,
resources: [
{
resource: 'acct:alice@example.com',
aliases: ['https://example.com/@alice'],
links: [
{
rel: 'http://webfinger.net/rel/profile-page',
type: 'text/html',
href: 'https://example.com/@alice'
},
{
rel: 'self',
type: 'application/activity+json', // ActivityPub/Mastodon
href: 'https://example.com/users/alice'
}
]
}
]
}
})
```
**Example (Content Collection):**
```typescript
discovery({
webfinger: {
enabled: true,
collections: [{
name: 'team', // Astro content collection
resourceTemplate: 'acct:{slug}@example.com',
linksBuilder: (member) => [
{
rel: 'http://webfinger.net/rel/profile-page',
href: `https://example.com/team/${member.slug}`,
type: 'text/html'
},
{
rel: 'http://webfinger.net/rel/avatar',
href: member.data.avatar,
type: 'image/jpeg'
}
],
propertiesBuilder: (member) => ({
'http://schema.org/name': member.data.name,
'http://schema.org/jobTitle': member.data.role
})
}]
}
})
```
**Common Use Cases:**
- **ActivityPub/Mastodon**: Enable federated social network discovery
- **OpenID Connect**: Provide issuer discovery for authentication
- **Team Profiles**: Make team members discoverable across services
- **Author Discovery**: Link blog authors to their profiles/social accounts
**Query Format:**
```
GET /.well-known/webfinger?resource=acct:alice@example.com
GET /.well-known/webfinger?resource=acct:alice@example.com&rel=self
```
**Notes:**
- Dynamic route - not prerendered
- Requires `?resource=` query parameter (RFC 7033)
- Optional `?rel=` parameter filters links
- CORS enabled (`Access-Control-Allow-Origin: *`)
- Media type: `application/jrd+json`
- Template vars: `{slug}`, `{id}`, `{data.fieldName}`, `{siteURL}`
##### `sitemap` ##### `sitemap`
Configuration passed to `@astrojs/sitemap`. Configuration passed to `@astrojs/sitemap`.
@ -488,11 +601,12 @@ Configure HTTP cache headers for discovery files.
**Type:** **Type:**
```typescript ```typescript
interface CachingConfig { interface CachingConfig {
robots?: number; // seconds robots?: number; // seconds
llms?: number; llms?: number;
humans?: number; humans?: number;
security?: number; security?: number;
canary?: number; canary?: number;
webfinger?: number;
sitemap?: number; sitemap?: number;
} }
``` ```
@ -500,12 +614,13 @@ interface CachingConfig {
**Default:** **Default:**
```typescript ```typescript
{ {
robots: 3600, // 1 hour robots: 3600, // 1 hour
llms: 3600, // 1 hour llms: 3600, // 1 hour
humans: 86400, // 24 hours humans: 86400, // 24 hours
security: 86400, // 24 hours security: 86400, // 24 hours
canary: 3600, // 1 hour (check frequently!) canary: 3600, // 1 hour (check frequently!)
sitemap: 3600 // 1 hour webfinger: 3600, // 1 hour
sitemap: 3600 // 1 hour
} }
``` ```