diff --git a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts index db6f9eb66502d9..0c601d2c0051b2 100644 --- a/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts +++ b/packages/next/src/client/components/router-reducer/reducers/find-head-in-cache.ts @@ -22,27 +22,16 @@ function findHeadInCacheImpl( // First try the 'children' parallel route if it exists // when starting from the "root", this corresponds with the main page component - if (parallelRoutes.children) { - const [segment, childParallelRoutes] = parallelRoutes.children - const childSegmentMap = cache.parallelRoutes.get('children') - if (childSegmentMap) { - const cacheKey = createRouterCacheKey(segment) - const cacheNode = childSegmentMap.get(cacheKey) - if (cacheNode) { - const item = findHeadInCacheImpl( - cacheNode, - childParallelRoutes, - keyPrefix + '/' + cacheKey - ) - if (item) return item - } - } - } + const parallelRoutesKeys = Object.keys(parallelRoutes).filter( + (key) => key !== 'children' + ) - // if we didn't find metadata in the page slot, check the other parallel routes - for (const key in parallelRoutes) { - if (key === 'children') continue // already checked above + // if we are at the root, we need to check the children slot first + if ('children' in parallelRoutes) { + parallelRoutesKeys.unshift('children') + } + for (const key of parallelRoutesKeys) { const [segment, childParallelRoutes] = parallelRoutes[key] const childSegmentMap = cache.parallelRoutes.get(key) if (!childSegmentMap) { diff --git a/packages/next/src/lib/metadata/metadata.tsx b/packages/next/src/lib/metadata/metadata.tsx index 9b8c593abec534..1413bc4f110780 100644 --- a/packages/next/src/lib/metadata/metadata.tsx +++ b/packages/next/src/lib/metadata/metadata.tsx @@ -206,9 +206,11 @@ export function createMetadataComponents({ const promise = resolveFinalMetadata() if (serveStreamingMetadata) { return ( - - - + ) } const metadataState = await promise diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index eece06cacbdeaa..1fabc8fcafab17 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -242,6 +242,8 @@ interface ParseRequestHeadersOptions { } const flightDataPathHeadKey = 'h' +const getFlightViewportKey = (requestId: string) => requestId + 'v' +const getFlightMetadataKey = (requestId: string) => requestId + 'm' interface ParsedRequestHeaders { /** @@ -333,30 +335,6 @@ function createNotFoundLoaderTree(loaderTree: LoaderTree): LoaderTree { ] } -function createDivergedMetadataComponents( - Metadata: React.ComponentType, - serveStreamingMetadata: boolean -): { - StaticMetadata: React.ComponentType<{}> - StreamingMetadata: React.ComponentType<{}> | null -} { - function EmptyMetadata() { - return null - } - const StreamingMetadata: React.ComponentType | null = serveStreamingMetadata - ? Metadata - : null - - const StaticMetadata: React.ComponentType<{}> = serveStreamingMetadata - ? EmptyMetadata - : Metadata - - return { - StaticMetadata, - StreamingMetadata, - } -} - /** * Returns a function that parses the dynamic segment and return the associated value. */ @@ -524,14 +502,6 @@ async function generateDynamicRSCPayload( serveStreamingMetadata, }) - const { StreamingMetadata, StaticMetadata } = - createDivergedMetadataComponents(() => { - return ( - // Adding requestId as react key to make metadata remount for each render - - ) - }, serveStreamingMetadata) - flightData = ( await walkTreeWithFlightRouterState({ ctx, @@ -548,9 +518,9 @@ async function generateDynamicRSCPayload( isPossibleServerAction={ctx.isPossibleServerAction} /> {/* Adding requestId as react key to make metadata remount for each render */} - - {StreamingMetadata ? : null} - + + {/* Not add requestId as react key to ensure segment prefetch could result consistently if nothing changed */} + ), injectedCSS: new Set(), @@ -854,14 +824,6 @@ async function getRSCPayload( const preloadCallbacks: PreloadCallbacks = [] - const { StreamingMetadata, StaticMetadata } = - createDivergedMetadataComponents(() => { - return ( - // Not add requestId as react key to ensure segment prefetch could result consistently if nothing changed - - ) - }, serveStreamingMetadata) - const seedData = await createComponentTree({ ctx, loaderTree: tree, @@ -875,7 +837,6 @@ async function getRSCPayload( missingSlots, preloadCallbacks, authInterrupts: ctx.renderOpts.experimental.authInterrupts, - StreamingMetadata, StreamingMetadataOutlet, }) @@ -893,8 +854,9 @@ async function getRSCPayload( statusCode={ctx.res.statusCode} isPossibleServerAction={ctx.isPossibleServerAction} /> - - + + {/* Not add requestId as react key to ensure segment prefetch could result consistently if nothing changed */} + ) @@ -981,16 +943,8 @@ async function getErrorRSCPayload( serveStreamingMetadata: serveStreamingMetadata, }) - const { StreamingMetadata, StaticMetadata } = - createDivergedMetadataComponents( - () => ( - - {/* Adding requestId as react key to make metadata remount for each render */} - - - ), - serveStreamingMetadata - ) + // {/* Adding requestId as react key to make metadata remount for each render */} + const metadata = const initialHead = ( @@ -1000,12 +954,11 @@ async function getErrorRSCPayload( isPossibleServerAction={ctx.isPossibleServerAction} /> {/* Adding requestId as react key to make metadata remount for each render */} - + {process.env.NODE_ENV === 'development' && ( )} - {StreamingMetadata ? : null} - + {metadata} ) @@ -1025,10 +978,7 @@ async function getErrorRSCPayload( const seedData: CacheNodeSeedData = [ initialTree[0], - - {StreamingMetadata ? : null} - - + {metadata} {process.env.NODE_ENV !== 'production' && err ? (