vinext 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +5 -2
  2. package/dist/build/action-owner-manifest.js +1 -0
  3. package/dist/build/prerender-paths.d.ts +11 -1
  4. package/dist/build/prerender-paths.js +36 -10
  5. package/dist/check.js +1 -1
  6. package/dist/cli.js +1 -1
  7. package/dist/client/dev-error-overlay.d.ts +2 -1
  8. package/dist/client/dev-error-overlay.js +8 -3
  9. package/dist/config/config-matchers.js +8 -4
  10. package/dist/config/destination-params.js +5 -2
  11. package/dist/config/next-config.d.ts +25 -1
  12. package/dist/config/next-config.js +31 -1
  13. package/dist/entries/app-rsc-entry.js +65 -30
  14. package/dist/entries/app-rsc-manifest.js +4 -0
  15. package/dist/entries/pages-server-entry.js +19 -4
  16. package/dist/index.js +37 -37
  17. package/dist/init-cloudflare.js +18 -2
  18. package/dist/init-platform.js +2 -2
  19. package/dist/init.js +42 -5
  20. package/dist/plugins/css-target.d.ts +18 -0
  21. package/dist/plugins/css-target.js +93 -0
  22. package/dist/routing/app-route-graph.d.ts +10 -0
  23. package/dist/routing/app-route-graph.js +15 -1
  24. package/dist/server/api-handler.d.ts +2 -0
  25. package/dist/server/api-handler.js +10 -8
  26. package/dist/server/app-action-forwarding.js +3 -1
  27. package/dist/server/app-browser-entry.js +37 -41
  28. package/dist/server/app-browser-error.d.ts +1 -1
  29. package/dist/server/app-browser-error.js +13 -4
  30. package/dist/server/app-browser-supplemental-refresh.d.ts +13 -0
  31. package/dist/server/app-browser-supplemental-refresh.js +36 -4
  32. package/dist/server/app-elements.d.ts +3 -0
  33. package/dist/server/app-elements.js +14 -1
  34. package/dist/server/app-fallback-renderer.js +2 -2
  35. package/dist/server/app-middleware.d.ts +2 -0
  36. package/dist/server/app-middleware.js +1 -0
  37. package/dist/server/app-optimistic-routing.d.ts +12 -1
  38. package/dist/server/app-optimistic-routing.js +38 -16
  39. package/dist/server/app-page-boundary-render.js +4 -2
  40. package/dist/server/app-page-cache-render.js +1 -1
  41. package/dist/server/app-page-dispatch.d.ts +11 -1
  42. package/dist/server/app-page-dispatch.js +78 -31
  43. package/dist/server/app-page-element-builder.d.ts +11 -20
  44. package/dist/server/app-page-element-builder.js +39 -50
  45. package/dist/server/app-page-intercept-segment-config.d.ts +56 -0
  46. package/dist/server/app-page-intercept-segment-config.js +90 -0
  47. package/dist/server/app-page-navigation-params.d.ts +23 -0
  48. package/dist/server/app-page-navigation-params.js +49 -0
  49. package/dist/server/app-page-render.d.ts +5 -2
  50. package/dist/server/app-page-render.js +17 -3
  51. package/dist/server/app-page-request.d.ts +24 -2
  52. package/dist/server/app-page-request.js +10 -10
  53. package/dist/server/app-page-route-wiring.d.ts +17 -5
  54. package/dist/server/app-page-route-wiring.js +19 -13
  55. package/dist/server/app-page-segment-plan.js +9 -1
  56. package/dist/server/app-page-segment-state.d.ts +9 -0
  57. package/dist/server/app-page-segment-state.js +54 -1
  58. package/dist/server/app-pages-bridge.d.ts +6 -0
  59. package/dist/server/app-pages-bridge.js +8 -3
  60. package/dist/server/app-request-stage-independent-entry.js +2 -3
  61. package/dist/server/app-response-stage-entry.js +1 -0
  62. package/dist/server/app-route-module-loader.d.ts +2 -0
  63. package/dist/server/app-route-module-loader.js +1 -0
  64. package/dist/server/app-router-entry.js +2 -3
  65. package/dist/server/app-rsc-cache-busting.d.ts +8 -0
  66. package/dist/server/app-rsc-cache-busting.js +13 -1
  67. package/dist/server/app-rsc-combined-handler.js +2 -1
  68. package/dist/server/app-rsc-handler.d.ts +14 -1
  69. package/dist/server/app-rsc-handler.js +111 -62
  70. package/dist/server/app-rsc-response-finalizer.d.ts +18 -3
  71. package/dist/server/app-rsc-response-finalizer.js +61 -7
  72. package/dist/server/app-rsc-route-matching.d.ts +14 -0
  73. package/dist/server/app-rsc-route-matching.js +42 -18
  74. package/dist/server/app-server-action-execution.js +16 -10
  75. package/dist/server/app-ssr-entry.js +8 -0
  76. package/dist/server/cache-control.d.ts +2 -0
  77. package/dist/server/cache-control.js +3 -1
  78. package/dist/server/config-headers.d.ts +7 -0
  79. package/dist/server/config-headers.js +20 -1
  80. package/dist/server/image-animation.d.ts +9 -0
  81. package/dist/server/image-animation.js +118 -0
  82. package/dist/server/image-local-patterns.d.ts +21 -0
  83. package/dist/server/image-local-patterns.js +59 -0
  84. package/dist/server/image-optimization.d.ts +48 -27
  85. package/dist/server/image-optimization.js +316 -22
  86. package/dist/server/image-source-reader.d.ts +34 -0
  87. package/dist/server/image-source-reader.js +126 -0
  88. package/dist/server/metadata-route-response.d.ts +6 -1
  89. package/dist/server/metadata-route-response.js +46 -10
  90. package/dist/server/middleware-matcher.d.ts +1 -0
  91. package/dist/server/middleware-matcher.js +1 -1
  92. package/dist/server/middleware-runtime.d.ts +5 -0
  93. package/dist/server/middleware-runtime.js +48 -15
  94. package/dist/server/middleware.d.ts +1 -1
  95. package/dist/server/middleware.js +2 -1
  96. package/dist/server/nitro-public-files-plugin.js +20 -8
  97. package/dist/server/nitro-request-target-plugin.d.ts +17 -0
  98. package/dist/server/nitro-request-target-plugin.js +22 -0
  99. package/dist/server/open-redirect.d.ts +2 -1
  100. package/dist/server/open-redirect.js +2 -1
  101. package/dist/server/pages-client-assets.d.ts +1 -0
  102. package/dist/server/pages-data-route.d.ts +5 -1
  103. package/dist/server/pages-data-route.js +14 -6
  104. package/dist/server/pages-i18n.d.ts +7 -0
  105. package/dist/server/pages-i18n.js +14 -1
  106. package/dist/server/pages-node-compat.js +7 -3
  107. package/dist/server/pages-page-handler.js +4 -4
  108. package/dist/server/pages-request-pipeline.d.ts +9 -0
  109. package/dist/server/pages-request-pipeline.js +35 -15
  110. package/dist/server/pages-request-stage-entry.js +8 -2
  111. package/dist/server/pages-router-entry.js +3 -0
  112. package/dist/server/prod-server.d.ts +1 -1
  113. package/dist/server/prod-server.js +64 -62
  114. package/dist/server/request-pipeline.d.ts +5 -0
  115. package/dist/server/request-pipeline.js +11 -1
  116. package/dist/server/response-stage-cacheability.d.ts +7 -0
  117. package/dist/server/response-stage-cacheability.js +6 -5
  118. package/dist/server/srvx-middleware-origin.d.ts +13 -0
  119. package/dist/server/srvx-middleware-origin.js +19 -0
  120. package/dist/server/srvx-request-target.d.ts +12 -0
  121. package/dist/server/srvx-request-target.js +20 -0
  122. package/dist/server/static-file-cache.js +10 -22
  123. package/dist/server/worker-image-optimization.d.ts +10 -3
  124. package/dist/server/worker-image-optimization.js +43 -9
  125. package/dist/server/worker-revalidation-context.js +1 -0
  126. package/dist/server/worker-utils.d.ts +8 -0
  127. package/dist/server/worker-utils.js +19 -2
  128. package/dist/shims/error-boundary.d.ts +6 -2
  129. package/dist/shims/error-boundary.js +4 -2
  130. package/dist/shims/image-props.d.ts +6 -0
  131. package/dist/shims/image-props.js +39 -3
  132. package/dist/shims/image.js +3 -3
  133. package/dist/shims/request-context.d.ts +3 -1
  134. package/dist/shims/slot.d.ts +3 -0
  135. package/dist/shims/slot.js +67 -9
  136. package/dist/shims/url-utils.js +6 -1
  137. package/dist/utils/base-path.d.ts +7 -0
  138. package/dist/utils/base-path.js +11 -1
  139. package/dist/utils/client-entry-manifest.d.ts +5 -0
  140. package/dist/utils/client-entry-manifest.js +1 -0
  141. package/dist/utils/client-runtime-metadata.d.ts +5 -0
  142. package/dist/utils/client-runtime-metadata.js +33 -7
  143. package/package.json +1 -1
