docs: drop the numeric section prefixes from the content paths (fixes #2939) - #3016
Merged
Conversation
`/02-foundations/01-design/02-colors` is now `/foundations/design/colors`. The
numbers stopped carrying the top-level order when the header moved to an
explicit `SECTION_ORDER`; what was left was the intra-section order and the
URLs themselves.
The authored order moves to `apps/docs/src/lib/content/contentOrder.ts`, a flat
list of pathnames that the navigation, the header, `llms.txt`, `llms.json` and
the sitemap sort by. Unlisted entries sort alphabetically by label — the
components, deliberately. `contentOrder.test.ts` rejects a stale entry and a
group that lists only some of its children, which is the silent half-ordered
case an in-code order list otherwise invites.
Old links keep working through one `rewrite` in `apps/docs/nginx.conf`: strip a
`NN-` prefix from any segment, 301, `/raw/**` included. A path with several
prefixes converges over as many hops; new paths never match, so it terminates.
`/_next/` is excluded — build chunks are named `<id>-<hash>.js` and a two-digit
id would be rewritten into a 404. Simulated against the build output: 2373 old
paths resolve to exactly their new path, 2787 new paths and all `_next` assets
stay untouched.
Two places relied on alphabetical happening to be the authored order, which
only held while the directories were numbered:
- the header linked a section at `mdxFiles[0]`, which would now land
Foundations on Fehlermeldungen instead of Design Tokens
- the components section was matched with `includes("04-components")`; a bare
`includes("components")` also matches `/foundations/structure/components`
Both compare path segments explicitly now.
Drive-by: the component overview linked its tiles at `.../overview`, a legacy
tab redirect.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`/foundations/internal` had exactly one child, so leaving it out changed no ordering. It did make the list read as an incomplete table of contents, which is what anyone opening the file uses it as. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # apps/docs/src/content/foundations/design/design-tokens/index.mdx
Contributor
Coverage Report for ./packages/components/
File CoverageNo changed files found. |
Contributor
🚀 Preview DeploymentPreview environments are ready:
Images:
|
…e focus `CodeBlock truncated (Local)` failed on webkit-linux with 1702 pixels (ratio 0.01) — the signature #3009 documents: a capture whose reference encodes a focus ring, taken without waiting for the focus. The reference does encode one. The scenario tabs onto the truncation toggle and captures it focused, and toggling swaps the label ("Show more" / "Show less"), so React re-renders the very button the focus sits on. The screenshot preamble settles on DOM mutations and `:focus` is a pseudo-class, so nothing waited for the ring to come back. #3009 migrated DatePicker and DateRangePicker to `waitForFocusInTheScenario()` and left this scenario behind. Same remedy here, before each capture. Not a change to what is rendered: main passed the scheduled visual run at 088b525 half an hour before this branch failed on it, and this branch touches no rendering code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The preview deployment answered `/04-components/actions/button` with `Location: http://…/components/actions/button` — every HTTPS visitor following a pre-rename link got downgraded to HTTP. The container listens on port 80 behind a TLS-terminating proxy, so nginx has no way to know the request arrived over TLS and builds absolute redirects with the wrong scheme. `absolute_redirect off` makes it send the path alone, which carries no scheme to get wrong. It also covers the `$uri/` directory redirect that `try_files` can emit — latent before, because nothing else redirected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Lisa18289
previously approved these changes
Aug 31, 2026
#3011 removed the internal Boundaries section, which this branch had renamed. The removal wins: the section and its examples are gone, and the link to it in the Error Handling pattern goes with them. That left `/foundations/internal` and `/foundations/internal/boundaries` in `CONTENT_ORDER` pointing at nothing. `contentOrder.test.ts` named both, which is the case it exists for — an order list in code going stale silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The 1.1.0 promotion (#3029) brought feature work from `next` written against the old, numbered docs paths. Two prose conflicts (Rating's scale guideline, Align's codemod pointer) keep main's wording with this branch's paths, and the two new Rating examples land in the renamed directory. It also brought seven references to paths this branch removed, in files that did not exist when the rename ran: - `packages/codemods/project.json` pointed an nx input at `01-get-started/versioning/index.mdx`. A glob matching nothing contributes nothing to the task hash, so `test:unit` would have served stale cache when that page changed — silently. - `documented.test.ts` and `mdxToMarkdown.test.ts` read or assert old paths. - `USAGE.md` lists `/raw/**` paths for consumers. - The CodeBlock migration entry links the old path, and while it was being touched, the legacy `/overview` tab redirect with it. `MIGRATION.md` is an output of `nx build codemods`, so the fix went into `entry.md` and the artifacts were regenerated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`unit` went red on `No test suite found in contentOrder.test.ts`. The 1.1.0 promotion gave `apps/docs` a Vitest `test:unit` alongside the existing `node:test` `test:links`, split by an `*.node.test.ts` infix — neither runner can execute the other's files. This guard is a `node:test` file and predates the split, so Vitest picked it up and found nothing it recognised. Renaming it to `contentOrder.node.test.ts` follows the rule `apps/docs` AGENTS.md now states, and puts it back beside `contentLinks.node.test.ts` — the other check that walks `src/content` from disk. It also makes the pointer in AGENTS.md and README.md true again: the guard does run in `test:links`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mfal
enabled auto-merge (squash)
August 31, 2026 14:09
Lisa18289
approved these changes
Sep 1, 2026
mfal
added a commit
that referenced
this pull request
Sep 1, 2026
#3016 dropped the numeric section prefixes from the docs content paths. Git followed the renames, so the merge itself was clean — but it left this branch's added table row pointing at the old `/04-components/navigation/link`. Main's rewrite could not touch a line that only exists here, so the link was dead without any conflict marker to show it. Pulled it onto the new format, matching the same page's other links.
mfal
added a commit
that referenced
this pull request
Sep 1, 2026
#3016 dropped the numeric section prefixes from the docs content paths. The two example files this branch adds were created in the old directory, so git flagged a location conflict and had already moved them to the renamed path — accepted as is. `index.mdx` merged cleanly and still references both examples.
mfal
added a commit
that referenced
this pull request
Sep 1, 2026
Review feedback from UX: the SegmentedControl -> RadioGroup direction always uses `RadioButton`, never the plain `Radio`. The entry offered both and left the pick to the reader — that choice is UX's, and it has been made. `Segment` -> `RadioButton` throughout: the frontmatter `apply`, the prose, the diff example, and `Segment`'s own `@deprecated`. The note that neither variant reproduces the segmented control's joined row stays, because the appearance does change; only the framing as an open choice goes. Also repoints the RadioGroup docs link at the prefix-free path. Both shapes still resolve today, but #3016 dropped the numeric section prefixes from the content paths, so `/components/form-controls/radio-group` is the canonical one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
/02-foundations/01-design/02-colorsis now/foundations/design/colors. This answers the product call #2939 asked for: breaking the public docs URLs is accepted, with a redirect layer.What replaced the numbers
The numbers stopped carrying the top-level order when the header moved to an explicit
SECTION_ORDER(#2760). What was left was the intra-section order and the URLs themselves.The authored order now lives in
apps/docs/src/lib/content/contentOrder.ts— a flat list of pathnames, read like a table of contents, that the navigation, the header,llms.txt,llms.jsonand the sitemap all sort by. Unlisted entries sort alphabetically by label; the components do that deliberately.An order list in code invites one silent failure: a forgotten line falls back to alphabetical and nothing says so.
contentOrder.test.tscloses that — it rejects a listed path that no longer exists, and a group that lists only some of its children. It runs inpnpm nx test:links docs, so CI catches it.It has already earned its keep: merging #3011, which removed the internal Boundaries section, left two entries pointing at nothing and the test named both. Without it they would have sat there matching no page, silently.
Redirects
One rule in
apps/docs/nginx.conf(the docs ship as an nginx image, sonext.configredirects would do nothing underoutput: "export"):Strips an
NN-prefix from any segment and 301s,/raw/**included. A path with several prefixes converges over as many hops; new paths never match, so it terminates./_next/is excluded because build chunks are named<id>-<hash>.js— a two-digit id would be rewritten into a 404.absolute_redirect offis the second half. The container listens on port 80 behind a TLS-terminating proxy, so nginx built theLocationashttp://…and downgraded every HTTPS visitor following a pre-rename link. Relative redirects carry no scheme to get wrong. This was latent before —try_files … $uri/can emit the same absolute redirect — but nothing redirected until now.Verified on the preview deployment, against real nginx:
/04-components/actions/button/components/actions/button/03-patterns/01-patterns/dashboard/patterns/patterns/dashboard/02-foundations/01-design/02-colors/foundations/design/colors/raw/02-foundations/01-design/02-colors.md/raw/foundations/design/colors.mdAll
https, all ending in 200,Locationrelative (location: /components/actions/button). New paths —/foundations/structure/componentsincluded — answer 200 in zero hops.Simulated against the whole
out/build beforehand: 2373 reconstructed old paths resolve to exactly their new path, and all 2787 new paths plus all 32_nextassets stay untouched.Two things that only worked because the directories were numbered
Both were "alphabetical happens to be the authored order", and both broke on the rename:
mdxFiles[0], i.e. filesystem order. After the rename that lands Foundations on Fehlermeldungen instead of Design Tokens. Caught in the built HTML; the first page is now picked by the authored order.includes("04-components"). A bareincludes("components")also matches/foundations/structure/components— that would have mis-marked the header's current section and mis-typed the static params. Both compare path segments explicitly now.Not in scope
03-patterns/01-patternsbecame/patterns/patterns/*. The duplication is already in the navigation today (section "Patterns" > group "Patterns"); the numbers only hid it in the URL. Dissolving that group is a content decision.Drive-by
The component overview linked its tiles at
.../overview, a legacy tab redirect. Pointing our own links at a redirect while building a redirect layer made no sense.One unrelated fix carried along
CodeBlock truncated (Local)failed the visual suite with 1702 pixels (ratio 0.01) — the signature #3009 documents for a capture whose reference encodes a focus ring, taken without waiting for the focus. It does encode one: the scenario tabs onto the truncation toggle and captures it focused, and toggling swaps the label, so React re-renders the button the focus sits on. #3009 migrated DatePicker and DateRangePicker towaitForFocusInTheScenario()and left this scenario behind; same remedy applied here. No baseline was touched.Not caused by this PR — main passed the scheduled visual run at 088b525 half an hour before this branch failed on it, and this branch changes no rendering code. The visual suite runs here at all because the PR touches root-level files, which makes nx consider everything affected.
Verification
pnpm nx test:links docs— 32 tests, all links in content and app sources resolvepnpm nx build docs— static export builds, navigation order checked in the emitted HTMLpnpm lint— 0 errorspnpm nx test:compile remote-react-components— for the visual-test fixnode --test .github/scripts/release-relevance-lib.test.mjs— 19 testsfixes #2939
🤖 Generated with Claude Code