next.js
d7608f7e - Fix prerendering of interception routes with generateStaticParams (#85835)

Commit
34 days ago
Fix prerendering of interception routes with generateStaticParams (#85835) ## What Fixes a bug where interception routes in parallel slots could not be prerendered using `generateStaticParams`, causing 404 responses when these routes were accessed directly. ## Why **The Problem:** Interception routes like `app/@modal/(.)photo/[id]/page.tsx` could not be prerendered even when they exported `generateStaticParams`. This was because the static path generation code only examined "children" segments in the loader tree, completely missing segments from parallel routes (like `@modal`) that actually contribute to the pathname. **Root Cause:** The previous implementation used `childrenRouteParamSegments` which only traversed the `children` branch of the loader tree: ```typescript // OLD: Only looked at children const childrenRouteParamSegments = [...segments from children only...] // This missed parallel routes like @modal that have dynamic segments ``` For a route structure like: ``` app/ [username]/ page.tsx @modal/ (.)[username]/ [id]/ page.tsx // ← This route's segments were MISSED ``` The build system couldn't discover the `[id]` parameter in the parallel route because it never traversed that branch of the tree. ## How **Solution:** Introduces `extractPathnameSegments()` which properly traverses the ENTIRE loader tree (not just children) to find ALL segments that contribute to the pathname: 1. **BFS Traversal**: Explores both `children` AND all parallel route slots (e.g., `@modal`, `@sidebar`) 2. **Depth Tracking**: Correctly tracks URL depth by: - Skipping route groups `(marketing)` - not in URL - Skipping parallel markers `@modal` - not in URL - Including interception markers `(.)photo` - ARE in URL 3. **Prefix Validation**: Ensures static segments match the target pathname before including dynamic segments 4. **Complete Parameter Discovery**: Returns all segments that contribute to pathname construction, regardless of which tree branch they're in **Example:** For `app/@modal/(.)photo/[id]/page.tsx`: - Old: Missed the `[id]` parameter entirely - New: Discovers `[id]` and enables prerendering with `generateStaticParams` ## Changes **New Module**: `extract-pathname-segments.ts` (192 lines) - Core algorithm for traversing loader tree and extracting pathname segments - Handles complex cases: parallel routes, interception routes, route groups - Well-documented with examples and algorithm explanation **Comprehensive Tests**: `extract-pathname-segments.test.ts` (897 lines) - Tests for simple cases, nested structures, parallel routes - Interception route handling in various configurations - Route group behavior and edge cases - Depth tracking validation **Integration**: `static-paths/app.ts` - Replaced `childrenRouteParamSegments` with `extractPathnameSegments()` - Updated pathname construction to use segments from parallel routes - Maintained backward compatibility **E2E Test**: Added test validating prerendering works for intercepted routes ## Test Plan The new E2E test verifies: ```typescript it('should prerender a dynamic intercepted route', async () => { // Verifies build output contains the prerendered interception route expect(next.cliOutput).toContain('/(.)john/1') // Verifies it doesn't generate the non-intercepted path expect(next.cliOutput).not.toContain('/john/1') }) ``` ## Impact **Before**: Interception routes with dynamic segments returned 404 when accessed directly, even with `generateStaticParams` **After**: These routes are properly prerendered at build time and return correct responses
Author
Parents
Loading