@@ -4,23 +4,24 @@ import { PRERENDER_REVALIDATE_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROU
4
4
  import { buildRequestHeadersFromMiddlewareResponse, hasMiddlewareRequestHeaderOverrides } from "../utils/middleware-request-headers.js";
5
5
  import { requestContextFromRequest } from "../config/request-context.js";
6
6
  import { isExternalUrl } from "../utils/external-url.js";
7
- import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
7
+ import { hasBasePath, restoreBasePath, stripBasePath } from "../utils/base-path.js";
8
8
  import "./app-rsc-vary.js";
9
9
  import { ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_REWRITTEN_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
10
10
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
11
- import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, normalizeTrailingSlashPathname, resolvePublicFileRoute, stripRequestUrlFragment } from "./request-pipeline.js";
11
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, hasUrlParserDotSegment, normalizeTrailingSlash, normalizeTrailingSlashPathname, resolvePublicFileRoute, stripRequestUrlFragment } from "./request-pipeline.js";
12
12
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
13
13
  import { normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
14
14
  import { patternToNextFormat } from "../routing/route-validation.js";
15
15
  import { getRequestExecutionContext } from "../shims/request-context.js";
16
16
  import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
17
17
  import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
18
- import { normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
18
+ import { isLocaleRedirect, normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
19
19
  import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
20
20
  import { markRouteCacheabilityDynamic, preserveRouteCacheabilityResponsePolicy } from "../shims/cacheability-classification.js";
21
- import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders, captureCdnResponsePolicyOverrides, isCdnResponsePolicyHeader, reconcileCdnResponseHeadersAfterOuterPolicy } from "./cache-control.js";
21
+ import { NEVER_CACHE_CONTROL, SERVER_ACTION_CACHE_CONTROL, applyCdnResponseHeaders, captureCdnResponsePolicyOverrides, isCdnResponsePolicyHeader, reconcileCdnResponseHeadersAfterOuterPolicy } from "./cache-control.js";
22
22
  import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
23
23
  import { getDraftModeCookieHeader, getEffectiveRequestCookieHeader, getHeadersContext, hasEffectiveRequestCookieChanges, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, runWithHeadersContext } from "../shims/headers.js";
24
+ import { normalizePathTrailingSlash } from "../shims/url-utils.js";
24
25
  import { mergeRewriteQuery } from "../utils/query.js";
25
26
  import { getScriptNonceFromHeaderSources } from "./csp.js";
26
27
  import { traceFindPageComponents } from "./pages-execution-tracing.js";
@@ -31,13 +32,15 @@ import { openForwardedMiddlewareContext } from "./forwarded-middleware-context.j
31
32
  import { consumeResponseStageLinkProvenance, copyLinkHeaderProvenance } from "./app-response-header-provenance.js";
32
33
  import { setFrameworkRequestRoute, traceFrameworkRequest } from "./request-tracing.js";
33
34
  import { mergeMiddlewareResponseHeaders, mergeMiddlewareResponseHeadersOntoResponse, withExternalRewriteResponseHeaders } from "./middleware-response-headers.js";
34
- import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
35
+ import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeDynamicShellRscRequestHeaders, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
35
36
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
37
+ import { applyAppRscConfigHeaders, finalizeAppRscResponse, isStreamedActionRedirectResponse, markAppRscApplicationResponse, markAppRscResponseConfigHeadersApplied, markAppRscRouteHandlerResponse, markStreamedActionRedirectResponse } from "./app-rsc-response-finalizer.js";
36
38
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
37
39
  import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
38
40
  import "./app-page-response.js";
39
41
  import { parseNextHttpErrorDigest } from "./next-error-digest.js";
40
42
  import { isAppRouteHandlerRoute } from "./app-rsc-route-matching.js";
43
+ import { resolveAppPageNavigationParams } from "./app-page-navigation-params.js";
41
44
  import { traceAppPageRender } from "./app-page-tracing.js";
42
45
  import { normalizeInterceptionContextHeader } from "./app-interception-context-header.js";
43
46
  import { buildPageCacheTags } from "./implicit-tags.js";
@@ -46,7 +49,6 @@ import { pickRootParams, setRootParams } from "../shims/root-params.js";
46
49
  import { createRouteTreePrefetchResponse, isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
47
50
  import { createSharedAppCacheIdentity, createSharedAppPageCacheIdentity, createSharedAppRouteCacheIdentity, createSharedHybridPagesCacheIdentity, isStaticCandidateAppPageDispatch, prepareSharedAppPageDispatch, withoutAppPageDispatchQuery } from "./app-worker-stages.js";
48
51
  import { flattenErrorCauses } from "../utils/error-cause.js";
49
- import { applyAppRscConfigHeaders, finalizeAppRscResponse, markAppRscResponseConfigHeadersApplied } from "./app-rsc-response-finalizer.js";
50
52
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
51
53
  import { hasPagesPreviewCookie } from "./pages-response-stage.js";
52
54
  import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
@@ -132,11 +134,8 @@ function readCacheabilityRequestProjection(options) {
132
134
  };
133
135
  return parsedCacheabilityRequestProjection.manifest;
134
136
  }
135
- function hasUrlParserDotSegment(pathname) {
136
- return pathname.split("/").some((segment) => {
137
- const decodedDots = segment.replaceAll(/%2e/gi, ".");
138
- return decodedDots === "." || decodedDots === "..";
139
- });
137
+ function isSameInterceptionSource(a, b) {
138
+ return b != null && (a.authorizationRoute ?? a.route) === b.route && haveSamePageParams(a.authorizationParams ?? a.params, b.params);
140
139
  }
141
140
  function applyMiddlewareContextToResponse(response, middlewareContext, appendToPostConfigLink = false) {
142
141
  if (!middlewareContext.headers && middlewareContext.status == null) return response;
@@ -152,6 +151,27 @@ function applyMiddlewareContextToResponse(response, middlewareContext, appendToP
152
151
  }));
153
152
  }
154
153
  /**
154
+ * These headers describe the current routed request, not the shared RSC
155
+ * bytes, so they are composed above a transported response stage: a cache HIT
156
+ * cannot replay another query/path and never loses dynamic params. An
157
+ * intercepted response's params include its target's, which this match lacks,
158
+ * so the response stage keeps them under an interception context, in its
159
+ * cache identity.
160
+ */
161
+ function withRoutedRscHeaders(response, navigationParams, resolvedUrl, keepsRenderedParams) {
162
+ const headers = new Headers(response.headers);
163
+ if (!keepsRenderedParams || !headers.has("X-Vinext-Params")) {
164
+ if (Object.keys(navigationParams).length > 0) headers.set(VINEXT_PARAMS_HEADER, encodeURIComponent(JSON.stringify(navigationParams)));
165
+ else headers.delete(VINEXT_PARAMS_HEADER);
166
+ }
167
+ headers.set(VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, encodeURIComponent(resolvedUrl));
168
+ return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
169
+ headers,
170
+ status: response.status,
171
+ statusText: response.statusText
172
+ }));
173
+ }
174
+ /**
155
175
  * Next.js answers a Link's segment prefetch of a page whose notFound(),
156
176
  * forbidden() or unauthorized() it stored with a 200, so its router renders
157
177
  * the page's fallback without loading the document. A shared response stage
@@ -257,10 +277,10 @@ function requestWithoutRscCacheBustingSearchParam(request) {
257
277
  stripRscCacheBustingSearchParam(url);
258
278
  return cloneRequestWithUrl(request, url.toString());
259
279
  }
260
- /** Send a response with the never-cache policy, rebuilding immutable headers. */
261
- function withNeverCacheControl(response) {
280
+ /** Send a response with a never-cache policy, rebuilding immutable headers. */
281
+ function withNeverCacheControl(response, cacheControl = NEVER_CACHE_CONTROL) {
262
282
  const applyNoStore = (headers) => {
263
- applyCdnResponseHeaders(headers, { cacheControl: NEVER_CACHE_CONTROL });
283
+ applyCdnResponseHeaders(headers, { cacheControl });
264
284
  };
265
285
  let markedResponse = response;
266
286
  try {
@@ -283,6 +303,19 @@ function withUnmatchedRouteCacheControl(response) {
283
303
  unmatchedRouteResponses.add(markedResponse);
284
304
  return markedResponse;
285
305
  }
306
+ const serverActionResponses = /* @__PURE__ */ new WeakSet();
307
+ function markServerActionResponse(response) {
308
+ serverActionResponses.add(response);
309
+ return response;
310
+ }
311
+ /**
312
+ * A fetch action's redirect that streams its target's render keeps the
313
+ * target's policy, as in Next.js. Every other action response is never cached.
314
+ */
315
+ function withServerActionCacheControl(response) {
316
+ if (isStreamedActionRedirectResponse(response)) return response;
317
+ return withNeverCacheControl(response, SERVER_ACTION_CACHE_CONTROL);
318
+ }
286
319
  async function handleAppRscRequest(options, request, preMiddlewareRequestContext, middlewareContext, isDataRequest, isMiddlewareDataRequest, pagesDataRequest, dispatchInternalRequest, allowInternalRscDocumentFallback, dispatchResponseStage, responseStageProbeMode = null, setInterceptionResponseUncacheable = () => {}) {
287
320
  const handlerStart = process.env.NODE_ENV !== "production" ? performance.now() : 0;
288
321
  if (process.env.NODE_ENV !== "production") {
@@ -339,7 +372,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
339
372
  const provesConcreteInterceptionSource = (sourceMatch, sourceContext = interceptionContextHeader) => {
340
373
  if (sourceMatch === null) return false;
341
374
  if (sourceMatch.interceptionSourceIsConcrete !== void 0) return sourceMatch.interceptionSourceIsConcrete;
342
- return sourceContext !== null && (options.matchRequestRoute ?? options.matchRoute)(sourceContext)?.route === sourceMatch.route;
375
+ return sourceContext !== null && (options.matchRequestRoute ?? options.matchRoute)(sourceContext)?.route === (sourceMatch.authorizationRoute ?? sourceMatch.route);
343
376
  };
344
377
  if (provesConcreteInterceptionSource(hadBasePath && hasRawInterceptionContext && interceptionContextHeader !== null ? options.matchInterceptRoute?.(requestPathname, interceptionContextHeader, interceptionIdHeader) ?? null : null)) setInterceptionResponseUncacheable(false);
345
378
  if (pathname === "/__vinext/prerender/static-params" || pathname === "/__vinext/prerender/pages-static-paths" || pathname === "/__vinext/prerender/metadata-routes") {
@@ -410,6 +443,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
410
443
  isDataRequest: isMiddlewareDataRequest,
411
444
  middlewareRequest: isolatedMiddlewareRequest,
412
445
  request: userlandRequest,
446
+ restoreLocaleRootTrailingSlash,
413
447
  validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
414
448
  });
415
449
  if (!dispatchResponseStage && middlewareResult.pathnameEligible) markRouteCacheabilityDynamic(middlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
@@ -467,19 +501,28 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
467
501
  const responseStagePolicy = await loadResponseStagePolicy();
468
502
  const cache = responseStageProbeMode || isOnDemandRevalidate || (props.kind === "app-page" || props.kind === "app-route-handler") && (props.bypassInterceptionContextCache || props.forceDynamic === true && responseStagePolicy === null) ? "bypass" : canUseSharedWorkerResponseStage ? "shared" : "bypass";
469
503
  let dispatchRequest = props.kind === "app-page" ? prepareSharedAppPageDispatch(stageRequest, cache) : stageRequest;
504
+ let dispatchProps = props;
470
505
  let canonicalRsc = null;
471
506
  if (cache === "shared" && props.kind === "app-page" && props.isRscRequest && (props.matchKind === "request" || props.matchKind === "resolved") && props.interceptionContext === null && props.interceptionId === null && props.mountedSlotsHeader === null) {
472
507
  const headers = new Headers(dispatchRequest.headers);
473
- if (props.renderMode === "navigation" ? canonicalizePrewarmableRscRequestHeaders(headers) : props.renderMode === "prefetch-loading-shell" && props.canUseCanonicalLoadingShell ? canonicalizeLoadingShellRscRequestHeaders(headers) : false) {
508
+ if (props.renderMode === "navigation" ? canonicalizePrewarmableRscRequestHeaders(headers) : props.renderMode === "prefetch-loading-shell" && props.canUseCanonicalLoadingShell ? canonicalizeLoadingShellRscRequestHeaders(headers) : props.renderMode === "prefetch-dynamic-shell" ? canonicalizeDynamicShellRscRequestHeaders(headers) : false) {
474
509
  canonicalRsc = {
475
510
  headers,
476
- navigation: props.renderMode === "navigation"
511
+ navigation: props.renderMode !== "prefetch-loading-shell"
477
512
  };
478
513
  dispatchRequest = cloneRequestWithHeaders(dispatchRequest, headers);
514
+ if (props.renderMode === "prefetch-dynamic-shell") {
515
+ const queryFree = withoutAppPageDispatchQuery(dispatchRequest.url, {
516
+ ...props,
517
+ renderMode: "navigation"
518
+ });
519
+ dispatchRequest = cloneRequestWithUrl(dispatchRequest, queryFree.url);
520
+ dispatchProps = queryFree.props;
521
+ }
479
522
  }
480
523
  }
481
524
  let stageProps = {
482
- ...props,
525
+ ...dispatchProps,
483
526
  cacheability: {
484
527
  ...props.cacheability,
485
528
  policyHeaders: responseStagePolicy
@@ -510,16 +553,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
510
553
  statusText: response.statusText
511
554
  });
512
555
  }
513
- if (props.kind !== "app-page" || !props.isRscRequest) return response;
514
- const headers = new Headers(response.headers);
515
- if (Object.keys(props.params).length > 0) headers.set(VINEXT_PARAMS_HEADER, encodeURIComponent(JSON.stringify(props.params)));
516
- else headers.delete(VINEXT_PARAMS_HEADER);
517
- headers.set(VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, encodeURIComponent(props.resolvedUrl));
518
- return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
519
- headers,
520
- status: response.status,
521
- statusText: response.statusText
522
- }));
556
+ return response;
523
557
  } : void 0;
524
558
  const responseStageRequest = (stageRequest = request) => {
525
559
  const activeHeaders = getHeadersContext()?.headers;
@@ -556,7 +590,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
556
590
  }
557
591
  return options.handleMetadataRouteRequest?.(cleanPathname, metadataRoutePathname) ?? null;
558
592
  };
