Repository navigation
fix(routing): rank overlapping routes segment by segment - #706
Merged
Merged
Conversation
Pages sorted dynamic patterns by comparing the whole pattern string, so `[lang]/about` (/:lang/about) registered ahead of `users/[id]` and won /users/about, and `[lang]/[slug]` shadowed every static sibling under `[lang]/`. WebSocket routes sorted by plain string order, so `chat/[room]` shadowed `chat/lobby`. The routes/ comparator ranked by segment but let parameter names break ties, so `[category]/[item]` won /fr/about over `[lang]/about`. Pages, routes/ and WebSocket routes now share one comparator: catch-alls last, fully static routes first, then the first differing segment decides (static, then param, then catch-all). Parameter names never decide. The Pages client matcher classifies segments with the same helper, so ranking and matching agree. Co-Authored-By: Claude Opus 5.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.
When several routes match a URL, the most specific one now handles it, the same way in
pages/,routes/and WebSocket routes. Before, each scanner ranked overlapping routes differently, and some URLs went to the wrong file without a warning:/users/aboutpages/[lang]/about.tsx,pages/users/[id].tsx[lang]/aboutusers/[id]/users/new/editpages/users/[id]/edit.tsx,pages/users/new/[tab].tsxusers/[id]/editusers/new/[tab]/fr/aboutpages/[lang]/about.tsx,pages/[lang]/[slug].tsx[lang]/[slug][lang]/about/fr/aboutroutes/[lang]/about.ts,routes/[category]/[item].ts[category]/[item][lang]/about/chat/lobbyroutes/chat/[room].ws.ts,routes/chat/lobby.ws.tschat/[room]chat/lobbyPages compared whole pattern strings, where
:sorts before letters, so any[param]beat a static segment at the same depth. This hit translated sites hardest: underpages/[lang]/every page is dynamic, so[lang]/[slug]shadowed every static page beside it. WebSocket routes used plain string order.routes/already compared segment by segment, but let parameter names break ties.All three now share one comparator: catch-alls last, fully static routes first, then the first differing segment decides (static, then
[param], then catch-all). Parameter names never decide. The Pages client matcher classifies segments with the same helper, so its speculative match agrees with the server.Unchanged: catch-all routes still rank after every other route, so
/docs/introgoes to[lang]/[slug]beforedocs/[...path].Docs: a short "Overlapping routes" section in the server routing guide, which the pages guide points to.
Tests: a comparator test that checks each pair really overlaps (using the client regex) and that the order doesn't depend on input order, plus one regression test each for the pages scan (through the generated
matchRoute), theroutes/scan and the WebSocket scan. All three scan tests fail onmain.🤖 Generated with Claude Code