mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
### What & Why
There was some code added in the catch-all route normalization that
doesn't seem to make sense -- it was checking if the provided `appPath`
depth was larger than the catch-all route depth, prior to inserting it.
But it was comparing depths in an inconsistent way (`.length` vs
`.length - 1`), and the catch all path was also considering the `@slot`
and `/page` suffix as part of the path depth.
This means that if you had a `@modal/[...catchAll]` slot, it wouldn't be
considered for a page like `/foo/bar/baz`, because `/foo/bar/baz`
(depth: 4 with the current logic) and `/@modal/[...catchAll]/page`
(depth: 3 with the current logic) signaled that the `/foo/bar/baz` route
was "more specific" and shouldn't match the catch-all.
I think this was most likely added to resolve a bug where we were
inserting optional catch-all (`[[...catchAll]]`) routes into parallel
slots. However, optional catch-all routes are currently unsupported with
parallel routes, so this feature didn't work properly and the partial
support introduced a bug for regular catch-all routes.
### How
This removes the confusing workaround and skips optional catch-all
segments in this handling. Separately, we can add support for optional
catch-all parallel routes, but doing so will require quite a bit more
changes & also similar handling in Turbopack. Namely, if have a
top-level optional catch-all, in both the Turbopack & current Webpack
implementation, that top-level catch-all wouldn't be matched. And if you
tried to have an optional catch-all slot, in both implementations, the
app would error with:
> You cannot define a route with the same specificity as a optional
catch-all route ("/" and "/[[...catchAll]]")
because our route normalization logic does not treat slots specificity
differently than pages.
**Note**: This keeps the test that was added when this logic was first
introduced in #60776 to ensure that the case this was originally added
for still passes.
Fixes #62948
Closes NEXT-2728
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import { retry } from 'next-test-utils'
|
|
|
|
describe('parallel-routes-catchall-specificity', () => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
})
|
|
|
|
it('should match the catch-all route when navigating from a page with a similar path depth as the previously matched slot', async () => {
|
|
const browser = await next.browser('/')
|
|
|
|
await browser.elementByCss('[href="/comments/some-text"]').click()
|
|
|
|
await browser.waitForElementByCss('h1')
|
|
|
|
// we're matching @modal/(...comments)/[productId]
|
|
expect(await browser.elementByCss('h1').text()).toBe('Modal')
|
|
|
|
await browser.elementByCss('[href="/u/foobar/l"]').click()
|
|
|
|
// we're now matching @modal/[...catchAll]
|
|
await retry(async () => {
|
|
expect(await browser.elementByCss('h1').text()).toBe('Profile')
|
|
})
|
|
|
|
await browser.back()
|
|
|
|
await browser.elementByCss('[href="/trending"]').click()
|
|
|
|
await retry(async () => {
|
|
expect(await browser.elementByCss('h1').text()).toBe('Trending')
|
|
})
|
|
})
|
|
})
|