Ensure route group with separate root layout does not get wrapped in <div> (#38792)

Ensures the `<html>` is not wrapped in an extra div when the root layout is nested in a route group.


## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
This commit is contained in:
Tim Neutkens 2022-07-19 15:42:37 +02:00 committed by GitHub
parent bae0482b19
commit 9b312dbbe0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 15 deletions

View file

@ -56,6 +56,7 @@ export function InnerLayoutRouter({
tree,
// isActive,
path,
rootLayoutIncluded,
}: {
parallelRouterKey: string
url: string
@ -65,6 +66,7 @@ export function InnerLayoutRouter({
tree: FlightRouterState
isActive: boolean
path: string
rootLayoutIncluded: boolean
}) {
const {
changeByServerResponse,
@ -216,19 +218,24 @@ export function InnerLayoutRouter({
throw createInfinitePromise()
}
return (
<div ref={focusAndScrollRef}>
<AppTreeContext.Provider
value={{
tree: tree[1][parallelRouterKey],
childNodes: childNode.parallelRoutes,
// TODO-APP: overriding of url for parallel routes
url: url,
}}
>
{childNode.subTreeData}
</AppTreeContext.Provider>
</div>
const subtree = (
<AppTreeContext.Provider
value={{
tree: tree[1][parallelRouterKey],
childNodes: childNode.parallelRoutes,
// TODO-APP: overriding of url for parallel routes
url: url,
}}
>
{childNode.subTreeData}
</AppTreeContext.Provider>
)
// Ensure root layout is not wrapped in a div
return rootLayoutIncluded ? (
<div ref={focusAndScrollRef}>{subtree}</div>
) : (
subtree
)
}
@ -251,11 +258,13 @@ export default function OuterLayoutRouter({
segmentPath,
childProp,
loading,
rootLayoutIncluded,
}: {
parallelRouterKey: string
segmentPath: FlightSegmentPath
childProp: ChildProp
loading: React.ReactNode | undefined
rootLayoutIncluded: boolean
}) {
const { childNodes, tree, url } = useContext(AppTreeContext)
@ -297,6 +306,7 @@ export default function OuterLayoutRouter({
segmentPath={segmentPath}
path={preservedSegment}
isActive={currentChildSegment === preservedSegment}
rootLayoutIncluded={rootLayoutIncluded}
/>
</LoadingBoundary>
)

View file

@ -543,15 +543,21 @@ export async function renderToHTML(
tree: [segment, parallelRoutes, { layout, loading, page }],
parentParams,
firstItem,
rootLayoutIncluded,
}: {
createSegmentPath: CreateSegmentPath
tree: LoaderTree
parentParams: { [key: string]: any }
rootLayoutIncluded?: boolean
firstItem?: boolean
}): { Component: React.ComponentType } => {
const Loading = loading ? interopDefault(loading()) : undefined
const layoutOrPageMod = layout ? layout() : page ? page() : undefined
const isPage = typeof page !== undefined
const isLayout = typeof layout !== 'undefined'
const isPage = typeof page !== 'undefined'
const layoutOrPageMod = isLayout ? layout() : isPage ? page() : undefined
const rootLayoutAtThisLevel = isLayout && !rootLayoutIncluded
const rootLayoutIncludedAtThisLevelOrAbove =
rootLayoutIncluded || rootLayoutAtThisLevel
const isClientComponentModule =
layoutOrPageMod && !layoutOrPageMod.hasOwnProperty('__next_rsc__')
@ -600,6 +606,7 @@ export async function renderToHTML(
},
tree: parallelRoutes[currentValue],
parentParams: currentParams,
rootLayoutIncluded: rootLayoutIncludedAtThisLevelOrAbove,
})
const childSegmentParam = getDynamicParamFromSegment(
@ -622,6 +629,7 @@ export async function renderToHTML(
segmentPath={createSegmentPath(currentSegmentPath)}
loading={Loading ? <Loading /> : undefined}
childProp={childProp}
rootLayoutIncluded={rootLayoutIncludedAtThisLevelOrAbove}
/>
)