fix(docs): emit the locale-independent .mdx URL from the docs page - #211
Merged
Conversation
The Copy Markdown button and the Open popover both derived their target as `page.url` plus `.mdx`. On a locale-prefixed route `page.url` carries the prefix, and `next.config.mjs` rewrites exactly one shape — `/docs/:path*.mdx` to `/llms.mdx/docs/:path*`. A prefixed URL matches no rewrite, falls through to this route with `architecture.mdx` as a slug, and is answered by `/_not-found` under `dynamicParams = false`. That was six of seven locales on all 79 pages. Derive the URL from `page.slugs` instead, through the existing `docsPath` helper, and bind it once so both controls take the same value. The prefix is dropped rather than the rewrite widened because the machine-facing markdown surface is English-only by AGENTS.md rule 1 — the same pin `llms.txt` and `llms-full.txt` carry — and `/llms.mdx/docs/[[...slug]]` is English-only by construction, calling `source.getPage(slug)` with no language. A prefixed rewrite would not deliver translated markdown; it would reverse that policy through a routing change. Byte-identical on the default locale, where `page.url` has no prefix to carry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G5zjYc2BoFV2NjKBBapC7C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #207
Every docs page rendered its Copy Markdown button and its Open popover with a target derived as
page.urlplus.mdx. On a locale-prefixed routepage.urlcarries the prefix, andnext.config.mjsrewrites exactly one shape —/docs/:path*.mdxto/llms.mdx/docs/:path*. A prefixed URL matches no rewrite, falls through toapp/[lang]/docs/[[...slug]]witharchitecture.mdxas a slug, and is answered by/_not-foundunderdynamicParams = false.The fix derives the URL from
page.slugsthrough the existingdocsPathhelper and binds it once, so both controls take the same value and a third control added later inherits it rather than re-deriving one frompage.url.next.config.mjsis untouched. The diff is one file.Why the prefix is dropped rather than the rewrite widened
This is a conformance decision, not the cheaper of two repairs. The machine-facing markdown surface here is English-only by AGENTS.md rule 1 — the same pin
llms.txtandllms-full.txtcarry, enforced bycheck-locale-surface.mjs./llms.mdx/docs/[[...slug]]is English-only by construction too: its handler callssource.getPage(slug)with no language argument, so the default language is the only thing it can serve, and it prerenders 79 bodies rather than 553.A
/:lang/docs/:path*.mdxrewrite would therefore not deliver translated markdown. It would either serve English from a URL claiming a locale, or turn/llms.mdxinto a locale-aware surface and put it out of step with the twollmsfiles beside it. Reversing that policy is a decision about the whole markdown surface, not a 404 fix.The third consumer: filed, not fixed — #210
The card named two consumers. The sweep found a third, and it is not repaired by this PR, deliberately.
/llms.txtstates two rules with nothing scoping the first to English: "Every page below is also available as Markdown by appending.mdxto its URL", and then, in Other Languages, "Every page above is also published under a locale prefix — for examplehttps://docs.objectos.ai/zh-Hans/docs/quickstart". Composing them is exactly what a machine reader does with anllms.txt, and it produces the same 404 this PR fixes for the in-page controls. Measured on the served file:/zh-Hans/docs/quickstart.mdx,/ja/docs/architecture.mdxand/de/docs/quickstart.mdxall 404, while/docs/quickstart.mdxanswers 200text/markdown.A related trace sits in
apps/docs/app/llms-full.txt/route.tsline 20, a comment asserting "The locale text stays reachable per page through the.mdxrewrite" — measured false; no locale text is reachable through that rewrite at all.Both are outside this card's declared surface, and the repair is a wording change to a machine-facing contract file, which deserves its own review rather than a rider here. Filed as #210. Leaving it visible is the point: repairing two of three would have removed the symptom that leads someone to the third.
Verification
Against
next starton a forced production build, readingmarkdownUrlout of the served payload.markdownUrlreaches the browser only as a client-component prop inside the RSC flight payload — it appears in no rendered markup — so extracting it is a deliberate read of the script bodies. The opposite check below strips those bodies first.The three named pages — before, on
ffe36c5, and after:markdownUrlbeforemarkdownUrlafter/docs/architecture/docs/architecture.mdx/docs/architecture.mdxtext/markdown, first line# Architecture/zh-Hans/docs/architecture/zh-Hans/docs/architecture.mdx/docs/architecture.mdxtext/markdown, first line# Architecture/ja/docs/architecture/ja/docs/architecture.mdx/docs/architecture.mdxtext/markdown, first line# ArchitectureExhaustive sweep, every docs page in every locale — 79 paths enumerated from the served
sitemap.xml, times 7 locales:553 renders collapse onto 79 distinct targets — one per logical page — which is the locale-independence claim measured rather than asserted. "english target moved: 0" is the regression check: on the default locale the old expression was literally
page.urlplus.mdx, andpage.urlis the path being requested, so every English page is asserted to still point exactly where it did. The docs index edge case is included:/docsemits/docs.mdx, which answers 200text/markdown.Controls, all 200 with no redirect and no locale prefix, byte counts identical before and after:
/docs/architecture.mdxtext/markdown, 12488 bytes/llms.txt/llms-full.txt/sitemap.xml/robots.txtThe visible page is unchanged. Every
scriptbody stripped before any comparison — a raw comparison would read the RSC payload, which is the one thing that legitimately changed. All three pages byte-identical after normalising content-hashed asset filenames, which move on any rebuild:The strip was verified to be doing work rather than comparing two empty files: the raw HTML contains
self.__next_f, the stripped file contains none, and the stripped files are ~54 KB.The two builds also produced an identical route table, and the same 310 pre-existing OG-card font-fetch warnings (a sandbox TLS artifact, unchanged by this diff).
Gates
Union re-run after the final commit, on
38e5a04:pnpm turbo run type-check build test --force—Tasks: 3 successful, 3 totalnode .github/scripts/check-locale-surface.mjs— exit 0; "every advertised URL has a source file and every source file is advertised; bothllmsbodies carry every en-only page title and none from the other locales"tscwas confirmed to actually include the edited file (--listFilesreportsapp/[lang]/docs/[[...slug]]/page.tsx), so "type-check clean" is a statement about this change and not a vacuous pass. Every exit code was captured before any pipe.Generated by Claude Code