@@ -57,6 +57,7 @@ const appRouteHandlerCachePath = resolveEntryPath(
5757 "../server/app-route-handler-cache.js" ,
5858 import . meta. url ,
5959) ;
60+ const implicitTagsPath = resolveEntryPath ( "../server/implicit-tags.js" , import . meta. url ) ;
6061const appPageCachePath = resolveEntryPath ( "../server/app-page-cache.js" , import . meta. url ) ;
6162const appPageExecutionPath = resolveEntryPath ( "../server/app-page-execution.js" , import . meta. url ) ;
6263const appPageBoundaryRenderPath = resolveEntryPath (
@@ -437,6 +438,7 @@ import {
437438import {
438439 applyRouteHandlerMiddlewareContext as __applyRouteHandlerMiddlewareContext,
439440} from ${ JSON . stringify ( appRouteHandlerResponsePath ) } ;
441+ import { buildPageCacheTags } from ${ JSON . stringify ( implicitTagsPath ) } ;
440442import { _consumeRequestScopedCacheLife, getCacheHandler } from "next/cache";
441443import { getRequestExecutionContext as _getRequestExecutionContext } from ${ JSON . stringify ( requestContextShimPath ) } ;
442444import { setRootParams as __setRootParams, pickRootParams as __pickRootParams } from ${ JSON . stringify ( rootParamsShimPath ) } ;
@@ -502,27 +504,6 @@ async function __isrSet(key, data, revalidateSeconds, tags) {
502504 const handler = getCacheHandler();
503505 await handler.set(key, data, { revalidate: revalidateSeconds, tags: Array.isArray(tags) ? tags : [] });
504506}
505- function __pageCacheTags(pathname, extraTags) {
506- const tags = [pathname, "_N_T_" + pathname];
507- // Layout hierarchy tags — matches Next.js getDerivedTags.
508- tags.push("_N_T_/layout");
509- const segments = pathname.split("/");
510- let built = "";
511- for (let i = 1; i < segments.length; i++) {
512- if (segments[i]) {
513- built += "/" + segments[i];
514- tags.push("_N_T_" + built + "/layout");
515- }
516- }
517- // Leaf page tag — revalidatePath(path, "page") targets this.
518- tags.push("_N_T_" + built + "/page");
519- if (Array.isArray(extraTags)) {
520- for (const tag of extraTags) {
521- if (!tags.includes(tag)) tags.push(tag);
522- }
523- }
524- return tags;
525- }
526507// Note: cache entries are written with \`headers: undefined\`. Next.js stores
527508// response headers (e.g. set-cookie from cookies().set() during render) in the
528509// cache entry so they can be replayed on HIT. We don't do this because:
@@ -2122,7 +2103,9 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
21222103 }
21232104
21242105 const { route, params } = match;
2125- setCurrentFetchSoftTags(__pageCacheTags(cleanPathname, []));
2106+ setCurrentFetchSoftTags(
2107+ buildPageCacheTags(cleanPathname, [], route.routeSegments, route.routeHandler ? "route" : "page"),
2108+ );
21262109
21272110 // Update navigation context with matched params
21282111 setNavigationContext({
@@ -2137,6 +2120,9 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
21372120 const handler = route.routeHandler;
21382121 const method = request.method.toUpperCase();
21392122 const revalidateSeconds = __getAppRouteHandlerRevalidateSeconds(handler);
2123+ const __buildRouteHandlerPageCacheTags = function(pathname, extraTags) {
2124+ return buildPageCacheTags(pathname, extraTags, route.routeSegments, "route");
2125+ };
21402126 if (__hasAppRouteHandlerDefaultExport(handler) && process.env.NODE_ENV === "development") {
21412127 console.error(
21422128 "[vinext] Detected default export in route handler " + route.pattern + ". Export a named export for each HTTP method instead.",
@@ -2179,7 +2165,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
21792165 ) {
21802166 const __cachedRouteResponse = await __readAppRouteHandlerCacheResponse({
21812167 basePath: __basePath,
2182- buildPageCacheTags: __pageCacheTags ,
2168+ buildPageCacheTags: __buildRouteHandlerPageCacheTags ,
21832169 cleanPathname,
21842170 clearRequestContext: function() {
21852171 __clearRequestContext();
@@ -2209,7 +2195,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
22092195 });
22102196 await _runWithUnifiedCtx(__revalUCtx, async () => {
22112197 _ensureFetchPatch();
2212- setCurrentFetchSoftTags(__pageCacheTags (cleanPathname, []));
2198+ setCurrentFetchSoftTags(buildPageCacheTags (cleanPathname, [], route.routeSegments, "route" ));
22132199 await renderFn();
22142200 });
22152201 },
@@ -2224,7 +2210,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
22242210 if (typeof handlerFn === "function") {
22252211 return __executeAppRouteHandler({
22262212 basePath: __basePath,
2227- buildPageCacheTags: __pageCacheTags ,
2213+ buildPageCacheTags: __buildRouteHandlerPageCacheTags ,
22282214 cleanPathname,
22292215 clearRequestContext: function() {
22302216 __clearRequestContext();
@@ -2370,7 +2356,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
23702356 });
23712357 return _runWithUnifiedCtx(__revalUCtx, async () => {
23722358 _ensureFetchPatch();
2373- setCurrentFetchSoftTags(__pageCacheTags (cleanPathname, []));
2359+ setCurrentFetchSoftTags(buildPageCacheTags (cleanPathname, [], route.routeSegments, "page" ));
23742360 setNavigationContext({ pathname: cleanPathname, searchParams: new URLSearchParams(), params });
23752361 // Slot context (X-Vinext-Mounted-Slots) is inherited from the
23762362 // triggering request so the regen result is cached under the
@@ -2400,7 +2386,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
24002386 __clearRequestContext();
24012387 const __freshHtml = await __readAppPageTextStream(__revalHtmlStream);
24022388 const __freshRscData = await __revalRscCapture.capturedRscDataPromise;
2403- const __pageTags = __pageCacheTags (cleanPathname, getCollectedFetchTags());
2389+ const __pageTags = buildPageCacheTags (cleanPathname, getCollectedFetchTags(), route.routeSegments, "page" );
24042390 return { html: __freshHtml, rscData: __freshRscData, tags: __pageTags };
24052391 });
24062392 },
@@ -2565,7 +2551,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
25652551 getFontStyles: _getSSRFontStyles,
25662552 getNavigationContext: _getNavigationContext,
25672553 getPageTags() {
2568- return __pageCacheTags (cleanPathname, getCollectedFetchTags());
2554+ return buildPageCacheTags (cleanPathname, getCollectedFetchTags(), route.routeSegments, "page" );
25692555 },
25702556 getRequestCacheLife() {
25712557 return _consumeRequestScopedCacheLife();
0 commit comments