559
- const applyConfigHeadersToResponseStage = async (response, preserveExistingPolicy = false) => {
593
+ const applyConfigHeadersToResponseStage = async (response, preserveExistingPolicy = false, routeHandlerRuntime) => {
560
594
  const headers = new Headers(response.headers);
561
595
  copyLinkHeaderProvenance(response.headers, headers);
562
596
  await applyAppRscConfigHeaders(headers, request, {
@@ -567,7 +601,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
567
601
  middlewareHeaders: middlewareContext.headers,
568
602
  overwriteExisting: preserveExistingPolicy ? /* @__PURE__ */ new Set() : isCdnResponsePolicyHeader,
569
603
  recordCacheability: dispatchResponseStage === void 0,
570
- requestContext: preMiddlewareRequestContext
604
+ requestContext: preMiddlewareRequestContext,
605
+ routeHandlerRuntime
571
606
  });
572
607
  return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
573
608
  headers,
@@ -593,10 +628,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
593
628
  })();
594
629
  let outerResponsePolicyPromise;
595
630
  const loadOuterResponsePolicy = () => outerResponsePolicyPromise ??= Promise.all([loadPreHandlerResponseHeaders(), loadResponseStagePolicy()]).then(([headers, responseStagePolicy]) => captureCdnResponsePolicyOverrides(headers, new Headers(responseStagePolicy ?? [])));
596
- const composeResponseStageResponse = async (response) => {
631
+ const composeResponseStageResponse = async (response, routeHandlerRuntime) => {
597
632
  const transportedLink = consumeResponseStageLinkProvenance(response);
598
633
  response = transportedLink.response;
599
- response = await applyConfigHeadersToResponseStage(response, Boolean(dispatchResponseStage || options.renderResponseStageLocally));
634
+ response = await applyConfigHeadersToResponseStage(response, Boolean(dispatchResponseStage || options.renderResponseStageLocally), routeHandlerRuntime);
600
635
  response = applyMiddlewareContextToResponse(response, middlewareContext, transportedLink.appendToPostConfigLink);
601
636
  reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, await loadOuterResponsePolicy());
602
637
  return markAppRscResponseConfigHeadersApplied(response);
@@ -629,10 +664,13 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
629
664
  const isPostRequest = request.method.toUpperCase() === "POST";
630
665
  const contentType = request.headers.get("content-type") || "";
631
666
  const isProgressiveActionRequest = isPostRequest && !actionId && contentType.startsWith("multipart/form-data");
632
- const serveImageEndpointIfMatched = () => {
633
- if (!filesystemRouteEligible || !resolvedPathnameHasBasePath || !isImageOptimizationPath(cleanPathname)) return null;
667
+ const serveImageEndpointIfMatched = async () => {
668
+ if (!filesystemRouteEligible || !resolvedPathnameHasBasePath || !isImageOptimizationPath(cleanPathnameIsRequestPathname ? requestPathname : cleanPathname)) return null;
634
669
  const imageUrl = new URL(resolvedUrl, url);
635
- const imageRedirect = resolveDevImageRedirect(imageUrl, [...options.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...options.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], options.imageConfig?.qualities, { isDev: options.isDev });
670
+ const imageRedirect = resolveDevImageRedirect(imageUrl, [...options.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...options.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], options.imageConfig?.qualities, {
671
+ isDev: options.isDev,
672
+ localPatterns: options.imageConfig?.localPatterns
673
+ });
636
674
  const middlewareHeaders = new Headers();
637
675
  mergeMiddlewareResponseHeaders(middlewareHeaders, middlewareContext.headers);
638
676
  if (!imageRedirect) return new Response("Invalid image optimization parameters", {
@@ -641,12 +679,12 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
641
679
  });
642
680
  const overrideHeaders = middlewareContext.requestHeaders ?? middlewareContext.headers;
643
681
  return markImageOptimizationSignal(Response.redirect(new URL(imageRedirect, url.origin).href, 302), {
644
- middlewareHeaders,
682
+ middlewareHeaders: new Headers(await loadPreHandlerResponseHeaders()),
645
683
  requestHeaders: overrideHeaders ? buildRequestHeadersFromMiddlewareResponse(request.headers, overrideHeaders) : null,
646
684
  search: imageUrl.search
647
685
  });
648
686
  };
649
- const imageEndpointResponse = serveImageEndpointIfMatched();
687
+ const imageEndpointResponse = await serveImageEndpointIfMatched();
650
688
  if (imageEndpointResponse) return imageEndpointResponse;
651
689
  const metadataRouteResponse = await renderMetadataRouteIfMatched();
652
690
  if (metadataRouteResponse) return composeResponseStageResponse(metadataRouteResponse);
@@ -689,7 +727,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
689
727
  bypassInterceptionContextCache = true;
690
728
  setInterceptionResponseUncacheable(true);
691
729
  };
692
- if (interceptionSourceMatch !== null && interceptionContextHeader !== null && interceptionSourcePathname !== null && !(interceptionSourceMatch.route === directPreActionMatch?.route && haveSamePageParams(interceptionSourceMatch.params, directPreActionMatch.params))) {
730
+ if (interceptionSourceMatch !== null && interceptionContextHeader !== null && interceptionSourcePathname !== null && !isSameInterceptionSource(interceptionSourceMatch, directPreActionMatch)) {
693
731
  const sourceRequestPathname = options.skipTrailingSlashRedirect ? interceptionContextHeader : normalizeTrailingSlashPathname(interceptionContextHeader, options.trailingSlash) ?? interceptionContextHeader;
694
732
  const decodedSourceRequestPathname = options.skipTrailingSlashRedirect ? interceptionSourcePathname : normalizeTrailingSlashPathname(interceptionSourcePathname, options.trailingSlash) ?? interceptionSourcePathname;
695
733
  const adoptRewrittenInterceptionSource = (rewrittenPathname) => {
@@ -699,7 +737,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
699
737
  interceptionSourceContext = rewrittenPathname;
700
738
  }
701
739
  const rewrittenSourceMatch = options.matchRoute(rewrittenPathname);
702
- return interceptionSourceMatch !== null && rewrittenSourceMatch?.route === interceptionSourceMatch.route && haveSamePageParams(rewrittenSourceMatch.params, interceptionSourceMatch.params);
740
+ return interceptionSourceMatch !== null && isSameInterceptionSource(interceptionSourceMatch, rewrittenSourceMatch);
703
741
  };
704
742
  if (configMatchers?.matchRedirect(matchPathname(sourceRequestPathname), options.configRedirects, preMiddlewareRequestContext, currentBasePathState(), dispatchResponseStage ? void 0 : markConditionalRedirectCacheability)) {
705
743
  options.clearRequestContext();
@@ -709,7 +747,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
709
747
  if (runMiddleware) {
710
748
  const sourceUrl = new URL(userlandRequest.url);
711
749
  sourceUrl.search = new URL(resolvedUrl, url).search;
712
- const sourceUrlPathname = resolvedPathnameHasBasePath && options.basePath ? sourceRequestPathname === "/" ? options.basePath : options.basePath + sourceRequestPathname : sourceRequestPathname;
750
+ const sourceUrlPathname = resolvedPathnameHasBasePath ? restoreBasePath(sourceRequestPathname, options.basePath) : sourceRequestPathname;
713
751
  sourceUrl.pathname = sourceUrlPathname;
714
752
  if (sourceUrl.pathname !== sourceUrlPathname) {
715
753
  options.clearRequestContext();
@@ -744,6 +782,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
744
782
  hadBasePath: resolvedPathnameHasBasePath,
745
783
  isDataRequest: isMiddlewareDataRequest,
746
784
  request: sourceMiddlewareRequest,
785
+ restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(normalizePathTrailingSlash(sourceUrlPathname, options.trailingSlash ?? false), options),
747
786
  validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
748
787
  }));
749
788
  } finally {
@@ -752,6 +791,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
752
791
  }
753
792
  if (!dispatchResponseStage && sourceMiddlewareResult.pathnameEligible) markRouteCacheabilityDynamic(sourceMiddlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
754
793
  if (sourceMiddlewareResult.kind === "response") {
794
+ if (request.body && !request.body.locked) request.body.cancel().catch(() => {});
755
795
  options.clearRequestContext();
756
796
  return sourceMiddlewareResult.response;
757
797
  }
@@ -798,7 +838,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
798
838
  }
799
839
  return !didRewriteSource || adoptRewrittenInterceptionSource(sourceRulesPathname);
800
840
  };
