next.js
21b9f6ba - fix: correct appPaths sort order for parallel routes with route groups (#91160)

Commit
69 days ago
fix: correct appPaths sort order for parallel routes with route groups (#91160) ### What? Fixes webpack dev 404s when parallel routes have children nested inside a route group (e.g. `@slot` + `(b1)/page`) and when a parallel route has `page.tsx` directly inside it (e.g. `@slot/page.tsx`). ### Why? Two separate issues caused 404s for parallel routes with route groups: 1. **Sort order**: The three `appPaths` sort sites used bare `.sort()` (lexicographic ordering). `renderPageComponent` relies on `appPaths[appPaths.length - 1]` being the children/root page. Without route groups this works because `@` (0x40) sorts after lowercase letters — `/@slot/page` comes before `/page`. But when the children page is inside a route group, `(` (0x28) sorts before `@` (0x40), flipping the order: `/(b1)/page < /@slot/page`. Now the last item is the slot page instead of the children page, so the manifest lookup fails and a 404 is returned. 2. **Double `__PAGE__` segment**: When a parallel route like `@slot` has `page.tsx` directly inside it, `resolveParallelSegments` returns `[PAGE_SEGMENT]` (an array) to signal that the loader should recurse into the slot directory to pick up layout/default files. However, the segment key normalization was mapping `PAGE_SEGMENT` to `PAGE_SEGMENT_KEY` (`__PAGE__`), while the recursion would also produce a `__PAGE__` for children — creating a double `__PAGE__` nesting (`slot: ['__PAGE__', { children: ['__PAGE__', ...] }, ...]`). ### How? **Sort order fix**: Adds a `compareAppPaths` comparator in `packages/next/src/shared/lib/router/utils/app-paths.ts` that sorts paths containing `/@` segments before paths without them, ensuring the children page is always last. Replaces the three bare `.sort()` calls with `.sort(compareAppPaths)` in: - `packages/next/src/build/entries.ts` - `packages/next/src/server/lib/router-utils/setup-dev-bundler.ts` - `packages/next/src/server/route-matcher-providers/dev/dev-app-page-route-matcher-provider.ts` **Loader tree fix**: Maps `PAGE_SEGMENT` to `'(slot)'` in the segment key normalization (same as `PARALLEL_VIRTUAL_SEGMENT`), instead of `PAGE_SEGMENT_KEY`. By the time this code is reached, `parallelSegmentKey === PAGE_SEGMENT` only occurs for the array case (the string case is handled by the early return), so this is safe. The actual `__PAGE__` is correctly created by the recursion. **Before:** `slot: ['__PAGE__', { children: ['__PAGE__', ...] }, ...]` **After:** `slot: ['(slot)', { children: ['__PAGE__', ...] }, ...]` Also adds an e2e test that verifies the fix across all modes (Turbopack dev, Turbopack start, webpack dev).
Author
Parents
Loading