Skip to content

feat(seo): make the site + bot API legible to AI agents and crawlers#346

Merged
QSchlegel merged 2 commits into
preprodfrom
claude/ai-crawler-bot-api-access
Jul 22, 2026
Merged

feat(seo): make the site + bot API legible to AI agents and crawlers#346
QSchlegel merged 2 commits into
preprodfrom
claude/ai-crawler-bot-api-access

Conversation

@QSchlegel

Copy link
Copy Markdown
Collaborator

Why

The whole UI renders behind an ssr:false MeshProvider boundary, so a no-JS fetch — search crawlers, social unfurlers, ChatGPT's URL fetcher / GPTBot, curl — receives an empty <div id="__next">. Nothing tells a fetcher what the app is or how to drive its bot API.

What

  • Server-render JSON-LD in <head> (was injected client-only via json-ld.tsx), so structured data is in the initial HTML for every fetcher. Preserves the per-page extraJsonLd merge; escapes << (valid JSON, breakout-proof, no raw-HTML prop). json-ld.tsx deleted (was only used here).
  • SeoFallback — a <noscript> content block rendered outside the ssr:false boundary (like Metatags): product overview, links to every public route, and a "Bot API for AI agents" section. JS visitors never render it.
  • /llms.txt (llmstxt.org) — machine-readable orientation for AI agents: the bot-API entry points (/api/swagger, /api/skill, /api-docs) plus a self-contained quickstart (4-step onboarding, bearer auth, scopes, key endpoints). Built from @/lib/seo, kept in sync with api/v1/README.md (register-without-address, botAuth binds it, botRotateSecret, observer ballot access).
  • OpenAPI servers — absolute base URL added to the spec so /api/swagger is self-locating for tooling / codegen / LLMs.

Verification

  • src/__tests__/seoFallback.test.ts — 9 tests (fallback renders inside <noscript> with description + all public/bot-API links; /llms.txt structure, onboarding steps, spec/skill links; JSON-LD route gating). All pass.
  • tsc clean for all changed files. (The worktree shows pre-existing environmental errors from uninstalled e2e/notifications deps — unrelated to this PR.)

Not in this PR (infra)

Cloudflare's managed robots.txt at the edge Disallow: /s GPTBot/ClaudeBot/etc. — a zone/dashboard setting, not code. On-demand ChatGPT browse (ChatGPT-User) isn't blocked, so that path works from this change alone.

🤖 Generated with Claude Code

The whole UI renders behind an ssr:false MeshProvider boundary, so a no-JS
fetch (search crawlers, social unfurlers, ChatGPT's URL fetcher / GPTBot,
curl) receives an empty <div id="__next"> — nothing describing the app or
how to use its bot API.

- Server-render the JSON-LD structured data in <head> (was injected
  client-only), so it appears in the initial HTML for every fetcher.
  Preserves the per-page extraJsonLd merge.
- Add a <noscript> content fallback (SeoFallback), rendered outside the
  ssr:false boundary: product overview, links to every public route, and a
  "Bot API for AI agents" section. JS visitors never render it.
- Add /llms.txt (llmstxt.org): machine-readable orientation for AI agents —
  the bot-API entry points plus a self-contained quickstart (onboarding,
  bearer auth, scopes, key endpoints), built from @/lib/seo and kept in sync
  with api/v1/README.md.
- Give the OpenAPI spec an absolute `servers` URL so /api/swagger is
  self-locating for tooling / codegen / LLMs.
- Tests covering the fallback output, bot-API links, and llms.txt content.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
multisig Ready Ready Preview, Comment Jul 22, 2026 2:32pm

Request Review

Add the new /llms.txt discovery file to INDEXABLE_ROUTES so it appears in
/sitemap.xml alongside the other indexable routes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@QSchlegel
QSchlegel merged commit 0a395ba into preprod Jul 22, 2026
5 of 6 checks passed
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.

1 participant