@@ -183,37 +183,56 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
183
183
184
184
private async injectEntryToPrerenderManifest (
185
185
key : string ,
186
- revalidate : NetlifyCachedPageValue [ 'revalidate' ] ,
186
+ { revalidate, cacheControl } : Pick < NetlifyCachedPageValue , 'revalidate' | 'cacheControl' > ,
187
187
) {
188
- if ( this . options . serverDistDir && ( typeof revalidate === 'number' || revalidate === false ) ) {
188
+ if (
189
+ this . options . serverDistDir &&
190
+ ( typeof revalidate === 'number' ||
191
+ revalidate === false ||
192
+ typeof cacheControl !== 'undefined' )
193
+ ) {
189
194
try {
190
195
const { loadManifest } = await import ( 'next/dist/server/load-manifest.js' )
191
196
const prerenderManifest = loadManifest (
192
197
join ( this . options . serverDistDir , '..' , 'prerender-manifest.json' ) ,
193
198
) as PrerenderManifest
194
199
195
- try {
196
- const { normalizePagePath } = await import (
197
- 'next/dist/shared/lib/page-path/normalize-page-path.js'
200
+ if ( typeof cacheControl !== 'undefined' ) {
201
+ // instead of `revalidate` property, we might get `cacheControls` ( https://github.com/vercel/next.js/pull/76207 )
202
+ // then we need to keep track of revalidate values via SharedCacheControls
203
+ const { SharedCacheControls } = await import (
204
+ // @ts -expect-error supporting multiple next version, this module is not resolvable with currently used dev dependency
205
+ // eslint-disable-next-line import/no-unresolved, n/no-missing-import
206
+ 'next/dist/server/lib/incremental-cache/shared-cache-controls.js'
198
207
)
199
-
200
- prerenderManifest . routes [ key ] = {
201
- experimentalPPR : undefined ,
202
- dataRoute : posixJoin ( '/_next/data' , `${ normalizePagePath ( key ) } .json` ) ,
203
- srcRoute : null , // FIXME: provide actual source route, however, when dynamically appending it doesn't really matter
204
- initialRevalidateSeconds : revalidate ,
205
- // Pages routes do not have a prefetch data route.
206
- prefetchDataRoute : undefined ,
208
+ const sharedCacheControls = new SharedCacheControls ( prerenderManifest )
209
+ sharedCacheControls . set ( key , cacheControl )
210
+ } else if ( typeof revalidate === 'number' || revalidate === false ) {
211
+ // if we don't get cacheControls, but we still get revalidate, it should mean we are before
212
+ // https://github.com/vercel/next.js/pull/76207
213
+ try {
214
+ const { normalizePagePath } = await import (
215
+ 'next/dist/shared/lib/page-path/normalize-page-path.js'
216
+ )
217
+
218
+ prerenderManifest . routes [ key ] = {
219
+ experimentalPPR : undefined ,
220
+ dataRoute : posixJoin ( '/_next/data' , `${ normalizePagePath ( key ) } .json` ) ,
221
+ srcRoute : null , // FIXME: provide actual source route, however, when dynamically appending it doesn't really matter
222
+ initialRevalidateSeconds : revalidate ,
223
+ // Pages routes do not have a prefetch data route.
224
+ prefetchDataRoute : undefined ,
225
+ }
226
+ } catch {
227
+ // depending on Next.js version - prerender manifest might not be mutable
228
+ // https://github.com/vercel/next.js/pull/64313
229
+ // if it's not mutable we will try to use SharedRevalidateTimings ( https://github.com/vercel/next.js/pull/64370) instead
230
+ const { SharedRevalidateTimings } = await import (
231
+ 'next/dist/server/lib/incremental-cache/shared-revalidate-timings.js'
232
+ )
233
+ const sharedRevalidateTimings = new SharedRevalidateTimings ( prerenderManifest )
234
+ sharedRevalidateTimings . set ( key , revalidate )
207
235
}
208
- } catch {
209
- // depending on Next.js version - prerender manifest might not be mutable
210
- // https://github.com/vercel/next.js/pull/64313
211
- // if it's not mutable we will try to use SharedRevalidateTimings ( https://github.com/vercel/next.js/pull/64370) instead
212
- const { SharedRevalidateTimings } = await import (
213
- 'next/dist/server/lib/incremental-cache/shared-revalidate-timings.js'
214
- )
215
- const sharedRevalidateTimings = new SharedRevalidateTimings ( prerenderManifest )
216
- sharedRevalidateTimings . set ( key , revalidate )
217
236
}
218
237
} catch { }
219
238
}
@@ -315,7 +334,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
315
334
316
335
span . addEvent ( blob . value ?. kind , { lastModified : blob . lastModified , revalidate, ttl } )
317
336
318
- await this . injectEntryToPrerenderManifest ( key , revalidate )
337
+ await this . injectEntryToPrerenderManifest ( key , blob . value )
319
338
320
339
return {
321
340
lastModified : blob . lastModified ,
@@ -327,7 +346,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
327
346
328
347
span . addEvent ( blob . value ?. kind , { lastModified : blob . lastModified , revalidate, ttl } )
329
348
330
- await this . injectEntryToPrerenderManifest ( key , revalidate )
349
+ await this . injectEntryToPrerenderManifest ( key , blob . value )
331
350
332
351
return {
333
352
lastModified : blob . lastModified ,
@@ -355,22 +374,25 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
355
374
if ( isCachedRouteValue ( data ) ) {
356
375
return {
357
376
...data ,
358
- revalidate : context . revalidate ,
377
+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
378
+ cacheControl : context . cacheControl ,
359
379
body : data . body . toString ( 'base64' ) ,
360
380
}
361
381
}
362
382
363
383
if ( isCachedPageValue ( data ) ) {
364
384
return {
365
385
...data ,
366
- revalidate : context . revalidate ,
386
+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
387
+ cacheControl : context . cacheControl ,
367
388
}
368
389
}
369
390
370
391
if ( data ?. kind === 'APP_PAGE' ) {
371
392
return {
372
393
...data ,
373
- revalidate : context . revalidate ,
394
+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
395
+ cacheControl : context . cacheControl ,
374
396
rscData : data . rscData ?. toString ( 'base64' ) ,
375
397
}
376
398
}
0 commit comments