Skip to content

fix: route precedence and conflict validation in fs-routes next adapter#135

Merged
uhyo merged 1 commit into
masterfrom
claude/nextjs-adapter-review-mw5yy8
Jul 11, 2026
Merged

fix: route precedence and conflict validation in fs-routes next adapter#135
uhyo merged 1 commit into
masterfrom
claude/nextjs-adapter-review-mw5yy8

Conversation

@uhyo

@uhyo uhyo commented Jul 11, 2026

Copy link
Copy Markdown
Owner

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. with blog/[slug]/page.tsx and blog/about/page.tsx, the URL /blog/about rendered the [slug] page (with empty params in 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

buildRoutes now throws with an actionable message instead of silently producing broken routes for:

  • optional catch-all segments ([[...param]]) — previously produced the garbage path /:[...slug]
  • parallel route slots (@slot) and intercepting routes ((.)segment) — previously became literal URL segments
  • two pages resolving to the same route (e.g. (a)/foo/page.tsx + (b)/foo/page.tsx, or sibling dynamic pages with different param names like [a] + [b])
  • duplicate page/layout files in one directory (page.tsx next to page.jsx) — previously the last one silently won

Multiple root layouts via route groups ((marketing)/layout.tsx + (shop)/layout.tsx) remain supported, matching Next.js, with a test pinning that behavior.

Tests

  • 13 new unit tests covering the specificity ordering (including through route-group layouts) and every new error case
  • New e2e regression coverage: blog/featured/page.tsx added to the fs-routing fixture as a static sibling of blog/[slug], asserted in both the production-build and dev-server specs
  • Full verification: unit tests (33 passed), typecheck, lint, format check, and both e2e suites (28/28 build, 25/25 dev) pass

Docs

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

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
@uhyo uhyo merged commit 16736af into master Jul 11, 2026
2 checks passed
@uhyo uhyo deleted the claude/nextjs-adapter-review-mw5yy8 branch July 11, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants