vinext 1.1.0 → 1.2.0

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 (234) hide show
  1. package/README.md +21 -9
  2. package/dist/build/client-build-config.d.ts +10 -0
  3. package/dist/build/client-build-config.js +18 -2
  4. package/dist/build/pages-client-assets-module.d.ts +8 -0
  5. package/dist/build/pages-client-assets-module.js +21 -1
  6. package/dist/build/prerender-paths.js +5 -3
  7. package/dist/build/run-prerender.js +1 -1
  8. package/dist/build/ssr-manifest.d.ts +2 -0
  9. package/dist/build/ssr-manifest.js +6 -2
  10. package/dist/check.js +7 -6
  11. package/dist/cli.js +2 -1
  12. package/dist/client/client-redirect-matcher.d.ts +14 -0
  13. package/dist/client/client-redirect-matcher.js +37 -0
  14. package/dist/client/client-redirects.d.ts +27 -0
  15. package/dist/client/client-redirects.js +28 -0
  16. package/dist/client/client-rewrites.d.ts +2 -1
  17. package/dist/client/client-rewrites.js +1 -1
  18. package/dist/config/config-matchers.d.ts +26 -11
  19. package/dist/config/config-matchers.js +78 -81
  20. package/dist/config/destination-params.d.ts +47 -0
  21. package/dist/config/destination-params.js +116 -0
  22. package/dist/config/next-config.d.ts +7 -0
  23. package/dist/config/next-config.js +3 -0
  24. package/dist/entries/app-rsc-entry.d.ts +4 -0
  25. package/dist/entries/app-rsc-entry.js +20 -6
  26. package/dist/entries/pages-client-entry.js +3 -1
  27. package/dist/entries/pages-server-entry.js +13 -37
  28. package/dist/index.d.ts +3 -1
  29. package/dist/index.js +134 -43
  30. package/dist/init-cloudflare.d.ts +9 -0
  31. package/dist/init-cloudflare.js +107 -31
  32. package/dist/init-platform.d.ts +4 -0
  33. package/dist/init-platform.js +27 -2
  34. package/dist/init.d.ts +1 -0
  35. package/dist/init.js +67 -3
  36. package/dist/plugins/ast-scope.d.ts +7 -0
  37. package/dist/plugins/ast-scope.js +59 -3
  38. package/dist/plugins/cache-flight-codec.d.ts +1 -1
  39. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  40. package/dist/plugins/dynamic-preload-metadata.js +9 -8
  41. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  42. package/dist/plugins/ignore-dynamic-requests.js +3 -4
  43. package/dist/plugins/middleware-server-only.d.ts +5 -4
  44. package/dist/plugins/middleware-server-only.js +8 -5
  45. package/dist/plugins/pages-node-externals.js +1 -1
  46. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  47. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  48. package/dist/plugins/strip-server-exports.js +262 -98
  49. package/dist/plugins/transform-result.d.ts +9 -5
  50. package/dist/plugins/transitive-externals.js +1 -1
  51. package/dist/plugins/typeof-window.d.ts +2 -2
  52. package/dist/plugins/use-cache-callable.js +8 -2
  53. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  54. package/dist/plugins/worker-server-only-imports.js +31 -0
  55. package/dist/plugins/worker-use-server.d.ts +25 -0
  56. package/dist/plugins/worker-use-server.js +129 -0
  57. package/dist/server/api-handler.d.ts +1 -0
  58. package/dist/server/api-handler.js +2 -1
  59. package/dist/server/app-browser-action-result.d.ts +1 -1
  60. package/dist/server/app-browser-action-result.js +9 -2
  61. package/dist/server/app-browser-navigation-controller.js +1 -1
  62. package/dist/server/app-browser-server-action-client.js +1 -1
  63. package/dist/server/app-middleware.d.ts +11 -0
  64. package/dist/server/app-middleware.js +17 -2
  65. package/dist/server/app-page-cache.d.ts +1 -1
  66. package/dist/server/app-page-cache.js +1 -1
  67. package/dist/server/app-page-dispatch.d.ts +3 -1
  68. package/dist/server/app-page-dispatch.js +4 -3
  69. package/dist/server/app-page-ppr-runtime.js +1 -1
  70. package/dist/server/app-page-render-observation.js +1 -1
  71. package/dist/server/app-page-request.js +53 -15
  72. package/dist/server/app-page-route-wiring.js +2 -2
  73. package/dist/server/app-pages-bridge.d.ts +1 -1
  74. package/dist/server/app-pages-bridge.js +2 -3
  75. package/dist/server/app-prerender-endpoints.js +9 -6
  76. package/dist/server/app-request-stage-dispatch.js +6 -2
  77. package/dist/server/app-request-stage-independent-entry.js +25 -5
  78. package/dist/server/app-response-stage-entry.js +10 -2
  79. package/dist/server/app-route-handler-cache.d.ts +1 -0
  80. package/dist/server/app-route-handler-cache.js +1 -0
  81. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  82. package/dist/server/app-route-handler-dispatch.js +5 -2
  83. package/dist/server/app-route-handler-execution.d.ts +1 -0
  84. package/dist/server/app-route-handler-execution.js +1 -0
  85. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  86. package/dist/server/app-route-handler-runtime.js +45 -24
  87. package/dist/server/app-router-entry.js +24 -5
  88. package/dist/server/app-rsc-cache-busting.js +1 -1
  89. package/dist/server/app-rsc-errors.js +20 -16
  90. package/dist/server/app-rsc-handler.d.ts +7 -0
  91. package/dist/server/app-rsc-handler.js +85 -35
  92. package/dist/server/app-rsc-response-stage.js +4 -2
  93. package/dist/server/app-segment-config.d.ts +2 -1
  94. package/dist/server/app-server-action-execution.d.ts +2 -1
  95. package/dist/server/app-server-action-execution.js +61 -22
  96. package/dist/server/app-ssr-entry.js +2 -1
  97. package/dist/server/app-worker-stages.d.ts +5 -0
  98. package/dist/server/app-worker-stages.js +1 -1
  99. package/dist/server/cacheability-request.js +2 -2
  100. package/dist/server/client-build-files.d.ts +16 -0
  101. package/dist/server/client-build-files.js +36 -0
  102. package/dist/server/client-reuse-manifest.js +1 -1
  103. package/dist/server/dev-server.js +38 -27
  104. package/dist/server/dev-stack-sourcemap.js +18 -23
  105. package/dist/server/document-initial-head.d.ts +0 -11
  106. package/dist/server/document-initial-head.js +1 -1
  107. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  108. package/dist/server/forwarded-middleware-context.js +22 -0
  109. package/dist/server/headers.d.ts +4 -1
  110. package/dist/server/headers.js +4 -1
  111. package/dist/server/http-conditional.d.ts +11 -0
  112. package/dist/server/http-conditional.js +10 -1
  113. package/dist/server/http-error-responses.d.ts +1 -1
  114. package/dist/server/image-optimization.d.ts +38 -0
  115. package/dist/server/image-optimization.js +93 -4
  116. package/dist/server/isr-cache.d.ts +10 -0
  117. package/dist/server/isr-cache.js +41 -6
  118. package/dist/server/metadata-route-response.js +9 -8
  119. package/dist/server/middleware-matcher.d.ts +2 -0
  120. package/dist/server/middleware-matcher.js +23 -2
  121. package/dist/server/middleware-runtime.d.ts +13 -0
  122. package/dist/server/middleware-runtime.js +33 -20
  123. package/dist/server/middleware.d.ts +1 -1
  124. package/dist/server/middleware.js +3 -1
  125. package/dist/server/multi-stage.d.ts +11 -0
  126. package/dist/server/normalize-path.d.ts +0 -13
  127. package/dist/server/normalize-path.js +1 -34
  128. package/dist/server/pages-api-route.d.ts +3 -2
  129. package/dist/server/pages-api-route.js +4 -3
  130. package/dist/server/pages-cache-tag.d.ts +12 -0
  131. package/dist/server/pages-cache-tag.js +19 -0
  132. package/dist/server/pages-client-assets.d.ts +2 -0
  133. package/dist/server/pages-data-route.d.ts +10 -0
  134. package/dist/server/pages-data-route.js +19 -2
  135. package/dist/server/pages-document-asset-props.d.ts +5 -1
  136. package/dist/server/pages-document-asset-props.js +13 -5
  137. package/dist/server/pages-document-splice.d.ts +19 -0
  138. package/dist/server/pages-document-splice.js +55 -0
  139. package/dist/server/pages-i18n.d.ts +12 -1
  140. package/dist/server/pages-i18n.js +18 -4
  141. package/dist/server/pages-node-compat.d.ts +16 -5
  142. package/dist/server/pages-node-compat.js +20 -12
  143. package/dist/server/pages-page-data.d.ts +32 -24
  144. package/dist/server/pages-page-data.js +50 -120
  145. package/dist/server/pages-page-handler.d.ts +0 -6
  146. package/dist/server/pages-page-handler.js +188 -126
  147. package/dist/server/pages-page-response.d.ts +12 -6
  148. package/dist/server/pages-page-response.js +41 -34
  149. package/dist/server/pages-request-pipeline.d.ts +10 -2
  150. package/dist/server/pages-request-pipeline.js +37 -18
  151. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  152. package/dist/server/pages-request-stage-entry.js +71 -12
  153. package/dist/server/pages-response-stage-entry.js +4 -0
  154. package/dist/server/pages-revalidate.js +1 -1
  155. package/dist/server/pages-router-entry.js +4 -3
  156. package/dist/server/prerender-manifest.d.ts +3 -3
  157. package/dist/server/prerender-manifest.js +4 -3
  158. package/dist/server/prerender-work-unit-setup.js +4 -0
  159. package/dist/server/prod-server.d.ts +12 -0
  160. package/dist/server/prod-server.js +199 -69
  161. package/dist/server/proper-error.d.ts +4 -0
  162. package/dist/server/proper-error.js +31 -0
  163. package/dist/server/request-pipeline.d.ts +4 -1
  164. package/dist/server/request-pipeline.js +3 -2
  165. package/dist/server/revalidation-request.d.ts +1 -0
  166. package/dist/server/revalidation-request.js +1 -1
  167. package/dist/server/rsc-stream-hints.js +31 -2
  168. package/dist/server/seed-cache.d.ts +1 -0
  169. package/dist/server/seed-cache.js +5 -4
  170. package/dist/server/server-reference-loader.d.ts +4 -0
  171. package/dist/server/server-reference-loader.js +29 -0
  172. package/dist/server/socket-error-backstop.d.ts +9 -1
  173. package/dist/server/socket-error-backstop.js +46 -17
  174. package/dist/server/static-file-signal.d.ts +15 -4
  175. package/dist/server/static-file-signal.js +46 -12
  176. package/dist/server/worker-image-optimization.d.ts +34 -0
  177. package/dist/server/worker-image-optimization.js +86 -0
  178. package/dist/server/worker-stages.d.ts +1 -1
  179. package/dist/server/worker-stages.js +2 -2
  180. package/dist/server/worker-utils.d.ts +8 -3
  181. package/dist/server/worker-utils.js +12 -7
  182. package/dist/shims/app-router-scroll.js +4 -1
  183. package/dist/shims/app-router-tree-context.d.ts +5 -0
  184. package/dist/shims/app-router-tree-context.js +27 -0
  185. package/dist/shims/cache-callable-runtime.d.ts +4 -2
  186. package/dist/shims/cache-callable-runtime.js +21 -12
  187. package/dist/shims/cache-handler.js +1 -9
  188. package/dist/shims/cache-runtime.d.ts +6 -1
  189. package/dist/shims/cache-runtime.js +2 -1
  190. package/dist/shims/cache.d.ts +2 -2
  191. package/dist/shims/cache.js +40 -13
  192. package/dist/shims/cdn-cache.d.ts +8 -0
  193. package/dist/shims/cdn-cache.js +17 -1
  194. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  195. package/dist/shims/disable-smooth-scroll.js +36 -0
  196. package/dist/shims/document-placeholders.d.ts +19 -0
  197. package/dist/shims/document-placeholders.js +45 -0
  198. package/dist/shims/document.js +21 -5
  199. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  200. package/dist/shims/dynamic-preload-chunks.js +13 -9
  201. package/dist/shims/dynamic.d.ts +1 -1
  202. package/dist/shims/dynamic.js +60 -8
  203. package/dist/shims/fetch-cache-state.d.ts +66 -0
  204. package/dist/shims/fetch-cache-state.js +92 -0
  205. package/dist/shims/fetch-cache.d.ts +3 -67
  206. package/dist/shims/fetch-cache.js +160 -125
  207. package/dist/shims/head.d.ts +10 -6
  208. package/dist/shims/head.js +15 -13
  209. package/dist/shims/image.js +2 -1
  210. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  211. package/dist/shims/internal/work-store-scope.js +24 -0
  212. package/dist/shims/navigation.js +31 -5
  213. package/dist/shims/request-context.d.ts +2 -0
  214. package/dist/shims/request-state-types.d.ts +2 -1
  215. package/dist/shims/router.js +12 -20
  216. package/dist/shims/server.d.ts +16 -0
  217. package/dist/shims/server.js +24 -4
  218. package/dist/shims/unified-request-context.d.ts +1 -1
  219. package/dist/shims/url-utils.d.ts +2 -0
  220. package/dist/shims/url-utils.js +3 -1
  221. package/dist/utils/client-runtime-metadata.js +1 -1
  222. package/dist/utils/hash.d.ts +7 -0
  223. package/dist/utils/hash.js +11 -1
  224. package/dist/utils/package-name.d.ts +6 -0
  225. package/dist/utils/package-name.js +12 -1
  226. package/dist/utils/plugin-rsc-version.d.ts +4 -0
  227. package/dist/utils/plugin-rsc-version.js +15 -0
  228. package/dist/utils/prerender-output-paths.js +15 -4
  229. package/dist/utils/public-file-path.d.ts +10 -2
  230. package/dist/utils/public-file-path.js +13 -9
  231. package/dist/utils/public-routes.js +2 -2
  232. package/dist/utils/react-version.d.ts +3 -0
  233. package/dist/utils/react-version.js +1 -1
  234. package/package.json +7 -3
@@ -2,7 +2,7 @@ import { NextI18nConfig } from "../config/next-config.js";
2
2
  import { Route } from "../routing/pages-router.js";
3
3
  import { ExecutionContextLike } from "../shims/request-context.js";
4
4
  import { EdgeApiExecutionRuntime } from "./edge-api-runtime.js";
5
- import { PagesReqResRequest, PagesReqResResponse, PagesRequestQuery } from "./pages-node-compat.js";
5
+ import { PagesApiReqResResponse, PagesReqResRequest, PagesRequestQuery } from "./pages-node-compat.js";
6
6
  //#region src/server/pages-api-route.d.ts
7
7
  type PagesApiRouteConfig = {
8
8
  runtime?: string;
@@ -36,7 +36,7 @@ type PagesApiRouteConfig = {
36
36
  externalResolver?: boolean;
37
37
  };
38
38
  };
39
- type PagesNodeApiRouteHandler = (req: PagesReqResRequest, res: PagesReqResResponse) => unknown;
39
+ type PagesNodeApiRouteHandler = (req: PagesReqResRequest, res: PagesApiReqResResponse) => unknown;
40
40
  type PagesEdgeApiRouteHandler = (request: Request) => Response | Promise<Response>;
41
41
  type PagesApiRouteModule = {
42
42
  /**
@@ -80,6 +80,7 @@ type HandlePagesApiRouteOptions = {
80
80
  allowedRevalidateHeaderKeys?: readonly string[];
81
81
  i18n?: NextI18nConfig | null;
82
82
  trailingSlash?: boolean;
83
+ skipTrailingSlashRedirect?: boolean;
83
84
  };
84
85
  trustedRevalidateOrigin?: string;
85
86
  };
@@ -9,7 +9,7 @@ import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } f
9
9
  import { tracePagesApiHandler } from "./pages-execution-tracing.js";
10
10
  import { resolveBodyParserConfig } from "./pages-body-parser-config.js";
11
11
  import { PagesBodyParseError } from "./pages-media-type.js";
12
- import { createPagesReqRes, markVinextStreamedApiResponse, parsePagesApiBody } from "./pages-node-compat.js";
12
+ import { createPagesApiReqRes, markVinextStreamedApiResponse, parsePagesApiBody } from "./pages-node-compat.js";
13
13
  import { finalizeEdgeApiResponse, isEdgeApiRuntime } from "./edge-api-runtime.js";
14
14
  //#region src/server/pages-api-route.ts
15
15
  function resolveModuleRuntime(module) {
@@ -47,7 +47,8 @@ async function _handlePagesApiRoute(options) {
47
47
  const nextRequest = new NextRequest(createEdgeApiRequest(options.request, options.url, params), options.nextConfig ? { nextConfig: {
48
48
  basePath: options.nextConfig.basePath,
49
49
  i18n: options.nextConfig.i18n ?? void 0,
50
- trailingSlash: options.nextConfig.trailingSlash
50
+ trailingSlash: options.nextConfig.trailingSlash,
51
+ skipTrailingSlashRedirect: options.nextConfig.skipTrailingSlashRedirect
51
52
  } } : void 0);
52
53
  const response = await tracePagesApiHandler(route.pattern, () => handler(nextRequest));
53
54
  if (response instanceof Response) {
@@ -70,7 +71,7 @@ async function _handlePagesApiRoute(options) {
70
71
  const query = buildPagesApiQuery(options.url, params);
71
72
  const bodyParserConfig = resolveBodyParserConfig(route.module.config);
72
73
  const body = bodyParserConfig.enabled ? await parsePagesApiBody(options.request, bodyParserConfig.sizeLimit) : void 0;
73
- const { req, res, responsePromise } = createPagesReqRes({
74
+ const { req, res, responsePromise } = createPagesApiReqRes({
74
75
  allowedRevalidateHeaderKeys: options.nextConfig?.allowedRevalidateHeaderKeys,
75
76
  body,
76
77
  initialResponseHeaders: options.initialResponseHeaders,
@@ -0,0 +1,12 @@
1
+ //#region src/server/pages-cache-tag.d.ts
2
+ /**
3
+ * Build the edge path tag for a Pages ISR pathname.
4
+ *
5
+ * Every spelling of one pathname shares a single ISR entry, because
6
+ * `pagesIsrCacheKey()` decodes each segment first. The tag must use that same
7
+ * decoded identity. Otherwise `/users/%40alice` is stored at the edge under its
8
+ * own tag, and `res.revalidate("/users/@alice")` or
9
+ * `revalidatePath("/users/@alice")` never purges it.
10
+ */
11
+ export declare function pagesPathCacheTag(isrPathname: string): string;
12
+ //#endregion
@@ -0,0 +1,19 @@
1
+ import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
+ import { encodeCacheTag } from "../utils/encode-cache-tag.js";
3
+ //#region src/server/pages-cache-tag.ts
4
+ /**
5
+ * Build the edge path tag for a Pages ISR pathname.
6
+ *
7
+ * Every spelling of one pathname shares a single ISR entry, because
8
+ * `pagesIsrCacheKey()` decodes each segment first. The tag must use that same
9
+ * decoded identity. Otherwise `/users/%40alice` is stored at the edge under its
10
+ * own tag, and `res.revalidate("/users/@alice")` or
11
+ * `revalidatePath("/users/@alice")` never purges it.
12
+ */
13
+ function pagesPathCacheTag(isrPathname) {
14
+ const pathname = normalizePathnameForRouteMatch(isrPathname);
15
+ const stem = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
16
+ return encodeCacheTag(`_N_T_${stem || "/"}`);
17
+ }
18
+ //#endregion
19
+ export { pagesPathCacheTag };
@@ -14,6 +14,8 @@ export type PagesClientAssets = {
14
14
  dynamicPreloads?: Record<string, string[]>;
15
15
  /** next.config crossOrigin, defaulting to anonymous for Vite's CORS-fetched assets. */
16
16
  crossOrigin?: AssetCrossOrigin;
17
+ /** Client bundle files outside `_next/static`, as URL pathnames. */
18
+ clientBuildFiles?: string[];
17
19
  };
18
20
  export declare function setPagesClientAssets(assets: PagesClientAssets | undefined): void;
19
21
  export declare function getPagesClientAssets(): PagesClientAssets;
@@ -61,6 +61,16 @@ export declare function encodeUrlParserIgnoredCharacters(pathname: string): stri
61
61
  * `/_next/data/<buildId>/about` → null (missing .json suffix)
62
62
  */
63
63
  export declare function parseNextDataPathname(pathname: string, buildId: string): NextDataMatch | null;
64
+ /**
65
+ * The page pathname a `_next/data` URL addresses, whatever its buildId. Next.js
66
+ * compiles every middleware matcher with an optional `/_next/data/<buildId>`
67
+ * prefix and `.json` suffix, so a matcher written for `/admin` also guards that
68
+ * page's data URL, even one with a stale buildId. Middleware matching uses this
69
+ * when the request reaches middleware with its raw data URL
70
+ * (`skipProxyUrlNormalize`).
71
+ * https://github.com/vercel/next.js/blob/v16.2.7/packages/next/src/build/analysis/get-page-static-info.ts
72
+ */
73
+ export declare function nextDataMiddlewareMatchPathname(pathname: string): string | null;
64
74
  export declare function normalizeNextDataPagePathname(pagePathname: string, trailingSlash?: boolean): string;
65
75
  /**
66
76
  * Next.js only applies `trailingSlash` while normalizing a data URL for
@@ -67,7 +67,24 @@ function parseNextDataPathname(pathname, buildId) {
67
67
  if (!isNextDataPathname(pathname)) return null;
68
68
  const expectedPrefix = `${NEXT_DATA_PREFIX}${buildId}/`;
69
69
  if (!pathname.startsWith(expectedPrefix)) return null;
70
- const rest = pathname.slice(expectedPrefix.length, -5);
70
+ return pageFromNextDataRest(pathname.slice(expectedPrefix.length, -5));
71
+ }
72
+ /**
73
+ * The page pathname a `_next/data` URL addresses, whatever its buildId. Next.js
74
+ * compiles every middleware matcher with an optional `/_next/data/<buildId>`
75
+ * prefix and `.json` suffix, so a matcher written for `/admin` also guards that
76
+ * page's data URL, even one with a stale buildId. Middleware matching uses this
77
+ * when the request reaches middleware with its raw data URL
78
+ * (`skipProxyUrlNormalize`).
79
+ * https://github.com/vercel/next.js/blob/v16.2.7/packages/next/src/build/analysis/get-page-static-info.ts
80
+ */
81
+ function nextDataMiddlewareMatchPathname(pathname) {
82
+ if (!isNextDataPathname(pathname)) return null;
83
+ const buildIdEnd = pathname.indexOf("/", 12);
84
+ if (buildIdEnd <= 12) return null;
85
+ return pageFromNextDataRest(pathname.slice(buildIdEnd + 1, -5))?.pagePathname ?? null;
86
+ }
87
+ function pageFromNextDataRest(rest) {
71
88
  if (rest.length === 0) return null;
72
89
  if (rest === "index") return { pagePathname: "/" };
73
90
  if (rest.endsWith("/index")) return { pagePathname: `/${rest.slice(0, -6)}` };
@@ -181,4 +198,4 @@ function normalizePagesDataRequest(request, buildId, basePath = "", trailingSlas
181
198
  };
182
199
  }
183
200
  //#endregion
184
- export { buildMiddlewarePrefetchSkipResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath };
201
+ export { buildMiddlewarePrefetchSkipResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, nextDataMiddlewareMatchPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath };
@@ -10,7 +10,11 @@ type ApplyDocumentAssetPropsOptions = {
10
10
  protectedAssetMarker?: string;
11
11
  scriptOwner?: "head" | "next-script";
12
12
  };
13
- export declare function extractDocumentAssetProps(html: string): {
13
+ /**
14
+ * Read and strip the nonce and crossOrigin props that `<Head>` and
15
+ * `<NextScript />` recorded on their tags, found by this render's token.
16
+ */
17
+ export declare function extractDocumentAssetProps(html: string, token: string): {
14
18
  html: string;
15
19
  props: DocumentAssetProps;
16
20
  };
@@ -1,4 +1,6 @@
1
+ import { escapeRegExp } from "../utils/regex.js";
1
2
  import { escapeHtmlAttr } from "./html.js";
3
+ import { getDocumentHeadOpenMarker, getDocumentScriptsPlaceholder } from "../shims/document-placeholders.js";
2
4
  //#region src/server/pages-document-asset-props.ts
3
5
  const HEAD_NONCE_ATTR = "data-vinext-head-nonce";
4
6
  const HEAD_CROSS_ORIGIN_ATTR = "data-vinext-head-cross-origin";
@@ -11,9 +13,15 @@ function readAttribute(tag, name) {
11
13
  function removeAttributes(tag, names) {
12
14
  return tag.replace(new RegExp(`\\s(?:${names.join("|")})="[^"]*"`, "g"), "");
13
15
  }
14
- function extractDocumentAssetProps(html) {
15
- const headTag = html.match(/<head\b[^>]*>/i)?.[0];
16
- const nextScriptTag = html.match(/<span\b[^>]*>(?=<!-- __NEXT_SCRIPTS__ -->)/i)?.[0];
16
+ /**
17
+ * Read and strip the nonce and crossOrigin props that `<Head>` and
18
+ * `<NextScript />` recorded on their tags, found by this render's token.
19
+ */
20
+ function extractDocumentAssetProps(html, token) {
21
+ const headTagPattern = new RegExp(`<head\\b[^>]*${escapeRegExp(getDocumentHeadOpenMarker(token))}[^>]*>`, "i");
22
+ const nextScriptTagPattern = new RegExp(`<span\\b[^>]*>(?=${escapeRegExp(getDocumentScriptsPlaceholder(token))})`, "i");
23
+ const headTag = html.match(headTagPattern)?.[0];
24
+ const nextScriptTag = html.match(nextScriptTagPattern)?.[0];
17
25
  const props = {
18
26
  headNonce: readAttribute(headTag, HEAD_NONCE_ATTR),
19
27
  headCrossOrigin: readAttribute(headTag, HEAD_CROSS_ORIGIN_ATTR),
@@ -21,14 +29,14 @@ function extractDocumentAssetProps(html) {
21
29
  scriptCrossOrigin: readAttribute(nextScriptTag, SCRIPT_CROSS_ORIGIN_ATTR)
22
30
  };
23
31
  return {
24
- html: html.replace(/<head\b[^>]*>/i, (tag) => removeAttributes(tag, [HEAD_NONCE_ATTR, HEAD_CROSS_ORIGIN_ATTR])).replace(/<span\b[^>]*>(?=<!-- __NEXT_SCRIPTS__ -->)/i, (tag) => removeAttributes(tag, [SCRIPT_NONCE_ATTR, SCRIPT_CROSS_ORIGIN_ATTR])),
32
+ html: html.replace(headTagPattern, (tag) => removeAttributes(tag, [HEAD_NONCE_ATTR, HEAD_CROSS_ORIGIN_ATTR])).replace(nextScriptTagPattern, (tag) => removeAttributes(tag, [SCRIPT_NONCE_ATTR, SCRIPT_CROSS_ORIGIN_ATTR])),
25
33
  props
26
34
  };
27
35
  }
28
36
  function addAttribute(tag, name, value, replaceExisting = false) {
29
37
  if (value === void 0) return tag;
30
38
  const attributePattern = new RegExp(`\\s${name}(?:="[^"]*")?`, "i");
31
- if (attributePattern.test(tag)) return replaceExisting ? tag.replace(attributePattern, ` ${name}="${escapeHtmlAttr(value)}"`) : tag;
39
+ if (attributePattern.test(tag)) return replaceExisting ? tag.replace(attributePattern, () => ` ${name}="${escapeHtmlAttr(value)}"`) : tag;
32
40
  if (!tag.endsWith(">")) return tag;
33
41
  const selfClosing = tag.endsWith("/>");
34
42
  const closingStart = selfClosing ? tag.length - 2 : tag.length - 1;
@@ -0,0 +1,19 @@
1
+ //#region src/server/pages-document-splice.d.ts
2
+ /**
3
+ * Drop `<Head>`'s marker attribute and insert `insertion` right after its
4
+ * opening tag. Dev HTML transforms may add attributes after the marker.
5
+ */
6
+ export declare function spliceDocumentHeadOpen(html: string, token: string, insertion: string): string;
7
+ /** Insert `insertion` right before `<Head>`'s closing tag. */
8
+ export declare function spliceDocumentHeadClose(html: string, token: string, insertion: string): string;
9
+ /** Put the generated hydration scripts where `<NextScript />` rendered. */
10
+ export declare function spliceDocumentScripts(html: string, token: string, scripts: string): string;
11
+ /**
12
+ * Split the Document where `<Main />` rendered. Like Next.js, a Document
13
+ * without `<Main />` gets the page body after its own markup.
14
+ */
15
+ export declare function splitDocumentAtMain(html: string, token: string): {
16
+ prefix: string;
17
+ suffix: string;
18
+ };
19
+ //#endregion
@@ -0,0 +1,55 @@
1
+ import { getDocumentHeadCloseMarker, getDocumentHeadOpenMarker, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder } from "../shims/document-placeholders.js";
2
+ //#region src/server/pages-document-splice.ts
3
+ /**
4
+ * Splices framework output into a serialized custom Pages Router Document.
5
+ *
6
+ * `<Head>`, `<Main />` and `<NextScript />` mark their splice points with the
7
+ * per-render token from `vinext/shims/document-placeholders`, so nothing the
8
+ * Document renders can be taken for one. Each edit slices at a located index
9
+ * instead of calling `String#replace`, so inserted HTML is never parsed for
10
+ * `$&`-style replacement patterns. Like Next.js, a Document that leaves out
11
+ * one of those components gets nothing inserted for it.
12
+ */
13
+ function spliceMarker(html, marker, insertion) {
14
+ const index = html.indexOf(marker);
15
+ if (index === -1) return html;
16
+ return html.slice(0, index) + insertion + html.slice(index + marker.length);
17
+ }
18
+ /**
19
+ * Drop `<Head>`'s marker attribute and insert `insertion` right after its
20
+ * opening tag. Dev HTML transforms may add attributes after the marker.
21
+ */
22
+ function spliceDocumentHeadOpen(html, token, insertion) {
23
+ const marker = getDocumentHeadOpenMarker(token);
24
+ const index = html.indexOf(marker);
25
+ if (index === -1) return html;
26
+ const tagEnd = html.indexOf(">", index + marker.length) + 1;
27
+ if (tagEnd === 0) return html;
28
+ return html.slice(0, index) + html.slice(index + marker.length, tagEnd) + insertion + html.slice(tagEnd);
29
+ }
30
+ /** Insert `insertion` right before `<Head>`'s closing tag. */
31
+ function spliceDocumentHeadClose(html, token, insertion) {
32
+ return spliceMarker(html, getDocumentHeadCloseMarker(token), insertion);
33
+ }
34
+ /** Put the generated hydration scripts where `<NextScript />` rendered. */
35
+ function spliceDocumentScripts(html, token, scripts) {
36
+ return spliceMarker(html, getDocumentScriptsPlaceholder(token), scripts);
37
+ }
38
+ /**
39
+ * Split the Document where `<Main />` rendered. Like Next.js, a Document
40
+ * without `<Main />` gets the page body after its own markup.
41
+ */
42
+ function splitDocumentAtMain(html, token) {
43
+ const placeholder = getDocumentMainPlaceholder(token);
44
+ const index = html.indexOf(placeholder);
45
+ if (index === -1) return {
46
+ prefix: html,
47
+ suffix: ""
48
+ };
49
+ return {
50
+ prefix: html.slice(0, index),
51
+ suffix: html.slice(index + placeholder.length)
52
+ };
53
+ }
54
+ //#endregion
55
+ export { spliceDocumentHeadClose, spliceDocumentHeadOpen, spliceDocumentScripts, splitDocumentAtMain };
@@ -24,6 +24,15 @@ type PagesI18nRequestInfo = {
24
24
  domainLocale?: DomainLocale;
25
25
  redirectUrl?: string;
26
26
  };
27
+ /**
28
+ * Return the configured locale that the first pathname segment names, compared
29
+ * case-insensitively (`/EN/about` -> `"en"`), or `undefined` when there is none.
30
+ * The configured casing is returned, not the request's.
31
+ *
32
+ * Ported from Next.js: packages/next/src/shared/lib/i18n/normalize-locale-path.ts
33
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
34
+ */
35
+ export declare function detectPathnameLocale(pathname: string, locales: readonly string[]): string | undefined;
27
36
  /**
28
37
  * Prepend the default locale prefix to a pathname when i18n is configured and
29
38
  * the path does not already carry a locale prefix. Mirrors Next.js's
@@ -42,7 +51,9 @@ type PagesI18nRequestInfo = {
42
51
  * - `/__vinext/*` (vinext-internal endpoints)
43
52
  *
44
53
  * Returns the input unchanged when i18n is not configured or when the path
45
- * already starts with one of the configured locales. The host-based default
54
+ * already starts with one of the configured locales (compared
55
+ * case-insensitively, like Next.js's `normalizeLocalePath`, so `/EN/about`
56
+ * is left alone rather than becoming `/en/EN/about`). The host-based default
46
57
  * locale (i18n.domains[].defaultLocale) is preferred over the global default
47
58
  * when supplied, matching Next.js's `domainLocale.defaultLocale` branch.
48
59
  *
@@ -9,6 +9,19 @@ function readHeader(headers, name) {
9
9
  }
10
10
  const normalizeHostname = normalizeDomainHostname;
11
11
  /**
12
+ * Return the configured locale that the first pathname segment names, compared
13
+ * case-insensitively (`/EN/about` -> `"en"`), or `undefined` when there is none.
14
+ * The configured casing is returned, not the request's.
15
+ *
16
+ * Ported from Next.js: packages/next/src/shared/lib/i18n/normalize-locale-path.ts
17
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
18
+ */
19
+ function detectPathnameLocale(pathname, locales) {
20
+ const segment = pathname.split("/", 2)[1]?.toLowerCase();
21
+ if (!segment) return void 0;
22
+ return locales.find((locale) => locale.toLowerCase() === segment);
23
+ }
24
+ /**
12
25
  * Prepend the default locale prefix to a pathname when i18n is configured and
13
26
  * the path does not already carry a locale prefix. Mirrors Next.js's
14
27
  * server-side path normalisation in `resolve-routes.ts` (lines ~250-263):
@@ -26,7 +39,9 @@ const normalizeHostname = normalizeDomainHostname;
26
39
  * - `/__vinext/*` (vinext-internal endpoints)
27
40
  *
28
41
  * Returns the input unchanged when i18n is not configured or when the path
29
- * already starts with one of the configured locales. The host-based default
42
+ * already starts with one of the configured locales (compared
43
+ * case-insensitively, like Next.js's `normalizeLocalePath`, so `/EN/about`
44
+ * is left alone rather than becoming `/en/EN/about`). The host-based default
30
45
  * locale (i18n.domains[].defaultLocale) is preferred over the global default
31
46
  * when supplied, matching Next.js's `domainLocale.defaultLocale` branch.
32
47
  *
@@ -42,8 +57,7 @@ const normalizeHostname = normalizeDomainHostname;
42
57
  function normalizeDefaultLocalePathname(pathname, i18n, options = {}) {
43
58
  if (!i18n) return pathname;
44
59
  if (pathname.startsWith("/_next/") || pathname.startsWith("/__vinext/")) return pathname;
45
- const parts = pathname.split("/", 3);
46
- if (parts[1] && i18n.locales.includes(parts[1])) return pathname;
60
+ if (detectPathnameLocale(pathname, i18n.locales)) return pathname;
47
61
  const defaultLocale = detectDomainLocale(i18n.domains, options.hostname ?? void 0)?.defaultLocale ?? i18n.defaultLocale;
48
62
  if (pathname === "/") return `/${defaultLocale}`;
49
63
  return `/${defaultLocale}${pathname}`;
@@ -229,4 +243,4 @@ function resolvePagesI18nRequest(url, i18nConfig, headers, hostname, basePath =
229
243
  };
230
244
  }
231
245
  //#endregion
232
- export { detectDomainLocale, detectLocaleFromAcceptLanguage, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, stripI18nLocaleForApiRoute };
246
+ export { detectDomainLocale, detectLocaleFromAcceptLanguage, detectPathnameLocale, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, stripI18nLocaleForApiRoute };
@@ -29,7 +29,6 @@ export type PagesReqResResponse = Writable & {
29
29
  send: (data: unknown) => void;
30
30
  redirect: (statusOrUrl: number | string, url?: string) => PagesReqResResponse;
31
31
  getHeaders: () => PagesReqResHeaders;
32
- revalidate: (urlPath: string, opts?: RevalidateOptions) => Promise<void>;
33
32
  setPreviewData: (data: object | string, options?: {
34
33
  maxAge?: number;
35
34
  path?: string;
@@ -41,6 +40,9 @@ export type PagesReqResResponse = Writable & {
41
40
  enable?: boolean;
42
41
  }) => PagesReqResResponse;
43
42
  };
43
+ export type PagesApiReqResResponse = PagesReqResResponse & {
44
+ revalidate: (urlPath: string, opts?: RevalidateOptions) => Promise<void>;
45
+ };
44
46
  type PagesRequestCookiesCarrier = {
45
47
  headers: {
46
48
  cookie?: string | string[] | null | undefined;
@@ -48,17 +50,19 @@ type PagesRequestCookiesCarrier = {
48
50
  cookies?: unknown;
49
51
  };
50
52
  type CreatePagesReqResOptions = {
51
- allowedRevalidateHeaderKeys?: readonly string[];
52
53
  body: unknown;
53
54
  initialResponseHeaders?: Headers;
54
55
  query: PagesRequestQuery;
55
56
  request: Request;
56
- trustedRevalidateOrigin?: string;
57
57
  url: string;
58
58
  };
59
- type CreatePagesReqResResult = {
59
+ type CreatePagesApiReqResOptions = CreatePagesReqResOptions & {
60
+ allowedRevalidateHeaderKeys?: readonly string[];
61
+ trustedRevalidateOrigin?: string;
62
+ };
63
+ type CreatePagesReqResResult<Res extends PagesReqResResponse = PagesReqResResponse> = {
60
64
  req: PagesReqResRequest;
61
- res: PagesReqResResponse;
65
+ res: Res;
62
66
  responsePromise: Promise<Response>;
63
67
  };
64
68
  /**
@@ -85,5 +89,12 @@ export declare function attachPagesPreviewApi(req: PagesReqResRequest, res: Page
85
89
  export declare function markVinextStreamedApiResponse(response: Response): void;
86
90
  export declare function isVinextStreamedApiResponse(response: Response): boolean;
87
91
  export declare function createPagesReqRes(options: CreatePagesReqResOptions): CreatePagesReqResResult;
92
+ /**
93
+ * Create the req/res pair for a Pages API route. Only API responses get
94
+ * `res.revalidate()`: Next.js attaches it in apiResolver
95
+ * (`packages/next/src/server/api-utils/node/api-resolver.ts`), so a page's
96
+ * getServerSideProps `res` never carries the revalidation secret.
97
+ */
98
+ export declare function createPagesApiReqRes(options: CreatePagesApiReqResOptions): CreatePagesReqResResult<PagesApiReqResResponse>;
88
99
  //#endregion
89
100
  export { PagesBodyParseError as PagesApiBodyParseError };
@@ -119,9 +119,6 @@ function attachPagesPreviewApi(req, res) {
119
119
  var PagesResponseStream = class extends Writable {
120
120
  resolveResponse;
121
121
  rejectResponse;
122
- requestHeaders;
123
- trustedRevalidateOrigin;
124
- allowedRevalidateHeaderKeys;
125
122
  resStatusCode = 200;
126
123
  resHeaders = {};
127
124
  setCookieHeaders = [];
@@ -131,13 +128,10 @@ var PagesResponseStream = class extends Writable {
131
128
  streamEnded = false;
132
129
  pendingWrite = null;
133
130
  discardBody = false;
134
- constructor(resolveResponse, rejectResponse, requestHeaders, trustedRevalidateOrigin, allowedRevalidateHeaderKeys = []) {
131
+ constructor(resolveResponse, rejectResponse) {
135
132
  super();
136
133
  this.resolveResponse = resolveResponse;
137
134
  this.rejectResponse = rejectResponse;
138
- this.requestHeaders = requestHeaders;
139
- this.trustedRevalidateOrigin = trustedRevalidateOrigin;
140
- this.allowedRevalidateHeaderKeys = allowedRevalidateHeaderKeys;
141
135
  this.once("error", (err) => {
142
136
  if (!this.resolved) {
143
137
  this.resolved = true;
@@ -206,9 +200,6 @@ var PagesResponseStream = class extends Writable {
206
200
  if (this.setCookieHeaders.length > 0) headers["set-cookie"] = this.setCookieHeaders;
207
201
  return headers;
208
202
  }
209
- async revalidate(urlPath, opts) {
210
- await performOnDemandRevalidate(this.requestHeaders, urlPath, opts, this.trustedRevalidateOrigin, this.allowedRevalidateHeaderKeys);
211
- }
212
203
  setPreviewData(data, options = {}) {
213
204
  setPagesPreviewData(this, data, options);
214
205
  return this;
@@ -346,7 +337,7 @@ function createPagesReqRes(options) {
346
337
  resolveResponse = resolve;
347
338
  rejectResponse = reject;
348
339
  });
349
- const res = new PagesResponseStream(resolveResponse, rejectResponse, options.request.headers, options.trustedRevalidateOrigin ?? new URL(options.request.url).origin, options.allowedRevalidateHeaderKeys);
340
+ const res = new PagesResponseStream(resolveResponse, rejectResponse);
350
341
  for (const [name, value] of options.initialResponseHeaders ?? []) {
351
342
  if (name.toLowerCase() === "set-cookie") continue;
352
343
  res.setHeader(name, value);
@@ -360,5 +351,22 @@ function createPagesReqRes(options) {
360
351
  responsePromise
361
352
  };
362
353
  }
354
+ /**
355
+ * Create the req/res pair for a Pages API route. Only API responses get
356
+ * `res.revalidate()`: Next.js attaches it in apiResolver
357
+ * (`packages/next/src/server/api-utils/node/api-resolver.ts`), so a page's
358
+ * getServerSideProps `res` never carries the revalidation secret.
359
+ */
360
+ function createPagesApiReqRes(options) {
361
+ const { req, res, responsePromise } = createPagesReqRes(options);
362
+ const trustedRevalidateOrigin = options.trustedRevalidateOrigin ?? new URL(options.request.url).origin;
363
+ return {
364
+ req,
365
+ res: Object.assign(res, { async revalidate(urlPath, opts) {
366
+ await performOnDemandRevalidate(options.request.headers, urlPath, opts, trustedRevalidateOrigin, options.allowedRevalidateHeaderKeys);
367
+ } }),
368
+ responsePromise
369
+ };
370
+ }
363
371
  //#endregion
364
- export { PagesBodyParseError as PagesApiBodyParseError, attachPagesPreviewApi, attachPagesRequestCookies, createPagesReqRes, isVinextStreamedApiResponse, markVinextStreamedApiResponse, parsePagesApiBody };
372
+ export { PagesBodyParseError as PagesApiBodyParseError, attachPagesPreviewApi, attachPagesRequestCookies, createPagesApiReqRes, createPagesReqRes, isVinextStreamedApiResponse, markVinextStreamedApiResponse, parsePagesApiBody };
@@ -1,5 +1,4 @@
1
1
  import { Route } from "../routing/pages-router.js";
2
- import { VinextNextData } from "../client/vinext-next-data.js";
3
2
  import { CachedPagesValue, CachedRedirectValue } from "../shims/cache-handler.js";
4
3
  import { ISRCacheEntry, IsrWritePolicy } from "./isr-cache.js";
5
4
  import { PagesPreviewData } from "./pages-preview.js";
@@ -43,6 +42,14 @@ export declare function assertPages404DoesNotReturnNotFound(routePattern: string
43
42
  * - packages/next/src/server/render.tsx (`metadata.cacheControl`)
44
43
  * - packages/next/src/server/route-modules/pages/pages-handler.ts
45
44
  */
45
+ /**
46
+ * Next.js renders a shared getStaticProps status page (/404, /500) for its own
47
+ * pathname, never for the request that reached it. Only the original
48
+ * request's trailing slash carries over under `trailingSlash`, read before
49
+ * rewrites and locale stripping.
50
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/pages/pages-handler.ts
51
+ */
52
+ export declare function resolvePagesStatusPageRenderPath(statusPathname: string, trailingSlash: boolean, requestPathname: string): string;
46
53
  export declare function resolvePagesRevalidateSeconds(result: PagesPagePropsResult, routeUrl?: string): number | false;
47
54
  type PagesMutableGsspResponse = {
48
55
  headersSent: boolean;
@@ -115,25 +122,9 @@ export type PagesPageModule = {
115
122
  revalidateReason?: "build" | "on-demand" | "stale";
116
123
  }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;
117
124
  };
118
- type RenderPagesIsrHtmlOptions = {
119
- buildId: string | null;
120
- cachedHtml: string;
121
- collectIsrHeadHTML?: (() => string) | undefined;
122
- createPageElement: (props: Record<string, unknown>) => ReactNode;
123
- i18n: PagesI18nRenderContext;
124
- pageProps: Record<string, unknown>;
125
- props?: Record<string, unknown>;
126
- params: Record<string, unknown>;
127
- renderIsrPassToStringAsync: (element: ReactNode, onHeadReady?: () => Promise<void>) => Promise<string>;
128
- routePattern: string;
129
- safeJsonStringify: (value: unknown) => string;
130
- vinext?: VinextNextData["__vinext"];
131
- nextData?: PagesNextDataExtras;
132
- };
133
125
  export type ResolvePagesPageDataOptions = {
134
126
  applyRequestContexts: () => void;
135
127
  basePath?: string;
136
- buildId: string | null;
137
128
  /**
138
129
  * When true, this is a `/_next/data/<buildId>/<page>.json` request. Callers
139
130
  * that respond with a JSON envelope (`{ pageProps }`) instead of HTML must
@@ -145,6 +136,8 @@ export type ResolvePagesPageDataOptions = {
145
136
  isDataReq?: boolean;
146
137
  err?: unknown;
147
138
  createGsspReqRes: () => PagesGsspContextResponse;
139
+ /** The req/res for a stale regeneration's render; defaults to `createGsspReqRes`. */
140
+ createRegenerationReqRes?: () => PagesGsspContextResponse;
148
141
  createAppTree?: (props: Record<string, unknown>) => ReactNode;
149
142
  createPageElement: (props: Record<string, unknown>) => ReactNode;
150
143
  fontLinkHeader: string;
@@ -188,6 +181,12 @@ export type ResolvePagesPageDataOptions = {
188
181
  * fallback path. Mirrors Next.js `unstable_onlyGenerated`.
189
182
  */
190
183
  revalidateOnlyGenerated?: boolean;
184
+ /**
185
+ * Set when a cache adapter regenerates an entry it stores for this build.
186
+ * The stored entry proves the path was admitted, so `getStaticPaths()` is
187
+ * skipped as it is for an entry read through `isrGet`.
188
+ */
189
+ regeneratesStoredEntry?: boolean;
191
190
  previewData?: PagesPreviewData | false;
192
191
  /**
193
192
  * The deployment ID used for deployment-skew protection. When set, it is
@@ -226,14 +225,19 @@ export type ResolvePagesPageDataOptions = {
226
225
  routePath: string;
227
226
  routeType: "render";
228
227
  }) => void;
229
- renderIsrPassToStringAsync: (element: ReactNode, onHeadReady?: () => Promise<void>) => Promise<string>;
230
228
  /**
231
- * Serializes the `<head>` collected by an ISR regeneration render. Called
232
- * inside that render's head scope so the regenerated shell can pick up
233
- * `next/head` output derived from the refreshed `getStaticProps` data.
229
+ * Render the whole document for regenerated props and store it as the ISR
230
+ * entry, through the same pipeline (and with the same cache write) as a
231
+ * foreground MISS. Next.js re-runs its full render on regeneration too;
232
+ * resolves once the entry is written.
234
233
  */
235
- collectIsrHeadHTML?: (() => string) | undefined;
236
- vinext?: VinextNextData["__vinext"];
234
+ renderIsrDocument: (input: {
235
+ documentReqRes: PagesGsspContextResponse;
236
+ expireSeconds: number | undefined;
237
+ pageProps: Record<string, unknown>;
238
+ props: Record<string, unknown>;
239
+ revalidateSeconds: number | false;
240
+ }) => Promise<void>;
237
241
  nextData?: PagesNextDataExtras;
238
242
  /**
239
243
  * The request's User-Agent string. When this matches a known crawler/bot
@@ -250,6 +254,11 @@ export type ResolvePagesPageDataOptions = {
250
254
  * response is a `304 Not Modified` with no body.
251
255
  */
252
256
  ifNoneMatch?: string;
257
+ /**
258
+ * The incoming request's `If-Modified-Since` header value. As in Next.js,
259
+ * which gives a page no Last-Modified, a request with it gets the page.
260
+ */
261
+ ifModifiedSince?: string;
253
262
  /**
254
263
  * The incoming request's `Cache-Control` header value. When it contains
255
264
  * `no-cache`, the 304 short-circuit is skipped and a full response is
@@ -320,6 +329,5 @@ export type PagesRouteParam = {
320
329
  };
321
330
  export declare function getPagesRouteParams(routePattern: string): PagesRouteParam[];
322
331
  export declare function matchesPagesStaticPath(pathEntry: PagesStaticPathsEntry, params: Record<string, unknown>, routeParams: PagesRouteParam[], routeUrl: string, i18n?: Pick<PagesI18nRenderContext, "locale" | "locales" | "defaultLocale">): boolean;
323
- export declare function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string>;
324
332
  export declare function resolvePagesPageData(options: ResolvePagesPageDataOptions): Promise<ResolvePagesPageDataResult>;
325
333
  //#endregion