mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
### 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: - https://github.com/vercel/next.js/issues/51805 - https://github.com/vercel/next.js/issues/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.  ### 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
74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
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)
|
|
})
|
|
}
|
|
}
|
|
)
|