801
- if (!rewriteSource(options.configRewrites.beforeFiles, false) || interceptionSourceMatch.route.isDynamic && !rewriteSource(options.configRewrites.afterFiles, true)) {
841
+ if (!rewriteSource(options.configRewrites.beforeFiles, false) || (interceptionSourceMatch.authorizationRoute ?? interceptionSourceMatch.route).isDynamic && !rewriteSource(options.configRewrites.afterFiles, true)) {
802
842
  options.clearRequestContext();
803
843
  return notFoundResponse();
804
844
  }
@@ -844,7 +884,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
844
884
  const handleServerAction = async (routeMatch, routePathname) => {
845
885
  if (!filesystemRouteEligible || !isPostRequest || !actionId) return null;
846
886
  if (routeMatch && isAppRouteHandlerRoute(routeMatch.route)) return null;
847
- if (!options.handleServerActionRequest) return createMissingServerActionResponse(options, actionId);
887
+ if (!options.handleServerActionRequest) return markServerActionResponse(createMissingServerActionResponse(options, actionId));
848
888
  const sourceConfigHeaders = new Headers();
849
889
  await applyAppRscConfigHeaders(sourceConfigHeaders, request, {
850
890
  basePath: options.basePath,
@@ -855,7 +895,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
855
895
  recordCacheability: dispatchResponseStage === void 0,
856
896
  requestContext: preMiddlewareRequestContext
857
897
  });
858
- return options.handleServerActionRequest({
898
+ const serverActionResponse = await options.handleServerActionRequest({
859
899
  actionId,
860
900
  cleanPathname,
861
901
  contentType,
@@ -871,13 +911,14 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
871
911
  sourceConfigHeaders,
872
912
  searchParams: getResolvedSearchParams()
873
913
  });
914
+ return serverActionResponse && markServerActionResponse(serverActionResponse);
874
915
  };
875
916
  let progressiveActionHandled = false;
876
917
  let progressiveActionFormState = null;
877
918
  const handleProgressiveAction = async (routeMatch, unrenderedRouteMatch) => {
878
919
  if (!filesystemRouteEligible || !isProgressiveActionRequest) return null;
879
920
  if (routeMatch && isAppRouteHandlerRoute(routeMatch.route)) return null;
880
- if (!options.handleProgressiveActionRequest) return unrenderedRouteMatch?.route.__loadPage && !unrenderedRouteMatch.route.__loadRouteHandler ? createMissingServerActionResponse(options, null) : null;
921
+ if (!options.handleProgressiveActionRequest) return unrenderedRouteMatch?.route.__loadPage && !unrenderedRouteMatch.route.__loadRouteHandler ? markServerActionResponse(createMissingServerActionResponse(options, null)) : null;
881
922
  const progressiveActionResult = await options.handleProgressiveActionRequest({
882
923
  actionId,
883
924
  cleanPathname,
@@ -886,7 +927,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
886
927
  request,
887
928
  routeMatch
888
929
  });
889
- if (progressiveActionResult instanceof Response) return progressiveActionResult;
930
+ if (progressiveActionResult instanceof Response) return markServerActionResponse(markAppRscApplicationResponse(progressiveActionResult));
890
931
  if (progressiveActionResult?.kind !== "form-state") return null;
891
932
  if ("actionError" in progressiveActionResult && middlewareContext.status === null && progressiveActionHttpFallbackStatus(progressiveActionResult.actionError) === null) middlewareContext.status = 500;
892
933
  return progressiveActionResult;
@@ -971,23 +1012,24 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
971
1012
  pathname: pagesRouteUrl,
972
1013
  pagesDataRequest,
973
1014
  request,
1015
+ requestBasePath: hadBasePath ? options.basePath : "",
974
1016
  url
975
1017
  })) ?? null : null;
976
1018
  if (response) preserveRouteCacheabilityResponsePolicy();
977
1019
  if (!response) return null;
978
1020
  if (sharedOuterPolicyNeedsReconciliation) reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, await loadOuterResponsePolicy());
