rsnext/test/e2e/app-dir/interception-routes-root-catchall/app/layout.tsx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

19 lines
290 B
TypeScript
Raw Normal View History

fix parallel catch-all route normalization (#59791) ### What? Catch-all routes are being matched to parallel routes which causes issues like an interception route being handled by the wrong page component, or a page component being associated with multiple pages resulting in a "You cannot have two parallel pages that resolve to the same path" build error. ### Why? #58215 fixed a bug that caused catchall paths to not properly match when used with parallel routes. In other words, a catchall slot wouldn't render on a page that could match that catch all. Or a catchall page wouldn't match a slot. At build time, a normalization step was introduced to take application paths and attempt to perform this matching behavior. However in it's current form, this causes the errors mentioned above to manifest. To better illustrate the problem, here are a few examples: Given: ``` { '/': [ '/page' ], '/[...slug]': [ '/[...slug]/page' ], '/items/[...ids]': [ '/items/[...ids]/page' ], '/(.)items/[...ids]': [ '/@modal/(.)items/[...ids]/page' ] } ``` The normalization logic would produce: ``` { '/': [ '/page' ], '/[...slug]': [ '/[...slug]/page' ], '/items/[...ids]': [ '/items/[...ids]/page' ], '/(.)items/[...ids]': [ '/@modal/(.)items/[...ids]/page', '/[...slug]/page' ] } ``` The interception route will now be improperly handled by `[...slug]/page` rather than the interception handler. Another example, which rather than incorrectly handling a match, will produce a build error: Given: ``` { '/': [ '/(group-b)/page' ], '/[...catcher]': [ '/(group-a)/@parallel/[...catcher]/page' ] } ``` The normalization logic would produce: ``` { '/': [ '/(group-b)/page', '/(group-a)/@parallel/[...catcher]/page' ], '/[...catcher]': [ '/(group-a)/@parallel/[...catcher]/page' ] } ``` The parallel catch-all slot is now part of `/`. This means when building the loader tree, two `children` parallel segments (aka page components) will be found when hitting `/`, which is an error. The error that was added here was originally intended to help catch scenarios like: `/app/(group-a)/page` and `/app/(group-b)/page`. However it also throws for parallel slots, which isn't necessarily an error (especially since the normalization logic will push potential matches). ### How? There are two small fixes in this PR, the rest are an abundance of e2e tests to help prevent regressions. - When normalizing catch-all routes, we will not attempt to push any page entrypoints for interception routes. These should already have all the information they need in `appPaths`. - Before throwing the error about duplicate page segments in `next-app-loader`, we check to see if it's because we already matched a page component but we also detected a parallel slot that would have matched the page slot. In this case, we don't error, since the app can recover from this. - Loading a client reference manifest shouldn't throw a cryptic require error. `loadClientReferenceManifest` is already potentially returning undefined, so this case should already be handled gracefully Separately, we'll need to follow-up on the Turbopack side to: - Make sure the duplicate matching matches the Webpack implementation (I believe Webpack is sorting, but Turbopack isn't) - Implement #58215 in Turbopack. Once this is done, we should expect the tests added in this PR to start failing. Fixes #58272 Fixes #58660 Fixes #58312 Fixes #59782 Fixes #59784 Closes NEXT-1809
2023-12-22 18:30:23 +01:00
import React from 'react'
export default function Root({
children,
modal,
}: {
children: React.ReactNode
modal: React.ReactNode
}) {
return (
<html>
<body>
<div id="children">{children}</div>
<div id="slot">{modal}</div>
</body>
</html>
)
}