Skip to content

Commit 4c4fb34

Browse files
committed
Fix missing keys in Fragments in arrays
1 parent abeabe4 commit 4c4fb34

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

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

Lines changed: 7 additions & 5 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
/**

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

Lines changed: 6 additions & 4 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
}
@@ -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)