Skip to content
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

parallel routes: fix client reference manifest grouping for catch-all segments #60482

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,19 @@ function getAppPathRequiredChunks(
// - app/foo/page -> app/foo
// - app/(group)/@named/foo/page -> app/foo
// - app/(.)foo/(..)bar/loading -> app/bar
// - app/[...catchAll]/page -> app
// - app/foo/@slot/[...catchAll]/page -> app/foo
function entryNameToGroupName(entryName: string) {
let groupName = entryName
.slice(0, entryName.lastIndexOf('/'))
// Remove slots
.replace(/\/@[^/]+/g, '')
// Remove the group with lookahead to make sure it's not interception route
.replace(/\/\([^/]+\)(?=(\/|$))/g, '')
// Remove catch-all routes since they should be part of the parent group that the catch-all would apply to.
// This is necessary to support parallel routes since multiple page components can be rendered on the same page.
// In order to do that, we need to ensure that the manifests are merged together by putting them in the same group.
.replace(/\/\[?\[\.\.\.[^\]]*\]\]?/g, '')

// Interception routes
groupName = groupName
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use client'

export function ClientComponent() {
return <div>catchall page client component</div>
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { ClientComponent } from './client-component'

export default function Page() {
return 'main catchall'
return (
<div>
main catchall <ClientComponent />
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,11 @@ createNextDescribe(
await browser.elementByCss('[href="/parallel-catchall/baz"]').click()
await check(
() => browser.waitForElementByCss('#main').text(),
'main catchall'
/main catchall/
)
await check(
() => browser.waitForElementByCss('#main').text(),
/catchall page client component/
)
await check(
() => browser.waitForElementByCss('#slot-content').text(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use client'

export function ClientComponent() {
return <div>catchall slot client component</div>
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { ClientComponent } from './client-component'

export default function Page() {
return 'slot catchall'
return (
<div>
slot catchall <ClientComponent />
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,19 @@ createNextDescribe(
// so we'd expect to see the catch-all slot & the page content
await check(() => browser.elementById('children').text(), /bar/)
await check(() => browser.elementById('slot').text(), /slot catchall/)
await check(
() => browser.elementById('slot').text(),
/catchall slot client component/
)
})

it('should match correctly when defining an explicit slot but no page', async () => {
const browser = await next.browser('/')
await check(() => browser.elementById('slot').text(), /slot catchall/)
await check(
() => browser.elementById('slot').text(),
/catchall slot client component/
)

await browser.elementByCss('[href="/baz"]').click()

Expand All @@ -46,12 +54,19 @@ createNextDescribe(
it('should match both the catch-all page & slot', async () => {
const browser = await next.browser('/')
await check(() => browser.elementById('slot').text(), /slot catchall/)

await check(
() => browser.elementById('slot').text(),
/catchall slot client component/
)
await browser.elementByCss('[href="/quux"]').click()

// quux doesn't have a page or slot defined. It should use the catch-all for both
await check(() => browser.elementById('children').text(), /main catchall/)
await check(() => browser.elementById('slot').text(), /slot catchall/)
await check(
() => browser.elementById('slot').text(),
/catchall slot client component/
)
})
}
)