Skip to content

Commit 09c58b7

Browse files
committed
Fix missing keys in Fragments in arrays
1 parent abeabe4 commit 09c58b7

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

packages/next/src/server/app-render/app-render.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ interface ParseRequestHeadersOptions {
171171
readonly isRoutePPREnabled: boolean
172172
}
173173

174+
const flightDataPathHeadKey = 'flight-data-path-head'
175+
174176
interface ParsedRequestHeaders {
175177
/**
176178
* Router state provided from the client-side router. Used to handle rendering
@@ -368,11 +370,11 @@ async function generateDynamicRSCPayload(
368370
isFirst: true,
369371
// For flight, render metadata inside leaf page
370372
rscPayloadHead: (
371-
<>
373+
<React.Fragment key={flightDataPathHeadKey}>
372374
<NonIndex ctx={ctx} />
373375
{/* Adding requestId as react key to make metadata remount for each render */}
374376
<MetadataTree key={requestId} />
375-
</>
377+
</React.Fragment>
376378
),
377379
injectedCSS: new Set(),
378380
injectedJS: new Set(),
@@ -522,11 +524,11 @@ async function getRSCPayload(
522524
typeof varyHeader === 'string' && varyHeader.includes(NEXT_URL)
523525

524526
const initialHead = (
525-
<>
527+
<React.Fragment key={flightDataPathHeadKey}>
526528
<NonIndex ctx={ctx} />
527529
{/* Adding requestId as react key to make metadata remount for each render */}
528530
<MetadataTree key={ctx.requestId} />
529-
</>
531+
</React.Fragment>
530532
)
531533

532534
return {
@@ -539,7 +541,7 @@ async function getRSCPayload(
539541
f: [[initialTree, seedData, initialHead]],
540542
m: missingSlots,
541543
G: GlobalError,
542-
} satisfies RSCPayload & { P: React.ReactNode }
544+
} satisfies InitialRSCPayload & { P: React.ReactNode }
543545
}
544546

545547
/**
@@ -579,14 +581,14 @@ async function getErrorRSCPayload(
579581
})
580582

581583
const initialHead = (
582-
<>
584+
<React.Fragment key={flightDataPathHeadKey}>
583585
<NonIndex ctx={ctx} />
584586
{/* Adding requestId as react key to make metadata remount for each render */}
585587
<MetadataTree key={requestId} />
586588
{process.env.NODE_ENV === 'development' && (
587589
<meta name="next-error" content="not-found" />
588590
)}
589-
</>
591+
</React.Fragment>
590592
)
591593

592594
const initialTree = createFlightRouterStateFromLoaderTree(

packages/next/src/server/app-render/create-component-tree.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ function errorMissingDefaultExport(pagePath: string, convention: string) {
5454
)
5555
}
5656

57+
const cacheNodeKey = 'cache-node'
58+
5759
async function createComponentTreeInternal({
5860
createSegmentPath,
5961
loaderTree: tree,
@@ -500,10 +502,10 @@ async function createComponentTreeInternal({
500502
// identical even without it. But maybe there's some findDOMNode-related
501503
// reason that I'm not aware of, so I'm leaving it as-is out of extreme
502504
// caution, for now.
503-
<>
505+
<React.Fragment key={cacheNodeKey}>
504506
{layerAssets}
505507
{parallelRouteProps.children}
506-
</>,
508+
</React.Fragment>,
507509
loadingData,
508510
]
509511
}
@@ -526,14 +528,14 @@ async function createComponentTreeInternal({
526528
return [
527529
actualSegment,
528530
parallelRouteCacheNodeSeedData,
529-
<>
531+
<React.Fragment key={cacheNodeKey}>
530532
<Postpone
531533
prerenderState={staticGenerationStore.prerenderState}
532534
reason='dynamic = "force-dynamic" was used'
533535
route={staticGenerationStore.route}
534536
/>
535537
{layerAssets}
536-
</>,
538+
</React.Fragment>,
537539
loadingData,
538540
]
539541
}
@@ -618,7 +620,7 @@ async function createComponentTreeInternal({
618620
return [
619621
actualSegment,
620622
parallelRouteCacheNodeSeedData,
621-
<>
623+
<React.Fragment key={cacheNodeKey}>
622624
{segmentElement}
623625
{/* This null is currently critical. The wrapped Component can render null and if there was not fragment
624626
surrounding it this would look like a pending tree data state on the client which will cause an error
@@ -629,7 +631,7 @@ async function createComponentTreeInternal({
629631
null it will look like `null` (the array is elided) and this is what confuses the client router.
630632
TODO-APP update router to use a Symbol for partial tree detection */}
631633
{null}
632-
</>,
634+
</React.Fragment>,
633635
loadingData,
634636
]
635637
}

0 commit comments

Comments
 (0)