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:
parent
25ad52e68b
commit
cfe3946ca2
133
README.md
133
README.md
@ -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
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user