Latent, not live: zero pages in content/docs/ have a dot in their slug today (measured). Filing it because the failure mode is silent and the trap is invisible from the source — recording it rather than swallowing it. Found while verifying #180.
(Angle-bracket markup omitted throughout — this repo's sanitizer strips it.)
Mechanism
middleware.ts's matcher exempts .*\..*, unanchored, so it skips any path containing a dot anywhere — not just an asset path and not just the last segment. #180 fixed the half where the first segment carries the dot. This is the other half: a dot in a later segment.
hideLocale: 'default-locale' means the public URL of an English page has no prefix, and the middleware rewrite is what maps it onto the internal /en/... route. Skip the middleware and that rewrite never happens — so a page whose slug contains a dot is reachable only at the internal route the config is trying to hide.
Measured
Temporarily added content/docs/probe.dotted.mdx, built, served with next start, then removed it (restore proven by git status clean):
| request |
status |
body carries the page |
/docs/probe.dotted — the page's public URL |
404 |
no |
/en/docs/probe.dotted — the internal route |
200 |
yes |
/zh-Hans/docs/probe.dotted |
200 |
yes |
/docs/architecture — control, no dot |
200 |
n/a |
So the page builds, prerenders, is advertised in the sitemap under its public URL, and 404s there. Every locale except the default works, because only the default locale depends on the rewrite.
This is unchanged by #180's fix — both readings above are from a build that has it. en and zh-Hans are enumerated locales, so the dynamicParams flag never sees them.
Why it is worth recording
- The failure is silent and inverted: the author sees the page render fine at
/en/docs/... while every published link, the sitemap entry, and the sidebar URL point at the 404. AGENTS.md already documents one silent-translation trap of exactly this shape (foo.cn.mdx renders nothing and raises no error); this is a second one.
- Dotted slugs are not exotic for this product's subject matter —
node.js, next.config, package.json, v1.0 are all plausible page names.
- Nothing would catch it:
check-locale-surface.mjs reads build output and would see the URL correctly advertised, because the page really does exist. The defect is only visible against a running server.
Note on the fix direction
Tightening the matcher is the obvious answer and is not cheap — the PM's adjudication on #180 records why: /llms.txt, /llms-full.txt, /sitemap.xml, /robots.txt and every .mdx page route depend on the dot exemption today, and the locale-surface gate reads build output rather than a running server, so a regression there would be caught by nothing. Any change here needs the running-server matrix, not a gate run.
A cheaper containment, if the routing change is judged not worth it: reject a dotted slug at build time, so the page cannot ship in a state where its own URL 404s.
Filed unassigned, observation-class.
Generated by Claude Code
Latent, not live: zero pages in
content/docs/have a dot in their slug today (measured). Filing it because the failure mode is silent and the trap is invisible from the source — recording it rather than swallowing it. Found while verifying #180.(Angle-bracket markup omitted throughout — this repo's sanitizer strips it.)
Mechanism
middleware.ts's matcher exempts.*\..*, unanchored, so it skips any path containing a dot anywhere — not just an asset path and not just the last segment. #180 fixed the half where the first segment carries the dot. This is the other half: a dot in a later segment.hideLocale: 'default-locale'means the public URL of an English page has no prefix, and the middleware rewrite is what maps it onto the internal/en/...route. Skip the middleware and that rewrite never happens — so a page whose slug contains a dot is reachable only at the internal route the config is trying to hide.Measured
Temporarily added
content/docs/probe.dotted.mdx, built, served withnext start, then removed it (restore proven bygit statusclean):/docs/probe.dotted— the page's public URL/en/docs/probe.dotted— the internal route/zh-Hans/docs/probe.dotted/docs/architecture— control, no dotSo the page builds, prerenders, is advertised in the sitemap under its public URL, and 404s there. Every locale except the default works, because only the default locale depends on the rewrite.
This is unchanged by #180's fix — both readings above are from a build that has it.
enandzh-Hansare enumerated locales, so thedynamicParamsflag never sees them.Why it is worth recording
/en/docs/...while every published link, the sitemap entry, and the sidebar URL point at the 404. AGENTS.md already documents one silent-translation trap of exactly this shape (foo.cn.mdxrenders nothing and raises no error); this is a second one.node.js,next.config,package.json,v1.0are all plausible page names.check-locale-surface.mjsreads build output and would see the URL correctly advertised, because the page really does exist. The defect is only visible against a running server.Note on the fix direction
Tightening the matcher is the obvious answer and is not cheap — the PM's adjudication on #180 records why:
/llms.txt,/llms-full.txt,/sitemap.xml,/robots.txtand every.mdxpage route depend on the dot exemption today, and the locale-surface gate reads build output rather than a running server, so a regression there would be caught by nothing. Any change here needs the running-server matrix, not a gate run.A cheaper containment, if the routing change is judged not worth it: reject a dotted slug at build time, so the page cannot ship in a state where its own URL 404s.
Filed unassigned, observation-class.
Generated by Claude Code