@@ -227,6 +227,12 @@ export type AppRenderContext = {
227
227
isNotFoundPath : boolean
228
228
nonce : string | undefined
229
229
res : BaseNextResponse
230
+ /**
231
+ * For now, the implicit tags are common for the whole route. If we ever start
232
+ * rendering/revalidating segments independently, they need to move to the
233
+ * work unit store.
234
+ */
235
+ implicitTags : ImplicitTags
230
236
}
231
237
232
238
interface ParseRequestHeadersOptions {
@@ -680,16 +686,24 @@ async function warmupDevRender(
680
686
req : BaseNextRequest ,
681
687
ctx : AppRenderContext
682
688
) : Promise < RenderResult > {
683
- const renderOpts = ctx . renderOpts
689
+ const {
690
+ clientReferenceManifest,
691
+ componentMod,
692
+ getDynamicParamFromSegment,
693
+ implicitTags,
694
+ renderOpts,
695
+ workStore,
696
+ } = ctx
697
+
684
698
if ( ! renderOpts . dev ) {
685
699
throw new InvariantError (
686
700
'generateDynamicFlightRenderResult should never be called in `next start` mode.'
687
701
)
688
702
}
689
703
690
704
const rootParams = getRootParams (
691
- ctx . componentMod . tree ,
692
- ctx . getDynamicParamFromSegment
705
+ componentMod . tree ,
706
+ getDynamicParamFromSegment
693
707
)
694
708
695
709
function onFlightDataRenderError ( err : DigestedError ) {
@@ -716,7 +730,7 @@ async function warmupDevRender(
716
730
type : 'prerender' ,
717
731
phase : 'render' ,
718
732
rootParams,
719
- implicitTags : undefined ,
733
+ implicitTags,
720
734
renderSignal : renderController . signal ,
721
735
controller : prerenderController ,
722
736
cacheSignal,
@@ -739,9 +753,9 @@ async function warmupDevRender(
739
753
// which contains the subset React.
740
754
workUnitAsyncStorage . run (
741
755
prerenderStore ,
742
- ctx . componentMod . renderToReadableStream ,
756
+ componentMod . renderToReadableStream ,
743
757
rscPayload ,
744
- ctx . clientReferenceManifest . clientModules ,
758
+ clientReferenceManifest . clientModules ,
745
759
{
746
760
onError,
747
761
signal : renderController . signal ,
@@ -759,7 +773,7 @@ async function warmupDevRender(
759
773
// that calls into renderToHTML... expects a result. We should refactor this to
760
774
// lift the warmup pathway outside of renderToHTML... but for now this suffices
761
775
return new FlightRenderResult ( '' , {
762
- fetchMetrics : ctx . workStore . fetchMetrics ,
776
+ fetchMetrics : workStore . fetchMetrics ,
763
777
devRenderResumeDataCache : createRenderResumeDataCache (
764
778
prerenderResumeDataCache
765
779
) ,
@@ -1343,6 +1357,12 @@ async function renderToHTMLOrFlightImpl(
1343
1357
1344
1358
const isActionRequest = getServerActionRequestMetadata ( req ) . isServerAction
1345
1359
1360
+ const implicitTags = await getImplicitTags (
1361
+ workStore . page ,
1362
+ url ,
1363
+ fallbackRouteParams
1364
+ )
1365
+
1346
1366
const ctx : AppRenderContext = {
1347
1367
componentMod : ComponentMod ,
1348
1368
url,
@@ -1364,16 +1384,11 @@ async function renderToHTMLOrFlightImpl(
1364
1384
nonce,
1365
1385
res,
1366
1386
sharedContext,
1387
+ implicitTags,
1367
1388
}
1368
1389
1369
1390
getTracer ( ) . setRootSpanAttribute ( 'next.route' , pagePath )
1370
1391
1371
- const implicitTags = await getImplicitTags (
1372
- workStore . page ,
1373
- url ,
1374
- fallbackRouteParams
1375
- )
1376
-
1377
1392
if ( isStaticGeneration ) {
1378
1393
// We're either building or revalidating. In either case we need to
1379
1394
// prerender our page rather than render it.
@@ -1394,8 +1409,7 @@ async function renderToHTMLOrFlightImpl(
1394
1409
ctx ,
1395
1410
metadata ,
1396
1411
workStore ,
1397
- loaderTree ,
1398
- implicitTags
1412
+ loaderTree
1399
1413
)
1400
1414
1401
1415
// If we're debugging partial prerendering, print all the dynamic API accesses
@@ -2217,7 +2231,7 @@ async function spawnDynamicValidationInDev(
2217
2231
route : string ,
2218
2232
requestStore : RequestStore
2219
2233
) : Promise < void > {
2220
- const { componentMod : ComponentMod } = ctx
2234
+ const { componentMod : ComponentMod , implicitTags } = ctx
2221
2235
const rootParams = getRootParams (
2222
2236
ComponentMod . tree ,
2223
2237
ctx . getDynamicParamFromSegment
@@ -2244,7 +2258,7 @@ async function spawnDynamicValidationInDev(
2244
2258
type : 'prerender' ,
2245
2259
phase : 'render' ,
2246
2260
rootParams,
2247
- implicitTags : undefined ,
2261
+ implicitTags,
2248
2262
renderSignal : initialServerRenderController . signal ,
2249
2263
controller : initialServerPrerenderController ,
2250
2264
cacheSignal,
@@ -2262,7 +2276,7 @@ async function spawnDynamicValidationInDev(
2262
2276
type : 'prerender' ,
2263
2277
phase : 'render' ,
2264
2278
rootParams,
2265
- implicitTags : undefined ,
2279
+ implicitTags,
2266
2280
renderSignal : initialClientController . signal ,
2267
2281
controller : initialClientController ,
2268
2282
cacheSignal,
@@ -2409,7 +2423,7 @@ async function spawnDynamicValidationInDev(
2409
2423
type : 'prerender' ,
2410
2424
phase : 'render' ,
2411
2425
rootParams,
2412
- implicitTags : undefined ,
2426
+ implicitTags,
2413
2427
renderSignal : finalServerController . signal ,
2414
2428
controller : finalServerController ,
2415
2429
// During the final prerender we don't need to track cache access so we omit the signal
@@ -2431,7 +2445,7 @@ async function spawnDynamicValidationInDev(
2431
2445
type : 'prerender' ,
2432
2446
phase : 'render' ,
2433
2447
rootParams,
2434
- implicitTags : undefined ,
2448
+ implicitTags,
2435
2449
renderSignal : finalClientController . signal ,
2436
2450
controller : finalClientController ,
2437
2451
// During the final prerender we don't need to track cache access so we omit the signal
@@ -2602,16 +2616,23 @@ async function prerenderToStream(
2602
2616
ctx : AppRenderContext ,
2603
2617
metadata : AppPageRenderResultMetadata ,
2604
2618
workStore : WorkStore ,
2605
- tree : LoaderTree ,
2606
- implicitTags : ImplicitTags
2619
+ tree : LoaderTree
2607
2620
) : Promise < PrerenderToStreamResult > {
2608
2621
// When prerendering formState is always null. We still include it
2609
2622
// because some shared APIs expect a formState value and this is slightly
2610
2623
// more explicit than making it an optional function argument
2611
2624
const formState = null
2612
- const rootParams = getRootParams ( tree , ctx . getDynamicParamFromSegment )
2613
2625
2614
- const renderOpts = ctx . renderOpts
2626
+ const {
2627
+ assetPrefix,
2628
+ getDynamicParamFromSegment,
2629
+ implicitTags,
2630
+ nonce,
2631
+ pagePath,
2632
+ renderOpts,
2633
+ } = ctx
2634
+
2635
+ const rootParams = getRootParams ( tree , getDynamicParamFromSegment )
2615
2636
const ComponentMod = renderOpts . ComponentMod
2616
2637
// TODO: fix this typescript
2617
2638
const clientReferenceManifest = renderOpts . clientReferenceManifest !
@@ -2620,7 +2641,7 @@ async function prerenderToStream(
2620
2641
const { ServerInsertedHTMLProvider, renderServerInsertedHTML } =
2621
2642
createServerInsertedHTML ( )
2622
2643
const { ServerInsertedMetadataProvider, getServerInsertedMetadata } =
2623
- createServerInsertedMetadata ( ctx . nonce )
2644
+ createServerInsertedMetadata ( nonce )
2624
2645
2625
2646
const tracingMetadata = getTracedMetadata (
2626
2647
getTracer ( ) . getTracePropagationData ( ) ,
@@ -2634,25 +2655,25 @@ async function prerenderToStream(
2634
2655
polyfill . endsWith ( '.js' ) && ! polyfill . endsWith ( '.module.js' )
2635
2656
)
2636
2657
. map ( ( polyfill ) => ( {
2637
- src : `${ ctx . assetPrefix } /_next/${ polyfill } ${ getAssetQueryString (
2658
+ src : `${ assetPrefix } /_next/${ polyfill } ${ getAssetQueryString (
2638
2659
ctx ,
2639
2660
false
2640
2661
) } `,
2641
2662
integrity : renderOpts . subresourceIntegrityManifest ?. [ polyfill ] ,
2642
2663
crossOrigin : renderOpts . crossOrigin ,
2643
2664
noModule : true ,
2644
- nonce : ctx . nonce ,
2665
+ nonce : nonce ,
2645
2666
} ) )
2646
2667
2647
2668
const [ preinitScripts , bootstrapScript ] = getRequiredScripts (
2648
2669
renderOpts . buildManifest ,
2649
2670
// Why is assetPrefix optional on renderOpts?
2650
2671
// @TODO make it default empty string on renderOpts and get rid of it from ctx
2651
- ctx . assetPrefix ,
2672
+ assetPrefix ,
2652
2673
renderOpts . crossOrigin ,
2653
2674
renderOpts . subresourceIntegrityManifest ,
2654
2675
getAssetQueryString ( ctx , true ) ,
2655
- ctx . nonce ,
2676
+ nonce ,
2656
2677
renderOpts . page
2657
2678
)
2658
2679
@@ -2882,7 +2903,7 @@ async function prerenderToStream(
2882
2903
ServerInsertedMetadataProvider = {
2883
2904
ServerInsertedMetadataProvider
2884
2905
}
2885
- nonce = { ctx . nonce }
2906
+ nonce = { nonce }
2886
2907
/> ,
2887
2908
{
2888
2909
signal : initialClientController . signal ,
@@ -3040,7 +3061,7 @@ async function prerenderToStream(
3040
3061
clientReferenceManifest = { clientReferenceManifest }
3041
3062
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3042
3063
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3043
- nonce = { ctx . nonce }
3064
+ nonce = { nonce }
3044
3065
/> ,
3045
3066
{
3046
3067
signal : finalClientController . signal ,
@@ -3165,13 +3186,13 @@ async function prerenderToStream(
3165
3186
clientReferenceManifest = { clientReferenceManifest }
3166
3187
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3167
3188
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3168
- nonce = { ctx . nonce }
3189
+ nonce = { nonce }
3169
3190
/> ,
3170
3191
JSON . parse ( JSON . stringify ( postponed ) ) ,
3171
3192
{
3172
3193
signal : createPostponedAbortSignal ( 'static prerender resume' ) ,
3173
3194
onError : htmlRendererErrorHandler ,
3174
- nonce : ctx . nonce ,
3195
+ nonce,
3175
3196
}
3176
3197
)
3177
3198
@@ -3185,7 +3206,7 @@ async function prerenderToStream(
3185
3206
stream : await continueStaticPrerender ( htmlStream , {
3186
3207
inlinedDataStream : createInlinedDataReadableStream (
3187
3208
reactServerResult . consumeAsStream ( ) ,
3188
- ctx . nonce ,
3209
+ nonce ,
3189
3210
formState
3190
3211
) ,
3191
3212
getServerInsertedHTML,
@@ -3356,7 +3377,7 @@ async function prerenderToStream(
3356
3377
clientReferenceManifest = { clientReferenceManifest }
3357
3378
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3358
3379
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3359
- nonce = { ctx . nonce }
3380
+ nonce = { nonce }
3360
3381
/> ,
3361
3382
{
3362
3383
signal : initialClientController . signal ,
@@ -3511,7 +3532,7 @@ async function prerenderToStream(
3511
3532
ServerInsertedMetadataProvider = {
3512
3533
ServerInsertedMetadataProvider
3513
3534
}
3514
- nonce = { ctx . nonce }
3535
+ nonce = { nonce }
3515
3536
/> ,
3516
3537
{
3517
3538
signal : finalClientController . signal ,
@@ -3608,7 +3629,7 @@ async function prerenderToStream(
3608
3629
stream : await continueFizzStream ( htmlStream ! , {
3609
3630
inlinedDataStream : createInlinedDataReadableStream (
3610
3631
serverPrerenderStreamResult . asStream ( ) ,
3611
- ctx . nonce ,
3632
+ nonce ,
3612
3633
formState
3613
3634
) ,
3614
3635
isStaticGeneration : true ,
@@ -3690,7 +3711,7 @@ async function prerenderToStream(
3690
3711
clientReferenceManifest = { clientReferenceManifest }
3691
3712
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3692
3713
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3693
- nonce = { ctx . nonce }
3714
+ nonce = { nonce }
3694
3715
/> ,
3695
3716
{
3696
3717
onError : htmlRendererErrorHandler ,
@@ -3822,13 +3843,13 @@ async function prerenderToStream(
3822
3843
clientReferenceManifest = { clientReferenceManifest }
3823
3844
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3824
3845
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3825
- nonce = { ctx . nonce }
3846
+ nonce = { nonce }
3826
3847
/> ,
3827
3848
JSON . parse ( JSON . stringify ( postponed ) ) ,
3828
3849
{
3829
3850
signal : createPostponedAbortSignal ( 'static prerender resume' ) ,
3830
3851
onError : htmlRendererErrorHandler ,
3831
- nonce : ctx . nonce ,
3852
+ nonce,
3832
3853
}
3833
3854
)
3834
3855
@@ -3842,7 +3863,7 @@ async function prerenderToStream(
3842
3863
stream : await continueStaticPrerender ( htmlStream , {
3843
3864
inlinedDataStream : createInlinedDataReadableStream (
3844
3865
reactServerResult . consumeAsStream ( ) ,
3845
- ctx . nonce ,
3866
+ nonce ,
3846
3867
formState
3847
3868
) ,
3848
3869
getServerInsertedHTML,
@@ -3901,11 +3922,11 @@ async function prerenderToStream(
3901
3922
clientReferenceManifest = { clientReferenceManifest }
3902
3923
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
3903
3924
ServerInsertedMetadataProvider = { ServerInsertedMetadataProvider }
3904
- nonce = { ctx . nonce }
3925
+ nonce = { nonce }
3905
3926
/> ,
3906
3927
{
3907
3928
onError : htmlRendererErrorHandler ,
3908
- nonce : ctx . nonce ,
3929
+ nonce,
3909
3930
bootstrapScripts : [ bootstrapScript ] ,
3910
3931
}
3911
3932
)
@@ -3935,7 +3956,7 @@ async function prerenderToStream(
3935
3956
stream : await continueFizzStream ( htmlStream , {
3936
3957
inlinedDataStream : createInlinedDataReadableStream (
3937
3958
reactServerResult . consumeAsStream ( ) ,
3938
- ctx . nonce ,
3959
+ nonce ,
3939
3960
formState
3940
3961
) ,
3941
3962
isStaticGeneration : true ,
@@ -3976,7 +3997,7 @@ async function prerenderToStream(
3976
3997
if ( shouldBailoutToCSR ) {
3977
3998
const stack = getStackWithoutErrorMessage ( err )
3978
3999
error (
3979
- `${ err . reason } should be wrapped in a suspense boundary at page "${ ctx . pagePath } ". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout\n${ stack } `
4000
+ `${ err . reason } should be wrapped in a suspense boundary at page "${ pagePath } ". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout\n${ stack } `
3980
4001
)
3981
4002
3982
4003
throw err
@@ -4009,11 +4030,11 @@ async function prerenderToStream(
4009
4030
4010
4031
const [ errorPreinitScripts , errorBootstrapScript ] = getRequiredScripts (
4011
4032
renderOpts . buildManifest ,
4012
- ctx . assetPrefix ,
4033
+ assetPrefix ,
4013
4034
renderOpts . crossOrigin ,
4014
4035
renderOpts . subresourceIntegrityManifest ,
4015
4036
getAssetQueryString ( ctx , false ) ,
4016
- ctx . nonce ,
4037
+ nonce ,
4017
4038
'/_not-found/page'
4018
4039
)
4019
4040
@@ -4065,11 +4086,11 @@ async function prerenderToStream(
4065
4086
ServerInsertedHTMLProvider = { ServerInsertedHTMLProvider }
4066
4087
preinitScripts = { errorPreinitScripts }
4067
4088
clientReferenceManifest = { clientReferenceManifest }
4068
- nonce = { ctx . nonce }
4089
+ nonce = { nonce }
4069
4090
/>
4070
4091
) ,
4071
4092
streamOptions : {
4072
- nonce : ctx . nonce ,
4093
+ nonce,
4073
4094
// Include hydration scripts in the HTML
4074
4095
bootstrapScripts : [ errorBootstrapScript ] ,
4075
4096
formState,
@@ -4107,7 +4128,7 @@ async function prerenderToStream(
4107
4128
stream : await continueFizzStream ( fizzStream , {
4108
4129
inlinedDataStream : createInlinedDataReadableStream (
4109
4130
flightStream ,
4110
- ctx . nonce ,
4131
+ nonce ,
4111
4132
formState
4112
4133
) ,
4113
4134
isStaticGeneration : true ,
0 commit comments