diff --git a/docs/package.json b/docs/package.json index 77251b72e..42a2a33ce 100644 --- a/docs/package.json +++ b/docs/package.json @@ -16,6 +16,7 @@ "@orama/tokenizers": "^3.1.16", "@streamdown/cjk": "^1.0.1", "@streamdown/code": "^1.0.1", + "@vercel/agent-readability": "^0.2.1", "@vercel/analytics": "^1.6.1", "@vercel/speed-insights": "^1.3.1", "ai": "^5.0.106", @@ -60,4 +61,4 @@ "typescript": "^5.9.3" }, "workspaces": [] -} +} \ No newline at end of file diff --git a/docs/proxy.ts b/docs/proxy.ts index baafb833a..b73293c13 100644 --- a/docs/proxy.ts +++ b/docs/proxy.ts @@ -7,6 +7,7 @@ import { } from "next/server"; import { i18n } from "@/lib/geistdocs/i18n"; import { trackMdRequest } from "@/lib/geistdocs/md-tracking"; +import { generateNotFoundMarkdown, isAIAgent } from "@vercel/agent-readability"; const { rewrite: rewriteLLM } = rewritePath( "/docs/*path", @@ -57,6 +58,39 @@ const proxy = (request: NextRequest, context: NextFetchEvent) => { } } + // AI agent detection — rewrite docs pages to markdown for agents + if ( + (pathname === "/docs" || pathname.startsWith("/docs/")) && + !pathname.includes("/llms.mdx/") + ) { + const agentResult = isAIAgent(request); + if (agentResult.detected && !isMarkdownPreferred(request)) { + const result = + pathname === "/docs" + ? `/${i18n.defaultLanguage}/llms.mdx` + : rewriteLLM(pathname); + + if (result) { + context.waitUntil( + trackMdRequest({ + path: pathname, + userAgent: request.headers.get("user-agent"), + referer: request.headers.get("referer"), + acceptHeader: request.headers.get("accept"), + requestType: "agent-rewrite", + detectionMethod: agentResult.method, + }) + ); + return NextResponse.rewrite(new URL(result, request.nextUrl)); + } + // Agent requested a non-existent docs URL + return new NextResponse(generateNotFoundMarkdown(pathname), { + headers: { "Content-Type": "text/markdown; charset=utf-8" }, + }); + } + } + + // Handle Accept header content negotiation and track the request if (isMarkdownPreferred(request)) { const result = rewriteLLM(pathname);