@bryanguffey/astro-standard-site 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,347 +1,575 @@
1
1
  # astro-standard-site
2
2
 
3
- The first Astro integration for [standard.site](https://standard.site) a unified schema for longform publishing on ATProto.
3
+ Publish your Astro blog to the federated web. This package connects your blog to [ATProto](https://atproto.com/) (the protocol behind Bluesky) using the [standard.site](https://standard.site/) schema, enabling:
4
4
 
5
- **Write once, publish everywhere.** Sync your Astro blog with any platform that supports the standard.site lexicon, like [pckt](https://pckt.blog)(**soon**), [Leaflet](https://leaflet.pub)(**soon**), and [Offprint](https://offprint.app)
6
- (also **soon**).
5
+ - **Cross-platform publishing** Your posts appear on Leaflet, WhiteWind, and other ATProto readers
6
+ - **Federated comments** — Display Bluesky replies as comments on your blog
7
+ - **Verified ownership** — Prove you own your content with cryptographic verification
7
8
 
8
- Created with love by Bryan Guffey
9
+ Created with love by *Bryan Guffey*
10
+ ## Installation
9
11
 
10
- ## Features
12
+ ```bash
13
+ npm install @bryanguffey/astro-standard-site
14
+ ```
11
15
 
12
- - 📤 **Publish** — Sync your Astro blog posts to ATProto
13
- - 📥 **Load** — Fetch documents from any ATProto repository
14
- - 💬 **Comments** — Display Bluesky replies as comments on your blog
15
- - 🔄 **Transform** — Convert sidenotes, resolve relative links, extract plain text
16
- - ✅ **Verify** — Generate `.well-known` endpoints and link tags per spec
17
- - 📝 **Type-safe** — Full TypeScript support with Zod schemas
16
+ ## Use Cases
18
17
 
19
- ## Installation
18
+ This package supports multiple workflows:
19
+
20
+ | You want to... | Use |
21
+ |----------------|-----|
22
+ | Show Bluesky replies as comments | `<Comments />` component |
23
+ | Publish Astro posts to ATProto | `StandardSitePublisher` |
24
+ | Pull ATProto posts into Astro | `standardSiteLoader` |
25
+ | Verify you own your content | Verification helpers |
26
+
27
+ You can mix and match — use comments without publishing, or publish without loading, etc.
28
+
29
+ ## Quick Start
30
+
31
+ ### 1. Display Bluesky Comments on Your Blog
32
+
33
+ The fastest way to get started — add federated comments to your existing posts.
34
+
35
+ **Add to your blog post layout:**
36
+
37
+ ```astro
38
+ ---
39
+ // src/layouts/BlogPost.astro
40
+ import Comments from '@bryanguffey/astro-standard-site/components/Comments.astro';
41
+
42
+ const { bskyPostUri } = Astro.props.frontmatter;
43
+ ---
44
+
45
+ <article>
46
+ <slot />
47
+ </article>
48
+
49
+ {bskyPostUri && (
50
+ <Comments
51
+ bskyPostUri={bskyPostUri}
52
+ canonicalUrl={Astro.url.href}
53
+ />
54
+ )}
55
+ ```
56
+
57
+ **Add the field to your content schema:**
58
+
59
+ ```ts
60
+ // src/content/config.ts
61
+ import { defineCollection, z } from 'astro:content';
62
+
63
+ const blog = defineCollection({
64
+ schema: z.object({
65
+ title: z.string(),
66
+ date: z.date(),
67
+ // ... your existing fields
68
+ bskyPostUri: z.string().optional(),
69
+ }),
70
+ });
71
+
72
+ export const collections = { blog };
73
+ ```
74
+
75
+ **Link a post to Bluesky:**
76
+
77
+ 1. Publish your blog post
78
+ 2. Share it on Bluesky
79
+ 3. Copy the post's AT-URI (click ··· → "Copy post link", then convert to AT-URI format)
80
+ 4. Add it to your post's frontmatter:
81
+
82
+ ```yaml
83
+ ---
84
+ title: "My First Federated Post"
85
+ date: 2026-01-15
86
+ bskyPostUri: "at://did:plc:your-did/app.bsky.feed.post/abc123def"
87
+ ---
88
+ ```
89
+
90
+ 5. Rebuild your site — comments now appear!
91
+
92
+ > **Tip:** To get the AT-URI from a Bluesky URL like `https://bsky.app/profile/you.bsky.social/post/abc123def`, the format is `at://did:plc:YOUR_DID/app.bsky.feed.post/abc123def`. You can find your DID at [bsky.app/settings](https://bsky.app/settings).
93
+
94
+ ---
95
+
96
+ ## Full Setup: Publish to ATProto
97
+
98
+ To publish your posts *to* ATProto (not just display comments), you'll need:
99
+
100
+ 1. A Bluesky account (or any ATProto PDS)
101
+ 2. An [app password](https://bsky.app/settings/app-passwords)
102
+
103
+ ### Create a Publication
104
+
105
+ First, create a publication record that represents your blog:
106
+
107
+ ```ts
108
+ // scripts/create-publication.ts
109
+ import { StandardSitePublisher } from '@bryanguffey/astro-standard-site';
110
+
111
+ const publisher = new StandardSitePublisher({
112
+ handle: 'you.bsky.social',
113
+ appPassword: process.env.ATPROTO_APP_PASSWORD!,
114
+ });
115
+
116
+ await publisher.login();
117
+
118
+ const result = await publisher.publishPublication({
119
+ name: 'My Awesome Blog',
120
+ url: 'https://yourblog.com',
121
+ description: 'Thoughts on code, life, and everything',
122
+ // Optional: customize your theme colors (RGB 0-255)
123
+ basicTheme: {
124
+ background: { r: 13, g: 17, b: 23 },
125
+ foreground: { r: 230, g: 237, b: 243 },
126
+ accent: { r: 74, g: 124, b: 155 },
127
+ accentForeground: { r: 255, g: 255, b: 255 },
128
+ },
129
+ });
130
+
131
+ console.log('Publication created!');
132
+ console.log('AT-URI:', result.uri);
133
+ console.log('Save this rkey for verification:', result.uri.split('/').pop());
134
+ ```
135
+
136
+ Run it once:
20
137
 
21
138
  ```bash
22
- npm install astro-standard-site
139
+ ATPROTO_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx" npx tsx scripts/create-publication.ts
23
140
  ```
24
141
 
25
- ## Quick Start
142
+ ### Publish Posts
26
143
 
27
- ### 1. Publish Your Blog Posts to ATProto
144
+ Create a sync script to publish your Astro posts:
28
145
 
29
146
  ```ts
30
147
  // scripts/sync-to-atproto.ts
148
+ import { StandardSitePublisher, transformContent } from '@bryanguffey/astro-standard-site';
31
149
  import { getCollection } from 'astro:content';
32
- import { StandardSitePublisher, transformPost } from 'astro-standard-site';
33
150
 
34
151
  const publisher = new StandardSitePublisher({
35
- identifier: 'your-handle.bsky.social',
36
- password: process.env.ATPROTO_APP_PASSWORD!,
152
+ handle: 'you.bsky.social',
153
+ appPassword: process.env.ATPROTO_APP_PASSWORD!,
37
154
  });
38
155
 
39
156
  await publisher.login();
40
- console.log('Logged in! PDS:', publisher.getPdsUrl());
41
157
 
42
- // Get all blog posts
43
158
  const posts = await getCollection('blog');
44
159
 
45
160
  for (const post of posts) {
46
- if (post.data.draft) continue;
47
-
48
- // Transform Astro post to standard.site format
49
- const doc = transformPost(post, {
50
- siteUrl: 'https://yourblog.com'
161
+ // Transform content for ATProto compatibility
162
+ const transformed = transformContent(post.body, {
163
+ baseUrl: 'https://yourblog.com',
51
164
  });
52
-
53
- // Publish to ATProto
54
- const result = await publisher.publishDocument(doc);
55
- console.log(`Published: ${post.slug} → ${result.uri}`);
56
- }
57
- ```
58
165
 
59
- ### 2. Add Comments from Bluesky
60
-
61
- ```astro
62
- ---
63
- // src/layouts/BlogPost.astro
64
- import Comments from 'astro-standard-site/components/Comments.astro';
65
-
66
- // After publishing, save the Bluesky post URI in your frontmatter
67
- const { bskyPostUri } = Astro.props.post.data;
68
- ---
69
-
70
- <article>
71
- <slot />
72
- </article>
166
+ const result = await publisher.publishDocument({
167
+ site: 'https://yourblog.com',
168
+ path: `/blog/${post.slug}`,
169
+ title: post.data.title,
170
+ description: post.data.description,
171
+ content: {
172
+ $type: 'site.standard.content.markdown',
173
+ text: transformed.markdown,
174
+ version: '1.0',
175
+ },
176
+ textContent: transformed.textContent,
177
+ publishedAt: post.data.date.toISOString(),
178
+ tags: post.data.tags,
179
+ });
73
180
 
74
- <Comments
75
- bskyPostUri={bskyPostUri}
76
- canonicalUrl={Astro.url.href}
77
- />
181
+ console.log(`Published: ${post.data.title}`);
182
+ console.log(` → ${result.uri}`);
183
+ }
78
184
  ```
79
185
 
80
- ### 3. Set Up Verification
186
+ ### Set Up Verification
187
+
188
+ Verification lets platforms confirm you own the content. Create a well-known endpoint:
81
189
 
82
190
  ```ts
83
191
  // src/pages/.well-known/site.standard.publication.ts
84
192
  import type { APIRoute } from 'astro';
85
- import { generatePublicationWellKnown } from 'astro-standard-site';
193
+ import { generatePublicationWellKnown } from '@bryanguffey/astro-standard-site';
86
194
 
87
195
  export const GET: APIRoute = () => {
88
196
  return new Response(
89
197
  generatePublicationWellKnown({
90
- did: 'did:plc:your-did-here',
91
- publicationRkey: 'your-publication-rkey',
198
+ did: 'did:plc:your-did-here', // Your DID
199
+ publicationRkey: '3abc123xyz789', // From create-publication output
92
200
  }),
93
201
  { headers: { 'Content-Type': 'text/plain' } }
94
202
  );
95
203
  };
96
204
  ```
97
205
 
206
+ After deploying, verify it works:
207
+
208
+ ```bash
209
+ curl https://yourblog.com/.well-known/site.standard.publication
210
+ # Should output: at://did:plc:xxx/site.standard.publication/3abc123xyz789
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Components
216
+
217
+ ### `<Comments />`
218
+
219
+ Displays Bluesky replies as a comment section.
220
+
221
+ ```astro
222
+ <Comments
223
+ bskyPostUri="at://did:plc:xxx/app.bsky.feed.post/abc123"
224
+ canonicalUrl="https://yourblog.com/post/my-post"
225
+ maxDepth={3}
226
+ title="Discussion"
227
+ showReplyLink={true}
228
+ class="my-custom-class"
229
+ />
230
+ ```
231
+
232
+ | Prop | Type | Default | Description |
233
+ |------|------|---------|-------------|
234
+ | `bskyPostUri` | `string` | — | AT-URI of the Bluesky announcement post |
235
+ | `canonicalUrl` | `string` | — | URL of your blog post (for mention search) |
236
+ | `maxDepth` | `number` | `3` | Maximum nesting depth for replies |
237
+ | `title` | `string` | `"Comments"` | Section heading |
238
+ | `showReplyLink` | `boolean` | `true` | Show "Reply on Bluesky" link |
239
+ | `class` | `string` | — | Custom CSS class |
240
+
241
+ **Styling:** The component uses CSS custom properties that inherit from your site's theme:
242
+
243
+ ```css
244
+ --color-border-soft
245
+ --color-text-primary
246
+ --color-text-secondary
247
+ --color-text-muted
248
+ --color-text-link
249
+ --color-bg-elevated
250
+ --space-xs, --space-sm, --space-md, --space-lg, --space-xl, --space-2xl
251
+ ```
252
+
253
+ ---
254
+
98
255
  ## API Reference
99
256
 
100
- ### Publisher
257
+ ### `StandardSitePublisher`
258
+
259
+ Handles authentication and publishing to ATProto.
101
260
 
102
261
  ```ts
103
- import { StandardSitePublisher } from 'astro-standard-site';
262
+ import { StandardSitePublisher } from '@bryanguffey/astro-standard-site';
104
263
 
105
264
  const publisher = new StandardSitePublisher({
106
- identifier: 'handle.bsky.social', // or DID
107
- password: process.env.ATPROTO_APP_PASSWORD!,
108
- // service: 'https://...' // Optional: auto-resolved from DID
265
+ handle: 'you.bsky.social', // Your handle
266
+ appPassword: 'xxxx-xxxx-xxxx', // App password (not your main password!)
267
+ // Optional: specify PDS directly (auto-resolved from DID by default)
268
+ pdsUrl: 'https://bsky.social',
109
269
  });
110
270
 
111
271
  await publisher.login();
272
+ ```
273
+
274
+ #### `publishDocument(input)`
112
275
 
113
- // Publish a document
114
- await publisher.publishDocument({
115
- site: 'https://yourblog.com', // Required
116
- title: 'My Post', // Required
117
- publishedAt: new Date().toISOString(), // Required
118
- path: '/blog/my-post', // Optional
119
- description: 'A great post', // Optional
120
- tags: ['tag1', 'tag2'], // Optional
121
- textContent: 'Plain text...', // Optional (for search)
122
- content: { // Optional (for rendering)
276
+ Publish a blog post.
277
+
278
+ ```ts
279
+ const result = await publisher.publishDocument({
280
+ // Required
281
+ site: 'https://yourblog.com',
282
+ title: 'My Post Title',
283
+ publishedAt: '2026-01-15T12:00:00Z',
284
+
285
+ // Recommended
286
+ path: '/blog/my-post',
287
+ description: 'A short excerpt...',
288
+ content: {
123
289
  $type: 'site.standard.content.markdown',
124
- text: '# My Post\n\nFull markdown...',
290
+ text: '# Full markdown content...',
291
+ version: '1.0',
125
292
  },
293
+ textContent: 'Plain text version for search indexing',
294
+
295
+ // Optional
296
+ updatedAt: '2026-01-16T12:00:00Z',
297
+ tags: ['astro', 'atproto'],
126
298
  });
127
299
 
128
- // Publish a publication (your blog itself)
129
- await publisher.publishPublication({
300
+ console.log(result.uri); // at://did:plc:xxx/site.standard.document/3abc...
301
+ console.log(result.cid); // Content hash
302
+ ```
303
+
304
+ #### `publishPublication(input)`
305
+
306
+ Create or update your publication metadata.
307
+
308
+ ```ts
309
+ const result = await publisher.publishPublication({
130
310
  name: 'My Blog',
131
311
  url: 'https://yourblog.com',
132
- description: 'Thoughts and writings',
312
+ description: 'What this blog is about',
313
+ basicTheme: {
314
+ background: { r: 255, g: 255, b: 255 },
315
+ foreground: { r: 0, g: 0, b: 0 },
316
+ accent: { r: 0, g: 102, b: 204 },
317
+ accentForeground: { r: 255, g: 255, b: 255 },
318
+ },
319
+ preferences: {
320
+ showInDiscover: true,
321
+ },
133
322
  });
134
-
135
- // List, update, delete
136
- const docs = await publisher.listDocuments();
137
- await publisher.updateDocument('rkey', { ...updatedData });
138
- await publisher.deleteDocument('rkey');
139
323
  ```
140
324
 
141
- ### Content Transformation
325
+ ### `transformContent(markdown, options)`
326
+
327
+ Transform markdown for ATProto compatibility.
142
328
 
143
329
  ```ts
144
- import {
145
- transformPost, // Full Astro post transformation
146
- transformContent, // Just the markdown body
147
- stripToPlainText, // Extract plain text for textContent
148
- convertSidenotes, // HTML sidenotes → markdown blockquotes
149
- } from 'astro-standard-site';
150
-
151
- // Transform an Astro blog post
152
- const doc = transformPost(post, { siteUrl: 'https://yourblog.com' });
153
-
154
- // Or transform just the content
155
- const { markdown, textContent, wordCount, readingTime } = transformContent(
156
- rawMarkdown,
157
- { siteUrl: 'https://yourblog.com' }
158
- );
159
- ```
330
+ import { transformContent } from '@bryanguffey/astro-standard-site';
160
331
 
161
- #### Sidenote Conversion
332
+ const result = transformContent(markdownString, {
333
+ baseUrl: 'https://yourblog.com', // For resolving relative links
334
+ });
162
335
 
163
- Your HTML sidenotes:
164
- ```html
165
- <div class="sidenote sidenote--tip">
166
- <span class="sidenote-label">Tip</span>
167
- <p>This is helpful!</p>
168
- </div>
336
+ result.markdown; // Cleaned markdown (sidenotes converted, links resolved)
337
+ result.textContent; // Plain text for search indexing
338
+ result.wordCount; // Number of words
339
+ result.readingTime; // Estimated minutes to read
169
340
  ```
170
341
 
171
- Become markdown blockquotes:
172
- ```markdown
173
- > **Tip:** This is helpful!
174
- ```
342
+ **What it does:**
343
+
344
+ - Converts HTML sidenotes to markdown blockquotes
345
+ - Resolves relative links (`/about` → `https://yourblog.com/about`)
346
+ - Strips markdown to plain text for the `textContent` field
347
+ - Calculates word count and reading time
348
+
349
+ ### `standardSiteLoader(config)`
350
+
351
+ Astro Content Layer loader — pull YOUR content written on other platforms (Leaflet, WhiteWind) into your Astro blog.
175
352
 
176
- ### Comments
353
+ **Primary use case:** You write posts on Leaflet, and want them to appear on your Astro site — but NOT the posts you published *from* your Astro site to ATProto.
177
354
 
178
355
  ```ts
179
- import { fetchComments, countComments } from 'astro-standard-site';
356
+ // src/content/config.ts
357
+ import { defineCollection } from 'astro:content';
358
+ import { standardSiteLoader } from '@bryanguffey/astro-standard-site';
180
359
 
181
- // Fetch from a Bluesky post thread
182
- const comments = await fetchComments({
183
- bskyPostUri: 'at://did:plc:xxx/app.bsky.feed.post/abc123',
184
- canonicalUrl: 'https://yourblog.com/post', // Also searches for mentions
185
- maxDepth: 3,
360
+ const federated = defineCollection({
361
+ loader: standardSiteLoader({
362
+ repo: 'me.bsky.social', // Your ATProto handle or DID
363
+ excludeSite: 'https://myblog.com', // Skip posts published FROM your Astro blog
364
+ }),
186
365
  });
187
366
 
188
- console.log(`${countComments(comments)} comments found`);
367
+ export const collections = { federated };
368
+ ```
369
+
370
+ | Option | Type | Description |
371
+ |--------|------|-------------|
372
+ | `repo` | `string` | **Required.** ATProto handle or DID to load from |
373
+ | `excludeSite` | `string` | Skip documents with this site URL (your blog) |
374
+ | `publication` | `string` | Only load documents from this specific site |
375
+ | `limit` | `number` | Max documents to fetch (default: 100) |
376
+ | `service` | `string` | PDS endpoint (default: public API) |
377
+
378
+ **Using loaded documents:**
189
379
 
190
- // Comments are returned as a tree structure
191
- for (const comment of comments) {
192
- console.log(`${comment.author.handle}: ${comment.text}`);
193
- for (const reply of comment.replies || []) {
194
- console.log(` ↳ ${reply.author.handle}: ${reply.text}`);
195
- }
380
+ ```astro
381
+ ---
382
+ // src/pages/federated/[...slug].astro
383
+ import { getCollection } from 'astro:content';
384
+
385
+ const posts = await getCollection('federated');
386
+ ---
387
+
388
+ {posts.map(post => (
389
+ <article>
390
+ <h2><a href={post.data.url}>{post.data.title}</a></h2>
391
+ <time>{post.data.publishedAt.toLocaleDateString()}</time>
392
+ <p>{post.data.description}</p>
393
+
394
+ {/* For plain text display */}
395
+ {post.data.textContent && (
396
+ <div>{post.data.textContent}</div>
397
+ )}
398
+
399
+ {/* Or handle markdown content specifically */}
400
+ {post.data.content?.$type === 'site.standard.content.markdown' && (
401
+ <div set:html={marked(post.data.content.text)} />
402
+ )}
403
+ </article>
404
+ ))}
405
+ ```
406
+
407
+ **Loaded document fields:**
408
+
409
+ | Field | Type | Description |
410
+ |-------|------|-------------|
411
+ | `id` | `string` | Record key (TID) |
412
+ | `uri` | `string` | Full AT-URI |
413
+ | `title` | `string` | Document title |
414
+ | `site` | `string` | Source publication URL |
415
+ | `publishedAt` | `Date` | Publication date |
416
+ | `path` | `string?` | Path segment |
417
+ | `url` | `string?` | Full URL (site + path) |
418
+ | `description` | `string?` | Excerpt |
419
+ | `tags` | `string[]` | Categories |
420
+ | `textContent` | `string?` | Plain text for display/search |
421
+ | `content` | `unknown` | Platform-specific content (see below) |
422
+ | `_raw` | `Document` | Full raw record |
423
+
424
+ **About the `content` field:**
425
+
426
+ The `content` field is an open union — different platforms use different types. Use `textContent` for simple display, or check `content.$type` for rich rendering:
427
+
428
+ ```ts
429
+ // Markdown content (Leaflet, this package)
430
+ if (post.data.content?.$type === 'site.standard.content.markdown') {
431
+ const markdown = post.data.content.text;
196
432
  }
433
+
434
+ // Or just use textContent for plain text
435
+ const plainText = post.data.textContent;
197
436
  ```
198
437
 
199
- ### Loader (Fetch from ATProto)
438
+ ### `publicationLoader(config)`
439
+
440
+ Load publication metadata (blog info, not posts):
200
441
 
201
442
  ```ts
202
- // src/content/config.ts
203
- import { defineCollection } from 'astro:content';
204
- import { standardSiteLoader } from 'astro-standard-site';
205
-
206
- // Load documents from any ATProto account
207
- const externalBlog = defineCollection({
208
- loader: standardSiteLoader({
209
- repo: 'someone.bsky.social',
210
- // publication: 'at://...', // Optional: filter by publication
211
- // limit: 50, // Optional: max documents
212
- }),
443
+ const publications = defineCollection({
444
+ loader: publicationLoader({ repo: 'someone.bsky.social' }),
213
445
  });
214
-
215
- export const collections = { externalBlog };
216
446
  ```
217
447
 
218
- ### Verification
448
+ ### `fetchComments(options)`
449
+
450
+ Fetch comments programmatically (used internally by the Comments component).
219
451
 
220
452
  ```ts
221
- import {
222
- generatePublicationWellKnown,
223
- generateDocumentLinkTag,
224
- } from 'astro-standard-site';
453
+ import { fetchComments } from '@bryanguffey/astro-standard-site';
225
454
 
226
- // For /.well-known/site.standard.publication
227
- const wellKnown = generatePublicationWellKnown({
228
- did: 'did:plc:xxx',
229
- publicationRkey: 'my-blog',
455
+ const comments = await fetchComments({
456
+ bskyPostUri: 'at://did:plc:xxx/app.bsky.feed.post/abc123',
457
+ canonicalUrl: 'https://yourblog.com/post/my-post',
458
+ maxDepth: 3,
230
459
  });
231
- // Returns: "at://did:plc:xxx/site.standard.publication/my-blog"
232
460
 
233
- // For document <head>
234
- const linkTag = generateDocumentLinkTag({
235
- did: 'did:plc:xxx',
236
- documentRkey: 'abc123',
237
- });
238
- // Returns: '<link rel="site.standard.document" href="at://did:plc:xxx/site.standard.document/abc123">'
461
+ // Returns array of Comment objects with nested replies
239
462
  ```
240
463
 
241
- ## The standard.site Lexicon
242
-
243
- This package implements the full [standard.site](https://standard.site) specification:
244
-
245
- ### `site.standard.publication`
246
- Represents your blog/publication:
247
- - `url` (required) — Base URL
248
- - `name` (required) — Publication name
249
- - `description` — Brief description
250
- - `icon` — Square image (256x256+, max 1MB)
251
- - `basicTheme` — Color theme for platforms
252
- - `preferences` — Platform-specific settings
253
-
254
- ### `site.standard.document`
255
- Represents a blog post:
256
- - `site` (required) — Publication URL or AT-URI
257
- - `title` (required) — Post title
258
- - `publishedAt` (required) — ISO 8601 datetime
259
- - `path` — URL path (combines with site)
260
- - `description` — Excerpt/summary
261
- - `tags` — Array of tags
262
- - `updatedAt` — Last modified datetime
263
- - `coverImage` — Hero image (max 1MB)
264
- - `textContent` — Plain text for search/indexing
265
- - `content` — Rich content (open union, platform-specific)
266
- - `bskyPostRef` — Link to Bluesky announcement post
267
-
268
- ## Workflow: Full Blog Sync
269
-
270
- Here's a complete workflow for syncing your Astro blog:
464
+ ### Verification Helpers
271
465
 
272
466
  ```ts
273
- // scripts/sync.ts
274
- import { getCollection } from 'astro:content';
275
467
  import {
276
- StandardSitePublisher,
277
- transformPost,
278
- } from 'astro-standard-site';
279
-
280
- async function sync() {
281
- const publisher = new StandardSitePublisher({
282
- identifier: process.env.ATPROTO_IDENTIFIER!,
283
- password: process.env.ATPROTO_APP_PASSWORD!,
284
- });
285
-
286
- await publisher.login();
287
- const did = publisher.getDid();
288
-
289
- // First, ensure publication exists
290
- const pubs = await publisher.listPublications();
291
- if (pubs.length === 0) {
292
- await publisher.publishPublication({
293
- name: 'My Blog',
294
- url: 'https://myblog.com',
295
- description: 'My thoughts and writings',
296
- rkey: 'my-blog',
297
- });
298
- }
299
-
300
- // Get existing documents
301
- const existing = await publisher.listDocuments();
302
- const existingByPath = new Map(
303
- existing.map(d => [d.value.path, d])
304
- );
305
-
306
- // Sync all posts
307
- const posts = await getCollection('blog');
308
-
309
- for (const post of posts) {
310
- if (post.data.draft) continue;
311
-
312
- const doc = transformPost(post, { siteUrl: 'https://myblog.com' });
313
- const existingDoc = existingByPath.get(doc.path);
314
-
315
- if (existingDoc) {
316
- // Update existing
317
- const rkey = existingDoc.uri.split('/').pop()!;
318
- await publisher.updateDocument(rkey, doc);
319
- console.log(`Updated: ${post.slug}`);
320
- } else {
321
- // Create new
322
- const result = await publisher.publishDocument(doc);
323
- console.log(`Created: ${post.slug} → ${result.uri}`);
324
- }
325
- }
326
-
327
- console.log('Sync complete!');
328
- }
468
+ generatePublicationWellKnown,
469
+ generateDocumentLinkTag,
470
+ getDocumentAtUri,
471
+ getPublicationAtUri,
472
+ parseAtUri,
473
+ } from '@bryanguffey/astro-standard-site';
474
+
475
+ // For /.well-known/site.standard.publication endpoint
476
+ generatePublicationWellKnown({ did: '...', publicationRkey: '...' });
477
+ // → "at://did:plc:xxx/site.standard.publication/abc123"
478
+
479
+ // For <head> tag to verify individual documents
480
+ generateDocumentLinkTag({ did: '...', documentRkey: '...' });
481
+ // '<link rel="site.standard.document" href="at://...">'
482
+
483
+ // Build AT-URIs
484
+ getDocumentAtUri('did:plc:xxx', '3abc123');
485
+ // "at://did:plc:xxx/site.standard.document/3abc123"
486
+
487
+ // Parse AT-URIs
488
+ parseAtUri('at://did:plc:xxx/site.standard.document/3abc123');
489
+ // → { did: 'did:plc:xxx', collection: 'site.standard.document', rkey: '3abc123' }
490
+ ```
491
+
492
+ ---
329
493
 
330
- sync().catch(console.error);
494
+ ## Workflow Tips
495
+
496
+ ### Getting Your DID
497
+
498
+ Your DID is your permanent identifier on ATProto. Find it at:
499
+ - [bsky.app/settings](https://bsky.app/settings) → scroll to "DID"
500
+ - Or: `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=you.bsky.social`
501
+
502
+ ### Getting AT-URIs from Bluesky URLs
503
+
504
+ Bluesky web URLs look like:
505
+ ```
506
+ https://bsky.app/profile/you.bsky.social/post/3abc123xyz
331
507
  ```
332
508
 
333
- Run with:
334
- ```bash
335
- ATPROTO_IDENTIFIER="you.bsky.social" \
336
- ATPROTO_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx" \
337
- npx tsx scripts/sync.ts
509
+ The AT-URI format is:
338
510
  ```
511
+ at://did:plc:YOUR_DID/app.bsky.feed.post/3abc123xyz
512
+ ```
513
+
514
+ ### Viewing Your Published Content
515
+
516
+ After publishing, view your records at:
517
+ - `https://pdsls.dev/at://YOUR_DID/site.standard.publication`
518
+ - `https://pdsls.dev/at://YOUR_DID/site.standard.document`
519
+
520
+ ### Comments Appear at Build Time
521
+
522
+ Comments are fetched when you build your site (static). To show new comments, rebuild and redeploy. For high-traffic sites, consider scheduled rebuilds or on-demand ISR.
523
+
524
+ ---
525
+
526
+ ## Troubleshooting
527
+
528
+ ### "Failed to resolve handle"
529
+
530
+ - Check your handle is correct
531
+ - Verify your PDS is reachable
532
+ - Make sure you're using an app password, not your main password
533
+
534
+ ### "Schema validation failed" / "invalid TID"
535
+
536
+ Record keys must be TIDs (timestamp identifiers). The package generates these automatically — if you see this error, you may be using an older version or passing a custom rkey.
537
+
538
+ ### Comments not appearing
339
539
 
340
- ## Resources
540
+ 1. Verify the `bskyPostUri` is correct (AT-URI format, not web URL)
541
+ 2. Check the Bluesky post exists and has public replies
542
+ 3. Rebuild your site after adding the URI
341
543
 
342
- - [standard.site specification](https://standard.site)
343
- - [ATProto documentation](https://atproto.com)
344
- - [pdsls.dev](https://pdsls.dev) Browse ATProto repositories
544
+ ### Verification endpoint returning 404
545
+
546
+ - Ensure the file is at `src/pages/.well-known/site.standard.publication.ts`
547
+ - The `.well-known` folder needs to be inside `pages/`
548
+ - Check your hosting platform allows `.well-known` paths
549
+
550
+ ---
551
+
552
+ ## How It Works
553
+
554
+ This package implements the [standard.site](https://standard.site/) specification, which defines a common schema for longform content on ATProto. This means:
555
+
556
+ 1. **Your content is portable** — It lives in your ATProto repository, not locked to any platform
557
+ 2. **Multiple readers** — Leaflet, WhiteWind, and future apps can all display your posts
558
+ 3. **Federated engagement** — Comments and likes from any ATProto app appear on your blog
559
+ 4. **Verified ownership** — The `.well-known` endpoint proves you control the content
560
+
561
+ ---
562
+
563
+ ## Links
564
+
565
+ - [standard.site specification](https://standard.site/)
566
+ - [ATProto documentation](https://atproto.com/)
567
+ - [Bluesky](https://bsky.app/)
568
+ - [Leaflet](https://leaflet.pub/) — ATProto blog reader
569
+ - [WhiteWind](https://whitewind.pages.dev/) — Another ATProto blog platform
570
+ - [pdsls.dev](https://pdsls.dev/) — Browse ATProto records
571
+
572
+ ---
345
573
 
346
574
  ## License
347
575
 
@@ -19,8 +19,8 @@
19
19
  * ```
20
20
  */
21
21
 
22
- import type { Comment } from '../src/comments';
23
- import { fetchComments, countComments } from '../src/comments';
22
+ import type { Comment } from '../dist/comments.js';
23
+ import { fetchComments, countComments } from '../dist/comments.js';
24
24
 
25
25
  interface Props {
26
26
  /** AT-URI of the Bluesky announcement post */
package/dist/schemas.d.ts CHANGED
@@ -1035,6 +1035,14 @@ export declare const LoaderConfigSchema: z.ZodObject<{
1035
1035
  repo: z.ZodString;
1036
1036
  /** PDS service URL (defaults to public.api.bsky.app for reads) */
1037
1037
  service: z.ZodDefault<z.ZodString>;
1038
+ /**
1039
+ * Exclude documents from this site URL.
1040
+ * Primary use case: exclude posts you published FROM your Astro blog,
1041
+ * so you only load posts written on other platforms (Leaflet, WhiteWind).
1042
+ *
1043
+ * @example excludeSite: 'https://myblog.com'
1044
+ */
1045
+ excludeSite: z.ZodOptional<z.ZodString>;
1038
1046
  /** Only load documents from a specific site/publication URI */
1039
1047
  publication: z.ZodOptional<z.ZodString>;
1040
1048
  /** Maximum number of documents to load */
@@ -1043,11 +1051,13 @@ export declare const LoaderConfigSchema: z.ZodObject<{
1043
1051
  service: string;
1044
1052
  limit: number;
1045
1053
  repo: string;
1054
+ excludeSite?: string | undefined;
1046
1055
  publication?: string | undefined;
1047
1056
  }, {
1048
1057
  repo: string;
1049
1058
  service?: string | undefined;
1050
1059
  limit?: number | undefined;
1060
+ excludeSite?: string | undefined;
1051
1061
  publication?: string | undefined;
1052
1062
  }>;
1053
1063
  export type LoaderConfig = z.infer<typeof LoaderConfigSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
package/dist/schemas.js CHANGED
@@ -126,6 +126,14 @@ export const LoaderConfigSchema = z.object({
126
126
  repo: z.string(),
127
127
  /** PDS service URL (defaults to public.api.bsky.app for reads) */
128
128
  service: z.string().url().default('https://public.api.bsky.app'),
129
+ /**
130
+ * Exclude documents from this site URL.
131
+ * Primary use case: exclude posts you published FROM your Astro blog,
132
+ * so you only load posts written on other platforms (Leaflet, WhiteWind).
133
+ *
134
+ * @example excludeSite: 'https://myblog.com'
135
+ */
136
+ excludeSite: z.string().optional(),
129
137
  /** Only load documents from a specific site/publication URI */
130
138
  publication: z.string().optional(),
131
139
  /** Maximum number of documents to load */
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bryanguffey/astro-standard-site",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "Astro integration for standard.site - unified ATProto longform publishing",
5
5
  "keywords": [
6
6
  "astro",