fix: route precedence and conflict validation in fs-routes next adapter#135
Merged
Conversation
FUNSTACK Router matches routes in definition order (first match wins), but the next adapter ordered sibling routes alphabetically, so dynamic ([slug]) and catch-all ([...slug]) segments were emitted before static siblings and shadowed them. Sibling routes are now ordered by specificity: static before dynamic before catch-all. Pathless layouts (layouts in route groups) are ranked by their greediest descendants. The adapter also fails loudly instead of silently producing broken routes for: - optional catch-all segments ([[...param]]) - parallel route slots (@slot) and intercepting routes ((.)segment) - two pages resolving to the same route (e.g. via route groups, or sibling dynamic pages with different param names) - duplicate page/layout files in one directory (page.tsx + page.jsx) Multiple root layouts via route groups remain supported. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138kFvyLCb2rhkZvC6sD2Bq
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.
Summary
Fixes a route-shadowing bug in the built-in Next.js-like file-system routing adapter and makes the adapter fail loudly on unsupported or conflicting route files.
Route precedence fix
FUNSTACK Router matches routes in definition order (first match wins), but the adapter ordered sibling routes alphabetically. Since
[sorts before lowercase letters, dynamic ([slug]) and catch-all ([...slug]) segments were emitted before static siblings and shadowed them — e.g. withblog/[slug]/page.tsxandblog/about/page.tsx, the URL/blog/aboutrendered the[slug]page (with emptyparamsin the statically generated HTML).Sibling routes are now ordered by specificity: static → dynamic → catch-all. Pathless layouts (layouts inside route groups) are ranked by their greediest descendants, and the sort is stable so equally-specific routes keep their alphabetical order.
Validation errors
buildRoutesnow throws with an actionable message instead of silently producing broken routes for:[[...param]]) — previously produced the garbage path/:[...slug]@slot) and intercepting routes ((.)segment) — previously became literal URL segments(a)/foo/page.tsx+(b)/foo/page.tsx, or sibling dynamic pages with different param names like[a]+[b])page.tsxnext topage.jsx) — previously the last one silently wonMultiple root layouts via route groups (
(marketing)/layout.tsx+(shop)/layout.tsx) remain supported, matching Next.js, with a test pinning that behavior.Tests
blog/featured/page.tsxadded to the fs-routing fixture as a static sibling ofblog/[slug], asserted in both the production-build and dev-server specsDocs
Adds "Route Precedence" and "Unsupported Syntaxes and Conflicts" sections to the File-System Routing guide.
🤖 Generated with Claude Code
https://claude.ai/code/session_0138kFvyLCb2rhkZvC6sD2Bq
Generated by Claude Code