1021
+ const markPagesResponse = (pagesResponse) => dispatchPagesResponseStage ? markAppRscResponseConfigHeadersApplied(pagesResponse) : isLocaleRedirect(response) ? pagesResponse : markAppRscApplicationResponse(pagesResponse);
979
1022
  const isRewritten = resolvedUrl !== originalResolvedUrl;
980
1023
  const isPrerender = typeof process !== "undefined" && process.env?.VINEXT_PRERENDER === "1";
981
- if ((!pagesDataRequest || !isRewritten) && !isPrerender) return dispatchPagesResponseStage ? markAppRscResponseConfigHeadersApplied(response) : response;
1024
+ if ((!pagesDataRequest || !isRewritten) && !isPrerender) return markPagesResponse(response);
982
1025
  const headers = new Headers(response.headers);
983
1026
  if (pagesDataRequest && isRewritten) headers.set("x-nextjs-rewrite", resolvedUrl);
984
1027
  if (isPrerender) headers.set(VINEXT_PRERENDER_REWRITTEN_HEADER, isRewritten ? "1" : "0");
985
- const markedResponse = new Response(response.body, {
1028
+ return markPagesResponse(new Response(response.body, {
986
1029
  headers,
987
1030
  status: response.status,
988
1031
  statusText: response.statusText
989
- });
990
- return dispatchPagesResponseStage ? markAppRscResponseConfigHeadersApplied(markedResponse) : markedResponse;
1032
+ }));
991
1033
  };
