Skip to content

fix: standard.site fixes#1901

Merged
danielroe merged 3 commits intonpmx-dev:mainfrom
fatfingers23:bug/standard-site-blog
Mar 3, 2026
Merged

fix: standard.site fixes#1901
danielroe merged 3 commits intonpmx-dev:mainfrom
fatfingers23:bug/standard-site-blog

Conversation

@fatfingers23
Copy link
Contributor

🧭 Context

Our blog posts should now show on readers like https://pckt.blog/read. Will need to clear all previous site.standard.* records from npmx.dev. Can use pdsls for this https://pdsls.dev/at://did:plc:u5zp7npt5kpueado77kuihyz

  • Moved to atcute for tids and dropped atproto/common. Works a bit better if needed client side and smaller package size if i'm not mistaken
  • Added the .well-known endpoint/ and at:// links on blog posts that the standard.site indexers need
  • change the tid offset for blog posts from file path to slug so it works better on the BlogPostWrapper
  • site.standard.documents now have a published time for when they're uploaded so they surface better

@vercel
Copy link

vercel bot commented Mar 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Mar 3, 2026 4:52pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 3, 2026 4:52pm
npmx-lunaria Ignored Ignored Mar 3, 2026 4:52pm

Request Review

@codecov
Copy link

codecov bot commented Mar 3, 2026

Codecov Report

❌ Patch coverage is 85.71429% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/components/global/BlogPostWrapper.vue 50.00% 1 Missing and 1 partial ⚠️
shared/utils/atproto.ts 93.33% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

This pull request implements deterministic TID (Temporal ID) generation for blog posts and introduces AT Protocol site standard publication metadata. The changes include migrating the TID library from @atproto/common to @atcute/tid, adding utility functions for deterministic blog TID generation and publication resource keys, introducing a new server route to serve site publication metadata at /.well-known/site.standard.publication, updating the site-sync module to use the new TID generation logic and adjusting publication URLs, adding SEO link metadata to the blog post component, and updating related tests and dependencies.

Possibly related PRs

  • feat: add server side atproto blog apis #841: Modifies AT Protocol tooling and constants (modules/standard-site-sync.ts, shared/utils/constants.ts) to integrate deterministic TID generation and update publication behaviour.

Suggested reviewers

  • danielroe
  • whitep4nth3r
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description comprehensively explains the changes: migration from atproto/common to atcute for TIDs, addition of .well-known endpoint and at:// links for standard.site support, TID offset changes from file path to slug, and publishedAt timestamps. The description is directly related to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modules/standard-site-sync.ts (1)

238-251: ⚠️ Potential issue | 🟠 Major

The instanceof XrpcResponseError check is incorrect and will prevent synchronisation.

The code checks checkForBlogResult instanceof XrpcResponseError, but xrpcSafe returns a discriminated union with a .success property, not an XrpcResponseError instance. This check will always be false, causing the code to skip the RecordNotFound logic and fall through to the error log instead.

Elsewhere in the same file (line 272), the code correctly uses if (publicationCheck.success). Use the same pattern here:

