diff --git a/next.config.mjs b/next.config.mjs index 227bf69ce..10314170b 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -114,6 +114,23 @@ const nextraConfig = withNextra({ { key: "Content-Type", value: "text/markdown; charset=utf-8" }, ], }, + // Also apply headers to the md-src directory (used by rewrites) + { + source: "/md-src/:path*.md", + headers: [ + { key: "X-Robots-Tag", value: "noindex" }, + { key: "Content-Type", value: "text/markdown; charset=utf-8" }, + { key: "Vary", value: "Accept" }, + ], + }, + // Add Vary: Accept to paths that might serve different content based on Accept header + // Excludes /api and /_next routes + { + source: "/:path((?!api/)(?!_next/)(?:[^/.]+(?:/[^/.]+)*)/?)", + headers: [ + { key: "Vary", value: "Accept" }, + ], + }, ]; // Do not index Vercel preview deployments @@ -146,12 +163,32 @@ const nextraConfig = withNextra({ async rewrites() { // Serve any ".md" path by mapping to the static copy in public/md-src // Example: /docs.md -> /md-src/docs.md, /docs/observability/overview.md -> /md-src/docs/observability/overview.md - return [ - { - source: "/:path*.md", - destination: "/md-src/:path*.md", - }, - ]; + return { + beforeFiles: [ + // Serve markdown for paths without file extensions when Accept header explicitly requests markdown + // Only serves markdown when Accept header contains text/markdown, text/plain, or application/markdown + // AND does NOT contain text/html (to prevent serving markdown to browsers) + // This regex matches paths that don't end with a file extension (no dot in the last segment) + // Excludes /api and /_next routes + { + source: "/:path((?!api/)(?!_next/)(?:[^/.]+(?:/[^/.]+)*)/?)", + has: [ + { + type: "header", + key: "accept", + value: "^(?!.*text/html).*(text/markdown|text/plain|application/markdown).*", + }, + ], + destination: "/md-src/:path*.md", + }, + ], + afterFiles: [ + { + source: "/:path*.md", + destination: "/md-src/:path*.md", + }, + ], + }; }, });