@@ -183,37 +183,56 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
183183
184184 private async injectEntryToPrerenderManifest (
185185 key : string ,
186- revalidate : NetlifyCachedPageValue [ 'revalidate' ] ,
186+ { revalidate, cacheControl } : Pick < NetlifyCachedPageValue , 'revalidate' | 'cacheControl' > ,
187187 ) {
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+ ) {
189194 try {
190195 const { loadManifest } = await import ( 'next/dist/server/load-manifest.js' )
191196 const prerenderManifest = loadManifest (
192197 join ( this . options . serverDistDir , '..' , 'prerender-manifest.json' ) ,
193198 ) as PrerenderManifest
194199
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'
198207 )
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 )
207235 }
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 )
217236 }
218237 } catch { }
219238 }
@@ -315,7 +334,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
315334
316335 span . addEvent ( blob . value ?. kind , { lastModified : blob . lastModified , revalidate, ttl } )
317336
318- await this . injectEntryToPrerenderManifest ( key , revalidate )
337+ await this . injectEntryToPrerenderManifest ( key , blob . value )
319338
320339 return {
321340 lastModified : blob . lastModified ,
@@ -327,7 +346,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
327346
328347 span . addEvent ( blob . value ?. kind , { lastModified : blob . lastModified , revalidate, ttl } )
329348
330- await this . injectEntryToPrerenderManifest ( key , revalidate )
349+ await this . injectEntryToPrerenderManifest ( key , blob . value )
331350
332351 return {
333352 lastModified : blob . lastModified ,
@@ -355,22 +374,25 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
355374 if ( isCachedRouteValue ( data ) ) {
356375 return {
357376 ...data ,
358- revalidate : context . revalidate ,
377+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
378+ cacheControl : context . cacheControl ,
359379 body : data . body . toString ( 'base64' ) ,
360380 }
361381 }
362382
363383 if ( isCachedPageValue ( data ) ) {
364384 return {
365385 ...data ,
366- revalidate : context . revalidate ,
386+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
387+ cacheControl : context . cacheControl ,
367388 }
368389 }
369390
370391 if ( data ?. kind === 'APP_PAGE' ) {
371392 return {
372393 ...data ,
373- revalidate : context . revalidate ,
394+ revalidate : context . revalidate ?? context . cacheControl ?. revalidate ,
395+ cacheControl : context . cacheControl ,
374396 rscData : data . rscData ?. toString ( 'base64' ) ,
375397 }
376398 }
0 commit comments