Skip to content

feat: improve agent readability and discovery#2233

Merged
atinux merged 32 commits intomainfrom
feat/agent-readability
May 4, 2026
Merged

feat: improve agent readability and discovery#2233
atinux merged 32 commits intomainfrom
feat/agent-readability

Conversation

@benjamincanac
Copy link
Copy Markdown
Member

@benjamincanac benjamincanac commented Apr 29, 2026

📚 Description

Improves nuxt.com's discoverability and readability for AI agents, following the Vercel agent-readability spec.

  • Discovery: /.well-known/api-catalog (RFC 9727), /.well-known/mcp/server-card.json (SEP-1649), RFC 8288 Link headers, Content-Signal in robots.txt, Vary: Accept, User-Agent on negotiated routes.
  • Markdown for agents: Accept: text/markdown and AI user-agent rewrites (Vercel edge), markdown alternate <link> per page via useCanonical composable, /sitemap.md, /raw/index.md, /raw/modules.md, /raw/changelog.md.
  • Structured data: Migrate to nuxt-schema-org v6 — Organization + WebSite + per-page TechArticle/BreadcrumbList JSON-LD, site-wide canonicals, <lastmod> on sitemap.xml, 302 on docs version redirects.
  • OG Image v6: Migrate to nuxt-og-image v6 with Takumi renderer, zeroRuntime: true, replace defineOgImageComponentdefineOgImage across all pages.
  • Caching: /raw/** and /.well-known/** use defineCachedEventHandler (SWR, 1h).
  • Cleanup: Centralize docs versions in shared/utils/docs.ts, drop queryCollectionWithEvent type cast, drive /raw/index.md from content/index.yml, trim /llms.txt 127 KB → 51 KB.

Publish well-known agent endpoints (RFC 9727 API catalog, MCP server card),
declare AI usage preferences via Content-Signal in robots.txt, and advertise
related resources via RFC 8288 Link headers and Vary: Accept, User-Agent on
agent-relevant routes. Extend md-rewrite to negotiate markdown via the Accept
header and known AI user agents (Vercel only). Add /raw/index.md as the
markdown counterpart of the (data-driven) homepage.
Set canonical URLs and a markdown alternate link site-wide via app.vue, plus
Organization + WebSite JSON-LD on every page, SoftwareApplication on the
homepage, and TechArticle + BreadcrumbList on docs pages. JSON-LD output is
HTML-escaped to prevent injection. Replace the meta-refresh stub used by the
docs version middleware with a real 301 so agents and crawlers follow it
without losing the canonical and structured data.
Publish a markdown sitemap at /sitemap.md so agents can list every page
without parsing XML. Add <lastmod> entries to sitemap.xml (post date for
blog, today for docs). Add a Nitro plugin that drops the v3 (legacy) and
v5 (nightly) sections from /llms.txt to keep it under the agent context
window threshold (127 KB → 51 KB); the full content is still served via
/llms-full.txt.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 29, 2026

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

Project Deployment Actions Updated (UTC)
nuxt Ready Ready Preview, Comment May 4, 2026 0:55am

Pull all hardcoded host strings through useSiteConfig() / getSiteConfig(event)
so canonical, JSON-LD, markdown alternate, sitemap.xml, sitemap.md and the
well-known endpoints all use the runtime origin. RFC 8288 Link headers on /
become relative URIs so they resolve to the request origin on previews,
production and localhost. nuxt-site-config-kit auto-detects VERCEL_URL etc.,
so the production site.url is provided by the deployment env (and the existing
$development override keeps localhost working in dev).

Switch /sitemap.md from ISR (with a redundant defineCachedEventHandler) to
plain prerender — the underlying collections are static, so a single build-
time render is enough.

Local audit goes from 73 to 77: JSON-LD, canonical (5/5), and markdown
alternate now surface to the auditor since sitemap.xml entries finally
point at the audited origin.
- Drop the v5 (nightly) section from /sitemap.md and skip /docs/5.x/* in the
  Vercel md-rewrite rules so the agent surfaces stay consistent with
  robots.txt's `Disallow: /docs/5.x/`.
- Switch the docs version middleware redirect from 301 to 302 so the target
  can flip to /docs/5.x/* when Nuxt 5 ships without leaving stale 301s
  cached forever in browsers and CDNs.
- Drop the redundant `transport` field on the MCP server card (only
  `endpoints[]` is in the current SEP-1649 shape).
- Advertise `<rel="alternate"; type="text/html">` alongside the canonical
  Link on /raw/index.md so agents that landed on the markdown copy can
  find the rich HTML page.
- Remove the hardcoded `softwareVersion: '4'` from the homepage JSON-LD —
  it would silently go stale when 5 ships and is optional in
  schema.org/SoftwareApplication.
- Use setResponseHeader consistently across the agent-facing routes.
- Pin api-catalog and MCP server card service-doc / documentation links to
  /docs/4.x/guide/ai/mcp so agents skip the docs version redirect hop.
/sitemap.md was listing v3 (legacy) and v5 (nightly) docs while
/sitemap.xml only ships v4 + blog. Drop the v3 section so both sitemaps
agree on what's surfaced to agents and crawlers; v5 was already removed
in the previous commit.
- Hardcode `https://nuxt.com` in /.well-known/api-catalog and
  /.well-known/mcp/server-card.json so previews advertise the canonical
  MCP server (matches nuxt/ui pattern).
- Wrap getSiteConfig(event).url with withoutTrailingSlash in the deploy-
  specific routes (sitemap.xml, sitemap.md, raw/index.md) to fix double
  slashes in generated URLs.
- app/app.vue: suppress canonical on unversioned /docs/* (meta-refresh
  stubs that the docs-version middleware redirects elsewhere should not
  advertise themselves as canonical).
- app/pages/docs/[...slug].vue: guard prerenderRoutes() with
  import.meta.server so it doesn't run on every client navigation.
- app/middleware/docs-version.global.ts: comment was overstating the
  benefit — prerendered pages still emit a meta-refresh stub; the 302
  only applies to dynamic renders.
- server/routes: standardize on defineEventHandler (auto-imported) and
  drop the manual h3 imports.
- modules/md-rewrite.ts: type the nitro arg as Nitro and tighten the
  negotiated rewrites from (.*) to (.+) so /blog/, /deploy/ trailing-
  slash variants don't rewrite to /raw/blog/.md.
When Vercel rewrites /docs/foo to /raw/docs/foo.md based on Accept or
User-Agent, the cached response at /raw/docs/foo.md must also carry
Vary: Accept, User-Agent — otherwise CDNs may serve cached markdown
to a browser that asked for HTML, or vice versa.

Picked up by the @vercel/agent-readability audit:
"Vary: Accept missing — without it CDNs serve cached HTML to agents
or markdown to browsers".
@atinux atinux merged commit 2eae4df into main May 4, 2026
14 checks passed
@atinux atinux deleted the feat/agent-readability branch May 4, 2026 13:00
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.

3 participants