992
1034
  const staticPagesFallbackResponse = await renderPagesForMatchKind("static");
993
1035
  if (staticPagesFallbackResponse) {
@@ -1018,7 +1060,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1018
1060
  filesystemRouteEligible = resolvedPathnameHasBasePath;
1019
1061
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
1020
1062
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1021
- const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1063
+ const rewrittenImageEndpointResponse = await serveImageEndpointIfMatched();
1022
1064
  if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
1023
1065
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
1024
1066
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
@@ -1066,7 +1108,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1066
1108
  filesystemRouteEligible = resolvedPathnameHasBasePath;
1067
1109
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
1068
1110
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1069
- const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1111
+ const rewrittenImageEndpointResponse = await serveImageEndpointIfMatched();
1070
1112
  if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
1071
1113
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
1072
1114
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
@@ -1088,7 +1130,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1088
1130
  if (interceptionCacheProofInvalidated && interceptionSourceContext !== null) {
1089
1131
  const finalInterceptionTargetPathname = cleanPathnameIsRequestPathname ? requestPathname : cleanPathname;
1090
1132
  const finalInterceptionSourceMatch = filesystemRouteEligible && match !== null ? options.matchInterceptRoute?.(finalInterceptionTargetPathname, interceptionSourceContext, interceptionIdHeader) ?? null : null;
1091
- const hasVerifiedFinalInterceptionSource = hasVerifiedInterceptionSource && interceptionSourceMatch !== null && provesConcreteInterceptionSource(finalInterceptionSourceMatch) && finalInterceptionSourceMatch?.route === interceptionSourceMatch.route && haveSamePageParams(finalInterceptionSourceMatch.params, interceptionSourceMatch.params);
1133
+ const hasVerifiedFinalInterceptionSource = hasVerifiedInterceptionSource && interceptionSourceMatch !== null && provesConcreteInterceptionSource(finalInterceptionSourceMatch) && finalInterceptionSourceMatch !== null && finalInterceptionSourceMatch.route === interceptionSourceMatch.route && haveSamePageParams(finalInterceptionSourceMatch.params, interceptionSourceMatch.params) && isSameInterceptionSource(finalInterceptionSourceMatch, {
1134
+ params: interceptionSourceMatch.authorizationParams ?? interceptionSourceMatch.params,
1135
+ route: interceptionSourceMatch.authorizationRoute ?? interceptionSourceMatch.route
1136
+ });
1092
1137
  if (interceptionIdHeader !== null && !hasVerifiedFinalInterceptionSource) {
1093
1138
  options.clearRequestContext();
1094
1139
  setInterceptionResponseUncacheable(true);
@@ -1168,7 +1213,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1168
1213
  route: null,
1169
1214
  scriptNonce
1170
1215
  }));
1171
- if (renderedNotFoundResponse) return withUnmatchedRouteCacheControl(renderedNotFoundResponse);
1216
+ if (renderedNotFoundResponse) return markAppRscApplicationResponse(withUnmatchedRouteCacheControl(renderedNotFoundResponse));
1172
1217
  options.clearRequestContext();
1173
1218
  const headers = new Headers();
1174
1219
  mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
@@ -1219,9 +1264,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1219
1264
  const rootParams = pickRootParams(renderParams, route.rootParamNames);
1220
1265
  setRootParams(rootParams);
1221
1266
  if (route.routeHandler) {
1222
- const routeHandlerRequest = isEdgeRouteHandler(route.routeHandler) ? userlandRequest : request;
1267
+ const routeHandlerRuntime = isEdgeRouteHandler(route.routeHandler) ? "edge" : "node";
1268
+ const routeHandlerRequest = routeHandlerRuntime === "edge" ? userlandRequest : request;
1223
1269
  const routeHandlerUrl = new URL(routeHandlerRequest.url);
1224
- const internalRscValues = isEdgeRouteHandler(route.routeHandler) ? [] : routeHandlerUrl.searchParams.getAll(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
1270
+ const internalRscValues = routeHandlerRuntime === "edge" ? [] : routeHandlerUrl.searchParams.getAll(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
1225
1271
  routeHandlerUrl.search = resolvedSearchParams.toString();
1226
1272
  for (const internalRscValue of internalRscValues) routeHandlerUrl.searchParams.append(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, internalRscValue);
1227
1273
  if (matchedResponseStage) return composeResponseStageResponse(await matchedResponseStage(responseStageRequest(), {
@@ -1249,10 +1295,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1249
1295
  routePattern: route.pattern,
1250
1296
  routePathname: responseStageRoutePathname,
1251
1297
  scriptNonce: scriptNonce ?? null
1252
- }));
1298
+ }), routeHandlerRuntime);
1253
1299
  const { setCurrentFetchSoftTags } = await import("../shims/fetch-cache.js");
1254
1300
  setCurrentFetchSoftTags(buildPageCacheTags(cleanPathname, [], [...route.routeSegments], "route"));
1255
- return options.dispatchMatchedRouteHandler({
1301
+ const routeHandlerResponse = await options.dispatchMatchedRouteHandler({
1256
1302
  bypassInterceptionContextCache,
1257
1303
  cachePathname,
1258
1304
  cleanPathname,
@@ -1262,6 +1308,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1262
1308
  route,
1263
1309
  searchParams: resolvedSearchParams
1264
1310
  });
1311
+ return markAppRscRouteHandlerResponse(routeHandlerResponse, routeHandlerRuntime);
1265
1312
  }
1266
1313
  const failedProgressiveActionResult = progressiveActionFormState && "actionError" in progressiveActionFormState ? progressiveActionFormState : null;
1267
1314
  const actionHttpFallbackStatus = failedProgressiveActionResult ? progressiveActionHttpFallbackStatus(failedProgressiveActionResult.actionError) : null;
@@ -1291,7 +1338,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1291
1338
  routePattern: route.pattern,
1292
1339
  routePathname: responseStageRoutePathname,
1293
1340
  scriptNonce: scriptNonce ?? null
1294
- }).then(composeResponseStageResponse) : await options.dispatchMatchedPage({
1341
+ }).then((response) => transportedResponseStage && isRscRequest ? withRoutedRscHeaders(response, resolveAppPageNavigationParams(route, params, cleanPathname), resolvedUrl, interceptionSourceContext !== null) : response).then(composeResponseStageResponse) : await options.dispatchMatchedPage({
1295
1342
  bypassInterceptionContextCache,
1296
1343
  cachePathname,
1297
1344
  cleanPathname,
@@ -1324,8 +1371,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1324
1371
  searchParams: resolvedSearchParams,
1325
1372
  renderMode
1326
1373
  }), isRscRequest && request.headers.get("Next-Router-Prefetch") === "1" && request.headers.has("Next-Router-Segment-Prefetch"));
1327
- if (progressiveActionFormState) return applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState);
1328
- return pageResponse;
1374
+ if (progressiveActionFormState) return markServerActionResponse(markAppRscApplicationResponse(applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState)));
1375
+ return markAppRscApplicationResponse(pageResponse);
1329
1376
  }
1330
1377
  function progressiveActionHttpFallbackStatus(actionError) {
1331
1378
  const actionErrorDigest = actionError && typeof actionError === "object" && "digest" in actionError ? String(actionError.digest) : null;
@@ -1393,7 +1440,7 @@ function createAppRscRequestHandler(options) {
1393
1440
  let appRequest = rawRequest;
1394
1441
  if (pagesDataNormalization?.isDataReq) {
1395
1442
  const appRequestUrl = new URL(pagesDataNormalization.request.url);
1396
- appRequestUrl.pathname = addBasePathToPathname(appRequestUrl.pathname, options.basePath);
1443
+ appRequestUrl.pathname = restoreBasePath(appRequestUrl.pathname, options.basePath);
1397
1444
  appRequest = cloneRequestWithUrl(pagesDataCandidate, appRequestUrl.toString());
1398
1445
  }
1399
1446
  const request = cloneRequestWithHeaders(appRequest, filteredHeaders);
@@ -1436,6 +1483,7 @@ function createAppRscRequestHandler(options) {
1436
1483
  recordCacheability: dispatchResponseStage === void 0,
1437
1484
  requestContext: preMiddlewareRequestContext
1438
1485
  });
1486
+ if (serverActionResponses.has(response)) return withServerActionCacheControl(response);
1439
1487
  return interceptionResponseUncacheable || unmatchedRouteResponses.has(response) ? withNeverCacheControl(response) : response;
1440
1488
  }, {
1441
1489
  cacheComponents: options.createPprFallbackShells !== void 0,
@@ -1448,7 +1496,8 @@ function createAppRscRequestHandler(options) {
1448
1496
  await closeAfterResponse(requestContext);
1449
1497
  throw error;
1450
1498
  }
1451
- return closeAfterResponseWithBody(response, requestContext);
1499
+ const closedResponse = closeAfterResponseWithBody(response, requestContext);
1500
+ return isStreamedActionRedirectResponse(response) ? markStreamedActionRedirectResponse(closedResponse) : closedResponse;
1452
1501
  };
1453
1502
  const appRscHandler = async function appRscHandler(rawRequest, ctx, allowInternalRscDocumentFallback = false, dispatchResponseStage, responseStageProbeMode = null, transportedPrerenderState, detachedTrace = false) {
1454
1503
  options.registerCacheAdapters();
@@ -1,5 +1,6 @@
1
1
  import { NextHeader, NextI18nConfig } from "../config/next-config.js";
2
2
  import { RequestContext } from "../config/request-context.js";
3
+ import { RouteHandlerRuntime } from "./config-headers.js";
3
4
  //#region src/server/app-rsc-response-finalizer.d.ts
4
5
  type FinalizeAppRscResponseOptions = {
5
6
  basePath: string;
@@ -29,9 +30,23 @@ type FinalizeAppRscResponseOptions = {
29
30
  middlewareHeaders?: Headers | null;
30
31
  /** Whether config matching should update the active cacheability classification. */
31
32
  recordCacheability?: boolean;
33
+ /** The runtime of the Route Handler that produced the response, if one did. */
34
+ routeHandlerRuntime?: RouteHandlerRuntime;
32
35
  };
33
36
  /** Mark a response whose final target pipeline has already applied config headers. */
34
37
  export declare function markAppRscResponseConfigHeadersApplied(response: Response): Response;
38
+ /** Mark a Server Action redirect that streams its target's render, and so keeps its policy. */
39
+ export declare function markStreamedActionRedirectResponse(response: Response): Response;
40
+ export declare function isStreamedActionRedirectResponse(response: Response): boolean;
41
+ /**
42
+ * Mark a response that a page, Route Handler, Server Action or Pages route
43
+ * produced. Next.js stages next.config headers before application code runs,
44
+ * so the redirects these return carry them. Redirects that routing answers
45
+ * itself (next.config redirects, trailing slash, middleware) go out without.
46
+ */
47
+ export declare function markAppRscApplicationResponse(response: Response): Response;
48
+ /** Mark a response a Route Handler produced, so its own headers meet config as in Next.js. */
49
+ export declare function markAppRscRouteHandlerResponse(response: Response, runtime: RouteHandlerRuntime): Response;
35
50
  /** Apply only the matching next.config headers for an App Router request. */
36
51
  export declare function applyAppRscConfigHeaders(headers: Headers, request: Request, options: FinalizeAppRscResponseOptions): Promise<void>;
37
52
  /**
@@ -42,9 +57,9 @@ export declare function applyAppRscConfigHeaders(headers: Headers, request: Requ
42
57
  * handling, so that every response path (page, route handler, server action,
43
58
  * metadata, not-found) gets headers applied consistently.
44
59
  *
45
- * Skips 3xx redirect responses. Response.redirect() creates immutable
46
- * headers that throw on mutation, and Next.js does not apply config headers
47
- * to redirects regardless.
60
+ * Skips 3xx responses that routing answered itself, as Next.js does not
61
+ * apply config headers to those. A 3xx that application code returned is
62
+ * finalized like any other response.
48
63
  */
49
64
  export declare function finalizeAppRscResponse(response: Response, request: Request, options: FinalizeAppRscResponseOptions): Promise<Response>;
50
65
  //#endregion