-
Notifications
You must be signed in to change notification settings - Fork 27.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
log a dev warning when a missing parallel slot results in a 404 (#60186)
### What & Why? When visiting a route that attempts to render a slot with no page & no default, the fallback behavior is to trigger a 404. However this can lead to a confusing development experience for complex parallel routing cases as you might not realize a default is missing, or which slot is causing the error. Previous issues where this caused confusion: - #51805 - #49569 ### How? This is a dev-only modification to track parallel slots that are using the default fallback (aka missing). When the `NotFoundBoundary` is triggered in development mode, this will log a warning about why it 404ed, along with a list of slot(s) that were determined to be missing. ![CleanShot 2024-01-03 at 14 34 30@2x](https://github.com/vercel/next.js/assets/1939140/1a00ea49-24b6-4ba0-9bac-8773c7e10a75) ### Future We should eventually lift this into some sort of dev-only UI to help catch it when not monitoring the browser console (similar to the error overlay). However, this will require some design thought and isn't necessary for the first iteration. Closes NEXT-1798
- Loading branch information
Showing
19 changed files
with
195 additions
and
8 deletions.
There are no files selected for viewing
This file contains 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 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 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
5 changes: 4 additions & 1 deletion
5
packages/next/src/client/components/parallel-route-default.tsx
This file contains 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 |
---|---|---|
@@ -1,5 +1,8 @@ | ||
import { notFound } from './not-found' | ||
|
||
export default function NoopParallelRouteDefault() { | ||
export const PARALLEL_ROUTE_DEFAULT_PATH = | ||
'next/dist/client/components/parallel-route-default' | ||
|
||
export default function ParallelRouteDefault() { | ||
notFound() | ||
} |
This file contains 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 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 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 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
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/@bar/has-both-slots/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>@bar slot</div> | ||
} |
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>@bar slot</div> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/@foo/has-both-slots/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>@foo slot</div> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/@foo/no-bar-slot/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>@foo slot</div> | ||
} |
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>@foo slot</div> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/both-slots-missing/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>Both Slots Missing</div> | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/has-both-slots/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>Has Both Slots</div> | ||
} |
This file contains 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,15 @@ | ||
export default function Layout(props: { | ||
children: React.ReactNode | ||
foo: React.ReactNode | ||
bar: React.ReactNode | ||
}) { | ||
return ( | ||
<html> | ||
<body> | ||
<div id="children">{props.children}</div> | ||
{props.foo} | ||
{props.bar} | ||
</body> | ||
</html> | ||
) | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/app-dir/parallel-route-not-found/app/no-bar-slot/page.tsx
This file contains 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,3 @@ | ||
export default function Page() { | ||
return <div>No @bar Slot</div> | ||
} |
This file contains 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,9 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Page() { | ||
return ( | ||
<div> | ||
<Link href="/nested">To /nested</Link> | ||
</div> | ||
) | ||
} |
73 changes: 73 additions & 0 deletions
73
test/e2e/app-dir/parallel-route-not-found/parallel-route-not-found.test.ts
This file contains 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,73 @@ | ||
import { createNextDescribe } from 'e2e-utils' | ||
|
||
createNextDescribe( | ||
'parallel-route-not-found', | ||
{ | ||
files: __dirname, | ||
}, | ||
({ next, isNextDev }) => { | ||
it('should handle a layout that attempts to render a missing parallel route', async () => { | ||
const browser = await next.browser('/no-bar-slot') | ||
const logs = await browser.log() | ||
expect(await browser.elementByCss('body').text()).toContain( | ||
'This page could not be found' | ||
) | ||
const warnings = logs.filter((log) => log.source === 'warning') | ||
if (isNextDev) { | ||
expect(warnings.length).toBe(1) | ||
expect(warnings[0].message).toContain( | ||
'No default component was found for a parallel route rendered on this page' | ||
) | ||
expect(warnings[0].message).toContain('Missing slots: @bar') | ||
} else { | ||
expect(warnings.length).toBe(0) | ||
} | ||
}) | ||
|
||
it('should handle multiple missing parallel routes', async () => { | ||
const browser = await next.browser('/both-slots-missing') | ||
const logs = await browser.log() | ||
|
||
expect(await browser.elementByCss('body').text()).toContain( | ||
'This page could not be found' | ||
) | ||
|
||
const warnings = logs.filter((log) => log.source === 'warning') | ||
if (isNextDev) { | ||
expect(warnings.length).toBe(1) | ||
expect(warnings[0].message).toContain( | ||
'No default component was found for a parallel route rendered on this page' | ||
) | ||
expect(warnings[0].message).toContain('Missing slots: @bar, @foo') | ||
} else { | ||
expect(warnings.length).toBe(0) | ||
} | ||
}) | ||
|
||
it('should render the page & slots if all parallel routes are found', async () => { | ||
const browser = await next.browser('/has-both-slots') | ||
const logs = await browser.log() | ||
|
||
expect(await browser.elementByCss('body').text()).toContain( | ||
'Has Both Slots' | ||
) | ||
expect(await browser.elementByCss('body').text()).toContain('@foo slot') | ||
expect(await browser.elementByCss('body').text()).toContain('@bar slot') | ||
|
||
const warnings = logs.filter((log) => log.source === 'warning') | ||
expect(warnings.length).toBe(0) | ||
}) | ||
|
||
if (isNextDev) { | ||
it('should not log any warnings for a regular not found page', async () => { | ||
const browser = await next.browser('/this-page-doesnt-exist') | ||
const logs = await browser.log() | ||
expect(await browser.elementByCss('body').text()).toContain( | ||
'This page could not be found' | ||
) | ||
const warnings = logs.filter((log) => log.source === 'warning') | ||
expect(warnings.length).toBe(0) | ||
}) | ||
} | ||
} | ||
) |