@@ -121,11 +121,8 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
121121 }
122122
123123 private captureCacheTags ( cacheValue : NetlifyIncrementalCacheValue | null , key : string ) {
124- if ( ! cacheValue ) {
125- return
126- }
127-
128124 const requestContext = getRequestContext ( )
125+
129126 // Bail if we can't get request context
130127 if ( ! requestContext ) {
131128 return
@@ -141,6 +138,13 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
141138 return
142139 }
143140
141+ // Set cache tags for 404 pages as well so that the content can later be purged
142+ if ( ! cacheValue ) {
143+ const cacheTags = [ `_N_T_${ key === '/index' ? '/' : encodeURI ( key ) } ` ]
144+ requestContext . responseCacheTags = cacheTags
145+ return
146+ }
147+
144148 if (
145149 cacheValue . kind === 'PAGE' ||
146150 cacheValue . kind === 'PAGES' ||
@@ -226,7 +230,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
226230 ...args : Parameters < CacheHandlerForMultipleVersions [ 'get' ] >
227231 ) : ReturnType < CacheHandlerForMultipleVersions [ 'get' ] > {
228232 return this . tracer . withActiveSpan ( 'get cache key' , async ( span ) => {
229- const [ key , ctx = { } ] = args
233+ const [ key , context = { } ] = args
230234 getLogger ( ) . debug ( `[NetlifyCacheHandler.get]: ${ key } ` )
231235
232236 span . setAttributes ( { key } )
@@ -259,21 +263,30 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
259263 return null
260264 }
261265
262- const staleByTags = await this . checkCacheEntryStaleByTags ( blob , ctx . tags , ctx . softTags )
266+ const staleByTags = await this . checkCacheEntryStaleByTags (
267+ blob ,
268+ context . tags ,
269+ context . softTags ,
270+ )
263271
264272 if ( staleByTags ) {
265273 span . addEvent ( 'Stale' , { staleByTags, key, ttl } )
266274 return null
267275 }
268276
269277 this . captureResponseCacheLastModified ( blob , key , span )
270- this . captureCacheTags ( blob . value , key )
278+
279+ // Next sets a kind/kindHint and fetchUrl for data requests, however fetchUrl was found to be most reliable across versions
280+ const isDataRequest = Boolean ( context . fetchUrl )
281+ if ( ! isDataRequest ) {
282+ this . captureCacheTags ( blob . value , key )
283+ }
271284
272285 switch ( blob . value ?. kind ) {
273286 case 'FETCH' :
274287 span . addEvent ( 'FETCH' , {
275288 lastModified : blob . lastModified ,
276- revalidate : ctx . revalidate ,
289+ revalidate : context . revalidate ,
277290 ttl,
278291 } )
279292 return {
@@ -387,13 +400,17 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
387400
388401 const value = this . transformToStorableObject ( data , context )
389402
390- // if previous CacheHandler.get call returned null (page was either never rendered or was on-demand revalidated)
391- // and we didn't yet capture cache tags, we try to get cache tags from freshly produced cache value
392- this . captureCacheTags ( value , key )
403+ // Next sets a fetchCache and fetchUrl for data requests, however fetchUrl was found to be most reliable across versions
404+ const isDataReq = Boolean ( context . fetchUrl )
405+ if ( ! isDataReq ) {
406+ // if previous CacheHandler.get call returned null (page was either never rendered or was on-demand revalidated)
407+ // and we didn't yet capture cache tags, we try to get cache tags from freshly produced cache value
408+ this . captureCacheTags ( value , key )
409+ }
393410
394411 await this . cacheStore . set ( key , { lastModified, value } , 'blobStore.set' )
395412
396- if ( data ?. kind === 'PAGE' || data ?. kind === 'PAGES' ) {
413+ if ( ( ! data && ! isDataReq ) || data ?. kind === 'PAGE' || data ?. kind === 'PAGES' ) {
397414 const requestContext = getRequestContext ( )
398415 if ( requestContext ?. didPagesRouterOnDemandRevalidate ) {
399416 // encode here to deal with non ASCII characters in the key
0 commit comments