-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Relax default.tsx validation for parallel routes leaf segments #84767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
b5454f4
fix(parallel-routes): relax default.tsx validation for leaf segments
wyattjoh c2764d5
test: simplified test expectation
wyattjoh b644833
test: added retry to make test less flakey
wyattjoh 3cfadbb
test: remove other slot to make test more deterministic
wyattjoh 74a06ed
test: removed second parallel route to make test more determanistic
wyattjoh 37c3534
test: added additional test case for validating the no-error case
wyattjoh ffa7de4
fix: removed unused stop/clean steps
wyattjoh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
125 changes: 125 additions & 0 deletions
125
test/e2e/app-dir/parallel-routes-leaf-segments/fixtures/build-error/README.md
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # Build Error Scenarios | ||
|
|
||
| This fixture contains scenarios that **SHOULD throw `MissingDefaultParallelRouteError`** during build. | ||
|
|
||
| ## Why These Should Error | ||
|
|
||
| All scenarios in this fixture have: | ||
| 1. ✅ Parallel routes (slots starting with `@`) | ||
| 2. ❌ **NO** `default.tsx` files for those parallel routes | ||
| 3. ✅ **Child routes** that make these **non-leaf segments** | ||
|
|
||
| The presence of child routes means `default.tsx` files are required for the parallel slots. | ||
|
|
||
| --- | ||
|
|
||
| ## Scenario 1: Non-Leaf Segment with Children | ||
|
|
||
| **Path:** `/with-children` | ||
|
|
||
| ``` | ||
| app/with-children/ | ||
| ├── @header/ | ||
| │ └── page.tsx ← Has page.tsx | ||
| │ ❌ NO default.tsx! ← Missing default.tsx | ||
| ├── @sidebar/ | ||
| │ └── page.tsx ← Has page.tsx | ||
| │ ❌ NO default.tsx! ← Missing default.tsx | ||
| ├── layout.tsx ← Uses @header and @sidebar | ||
| ├── page.tsx ← Parent page | ||
| └── child/ | ||
| └── page.tsx ← ⚠️ CHILD ROUTE EXISTS! | ||
| ``` | ||
|
|
||
| **Expected Error:** | ||
| ``` | ||
| MissingDefaultParallelRouteError: | ||
| Missing required default.js file for parallel route at /with-children/@header | ||
| The parallel route slot "@header" is missing a default.js file. | ||
| ``` | ||
|
|
||
| **Why it errors:** | ||
| - When navigating from `/with-children` to `/with-children/child`, the routing system needs to know what to render for the `@header` and `@sidebar` slots | ||
| - Since `/with-children/child` doesn't define these parallel routes, Next.js looks for `default.tsx` files | ||
| - No `default.tsx` files exist → ERROR! | ||
|
|
||
| --- | ||
|
|
||
| ## Scenario 2: Non-Leaf with Route Groups and Children | ||
|
|
||
| **Path:** `/with-groups-and-children` | ||
|
|
||
| ``` | ||
| app/with-groups-and-children/(dashboard)/(overview)/ | ||
| ├── @analytics/ | ||
| │ └── page.tsx ← Has page.tsx | ||
| │ ❌ NO default.tsx! ← Missing default.tsx | ||
| ├── @metrics/ | ||
| │ └── page.tsx ← Has page.tsx | ||
| │ ❌ NO default.tsx! ← Missing default.tsx | ||
| ├── layout.tsx ← Uses @analytics and @metrics | ||
| ├── page.tsx ← Parent page | ||
| └── nested/ | ||
| └── page.tsx ← ⚠️ CHILD ROUTE EXISTS! | ||
| ``` | ||
|
|
||
| **Route Groups:** `(dashboard)` and `(overview)` don't affect the URL | ||
|
|
||
| **Expected Error:** | ||
| ``` | ||
| MissingDefaultParallelRouteError: | ||
| Missing required default.js file for parallel route at /with-groups-and-children/(dashboard)/(overview)/@analytics | ||
| The parallel route slot "@analytics" is missing a default.js file. | ||
| ``` | ||
|
|
||
| **Why it errors:** | ||
| - Even with route groups, the segment has a child route (`/nested`) | ||
| - The `hasChildRoutesForSegment()` helper correctly: | ||
| 1. Filters out route groups `(dashboard)` and `(overview)` | ||
| 2. Detects the `nested/page.tsx` child route | ||
| 3. Identifies this as a **non-leaf segment** | ||
| - No `default.tsx` files exist → ERROR! | ||
|
|
||
| --- | ||
|
|
||
| ## How to Fix These Errors | ||
|
|
||
| To make these scenarios build successfully, add `default.tsx` files: | ||
|
|
||
| ### For Scenario 1: | ||
| ```tsx | ||
| // app/with-children/@header/default.tsx | ||
| export default function HeaderDefault() { | ||
| return <div>Header Fallback</div> | ||
| } | ||
|
|
||
| // app/with-children/@sidebar/default.tsx | ||
| export default function SidebarDefault() { | ||
| return <div>Sidebar Fallback</div> | ||
| } | ||
| ``` | ||
|
|
||
| ### For Scenario 2: | ||
| ```tsx | ||
| // app/with-groups-and-children/(dashboard)/(overview)/@analytics/default.tsx | ||
| export default function AnalyticsDefault() { | ||
| return <div>Analytics Fallback</div> | ||
| } | ||
|
|
||
| // app/with-groups-and-children/(dashboard)/(overview)/@metrics/default.tsx | ||
| export default function MetricsDefault() { | ||
| return <div>Metrics Fallback</div> | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Contrast with `no-build-error` Fixture | ||
|
|
||
| The `no-build-error` fixture has similar parallel routes but: | ||
| - ❌ **NO child routes** (leaf segments) | ||
| - ✅ `default.tsx` files are **NOT required** | ||
|
|
||
| This fixture (build-error) has: | ||
| - ✅ **Child routes exist** (non-leaf segments) | ||
| - ❌ `default.tsx` files **ARE required** but missing → **ERROR!** |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/parallel-routes-leaf-segments/fixtures/build-error/app/layout.tsx
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| export default function RootLayout({ | ||
| children, | ||
| }: { | ||
| children: React.ReactNode | ||
| }) { | ||
| return ( | ||
| <html> | ||
| <body>{children}</body> | ||
| </html> | ||
| ) | ||
| } |
27 changes: 27 additions & 0 deletions
27
test/e2e/app-dir/parallel-routes-leaf-segments/fixtures/build-error/app/page.tsx
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import Link from 'next/link' | ||
|
|
||
| export default function HomePage() { | ||
| return ( | ||
| <div> | ||
| <h1>Build Error Scenarios Test</h1> | ||
| <p> | ||
| These routes SHOULD cause MissingDefaultParallelRouteError because they | ||
| have parallel routes without default.tsx files AND have child routes. | ||
| </p> | ||
| <nav> | ||
| <ul> | ||
| <li> | ||
| <Link href="/with-children"> | ||
| Non-Leaf Segment with Children (SHOULD ERROR) | ||
| </Link> | ||
| </li> | ||
| <li> | ||
| <Link href="/with-groups-and-children"> | ||
| Non-Leaf with Route Groups and Children (SHOULD ERROR) | ||
| </Link> | ||
| </li> | ||
| </ul> | ||
| </nav> | ||
| </div> | ||
| ) | ||
| } |
8 changes: 8 additions & 0 deletions
8
...dir/parallel-routes-leaf-segments/fixtures/build-error/app/with-children/@header/page.tsx
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| export default function HeaderSlot() { | ||
| return ( | ||
| <div> | ||
| <h3>Header Slot (Parent)</h3> | ||
| <p>This is the @header parallel route</p> | ||
| </div> | ||
| ) | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's technically valid to have only named parallel routes, eg
@fooand@barwithout necessarily having a children page slot.Does this account for that possibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think you could provide an example file/folder tree of the app structure you're envisioning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eg:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does! I've added this as a test case as well to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8f89ba8