if (!checkForBlogResult.success) {
  if (checkForBlogResult.error === 'RecordNotFound') {
🧹 Nitpick comments (2)
shared/utils/constants.ts (1)

13-13: Avoid duplicating the DID literal in two exported constants.

Line 54 duplicates Line 13 exactly. Prefer aliasing to a single source of truth to prevent value drift.

Proposed refactor
-export const NPMX_DEV_DID = 'did:plc:u5zp7npt5kpueado77kuihyz'
+export const NPMX_DEV_DID = NPMX_DID

Also applies to: 54-54

modules/standard-site-sync.ts (1)

89-90: Consider extracting the delay duration to a named constant.

The 2-second delay is pragmatic for allowing indexers to catch up, but the magic number could benefit from being a named constant with documentation explaining its purpose. Additionally, fixed delays can be fragile if indexer performance varies.

💡 Optional improvement
+/** Delay to allow firehose/indexers to process the new publication record */
+const INDEXER_CATCHUP_DELAY_MS = 2_000
+
 // ...inside the hook:
-            // Wait for the firehose and indexers to catch up if we create a publication
-            await new Promise(sleepResolve => setTimeout(sleepResolve, 2_000))
+            // Wait for the firehose and indexers to catch up if we create a publication
+            await new Promise(sleepResolve => setTimeout(sleepResolve, INDEXER_CATCHUP_DELAY_MS))

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0020999 and a10d0df.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • app/components/global/BlogPostWrapper.vue
  • modules/standard-site-sync.ts
  • nuxt.config.ts
  • package.json
  • server/routes/.well-known/site.standard.publication.get.ts
  • server/utils/atproto/utils/likes.ts
  • shared/utils/atproto.ts
  • shared/utils/constants.ts
  • test/unit/server/utils/likes-evolution.spec.ts

@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { BlogPostFrontmatter } from '#shared/schemas/blog'
import { generateBlogTID } from '#shared/utils/atproto'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n app/components/global/BlogPostWrapper.vue | head -30

Repository: npmx-dev/npmx.dev

Length of output: 1162


🏁 Script executed:

fd constants -type f -path "*/shared/*" | head -20

Repository: npmx-dev/npmx.dev

Length of output: 231


🏁 Script executed:

rg "NPMX_DEV_DID" --type ts --type js -B 2 -A 2

Repository: npmx-dev/npmx.dev

Length of output: 1638


Import NPMX_DEV_DID before using it on line 22.

The constant is used in the useHead block but not imported, which will fail type-checking and the build.

Proposed fix
 import type { BlogPostFrontmatter } from '#shared/schemas/blog'
 import { generateBlogTID } from '#shared/utils/atproto'
+import { NPMX_DEV_DID } from '#shared/utils/constants'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { generateBlogTID } from '#shared/utils/atproto'
import type { BlogPostFrontmatter } from '#shared/schemas/blog'
import { generateBlogTID } from '#shared/utils/atproto'
import { NPMX_DEV_DID } from '#shared/utils/constants'

@@ -14,6 +15,15 @@ useSeoMeta({
...(props.frontmatter.draft ? { robots: 'noindex, nofollow' } : {}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd app/components/global && wc -l BlogPostWrapper.vue

Repository: npmx-dev/npmx.dev

Length of output: 83


🏁 Script executed:

cd app/components/global && cat -n BlogPostWrapper.vue | sed -n '1,50p'

Repository: npmx-dev/npmx.dev

Length of output: 2026


🏁 Script executed:

cd app/components/global && grep -r "site.standard.document" --include="*.ts" --include="*.tsx" --include="*.vue" --include="*.js" | head -20

Repository: npmx-dev/npmx.dev

Length of output: 263


🏁 Script executed:

grep -r "NPMX_DEV_DID" --include="*.ts" --include="*.tsx" --include="*.vue" --include="*.js" | head -10

Repository: npmx-dev/npmx.dev

Length of output: 670


🏁 Script executed:

grep -r "generateBlogTID" --include="*.ts" --include="*.tsx" --include="*.vue" --include="*.js" -A 3 | head -30

Repository: npmx-dev/npmx.dev

Length of output: 1466


🏁 Script executed:

cat app/modules/standard-site-sync.ts

Repository: npmx-dev/npmx.dev

Length of output: 126


🏁 Script executed:

grep -r "frontmatter.draft" --include="*.ts" --include="*.tsx" --include="*.vue" --include="*.js" -B 2 -A 2

Repository: npmx-dev/npmx.dev

Length of output: 849


🏁 Script executed:

fd "standard-site-sync" --type f

Repository: npmx-dev/npmx.dev

Length of output: 90


🏁 Script executed:

fd "modules" --type d | head -5

Repository: npmx-dev/npmx.dev

Length of output: 69


🏁 Script executed:

cat modules/standard-site-sync.ts

Repository: npmx-dev/npmx.dev

Length of output: 9654


Guard site.standard.document link emission for draft posts.

Line 15 prevents search engine indexing of drafts with noindex, nofollow, but lines 18-25 unconditionally emit a site.standard.document link containing the draft's identifier. The AT Protocol sync module (standard-site-sync.ts) correctly filters drafts from being synced, so this link points to a non-existent record. However, the link header itself leaks the draft's existence to anything monitoring the page source.

Proposed fix
-useHead({
-  link: [
-    {
-      rel: 'site.standard.document',
-      href: `at://${NPMX_DEV_DID}/site.standard.document/${generateBlogTID(props.frontmatter.date, props.frontmatter.slug)}`,
-    },
-  ],
-})
+if (!props.frontmatter.draft) {
+  useHead({
+    link: [
+      {
+        rel: 'site.standard.document',
+        href: `at://${NPMX_DEV_DID}/site.standard.document/${generateBlogTID(props.frontmatter.date, props.frontmatter.slug)}`,
+      },
+    ],
+  })
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
...(props.frontmatter.draft ? { robots: 'noindex, nofollow' } : {}),
useHead({
link: props.frontmatter.draft ? [] : [
{
rel: 'site.standard.document',
href: `at://${NPMX_DEV_DID}/site.standard.document/${generateBlogTID(props.frontmatter.date, props.frontmatter.slug)}`,
},
],
})

@@ -0,0 +1,6 @@
import { npmxPublicationRkey } from '#shared/utils/atproto'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n server/routes/.well-known/site.standard.publication.get.ts

Repository: npmx-dev/npmx.dev

Length of output: 357


🏁 Script executed:

rg "NPMX_DEV_DID" --type ts --type tsx -A 2 -B 2

Repository: npmx-dev/npmx.dev

Length of output: 88


🏁 Script executed:

rg "NPMX_DEV_DID" -A 2 -B 2

Repository: npmx-dev/npmx.dev

Length of output: 1638


🏁 Script executed:

rg "defineEventHandler|setResponseHeader" shared/utils/constants.ts

Repository: npmx-dev/npmx.dev

Length of output: 43


🏁 Script executed:

fd "nuxt.config" -type f

Repository: npmx-dev/npmx.dev

Length of output: 231


🏁 Script executed:

grep -r "auto-import\|defineEventHandler" . --include="*.config.*" --include="*.json" 2>/dev/null | head -20

Repository: npmx-dev/npmx.dev

Length of output: 43


🏁 Script executed:

find server/routes -name "*.ts" -type f | head -5 | xargs cat

Repository: npmx-dev/npmx.dev

Length of output: 3058


🏁 Script executed:

cat -n server/routes/.well-known/site.standard.publication.get.ts | head -10

Repository: npmx-dev/npmx.dev

Length of output: 357


Import NPMX_DEV_DID from #shared/utils/constants.

Line 5 references NPMX_DEV_DID without importing it, which will cause a runtime error.

Proposed fix
 import { npmxPublicationRkey } from '#shared/utils/atproto'
+import { NPMX_DEV_DID } from '#shared/utils/constants'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { npmxPublicationRkey } from '#shared/utils/atproto'
import { npmxPublicationRkey } from '#shared/utils/atproto'
import { NPMX_DEV_DID } from '#shared/utils/constants'

Comment on lines +18 to +25
useHead({
link: [
{
rel: 'site.standard.document',
href: `at://${NPMX_DEV_DID}/site.standard.document/${generateBlogTID(props.frontmatter.date, props.frontmatter.slug)}`,
},
],
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be done only for production

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { isProduction } from '../config/env' the best check for that?

@danielroe danielroe added this pull request to the merge queue Mar 3, 2026
Merged via the queue into npmx-dev:main with commit 75255f1 Mar 3, 2026
21 checks passed
@github-actions github-actions bot mentioned this pull request Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants