vinext 0.1.8 → 0.2.1

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 (285) hide show
  1. package/README.md +51 -30
  2. package/dist/build/css-url-assets.d.ts +3 -1
  3. package/dist/build/css-url-assets.js +18 -1
  4. package/dist/build/inject-pregenerated-paths.d.ts +7 -0
  5. package/dist/build/inject-pregenerated-paths.js +21 -0
  6. package/dist/build/layout-classification.js +1 -1
  7. package/dist/build/nitro-route-rules.js +1 -1
  8. package/dist/build/pages-client-assets-module.d.ts +11 -0
  9. package/dist/build/pages-client-assets-module.js +27 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +2 -1
  15. package/dist/build/prerender.js +98 -27
  16. package/dist/build/report.d.ts +13 -2
  17. package/dist/build/report.js +99 -2
  18. package/dist/build/run-prerender.d.ts +7 -0
  19. package/dist/build/run-prerender.js +12 -2
  20. package/dist/build/standalone.js +2 -0
  21. package/dist/cache/cache-adapters-virtual.js +3 -3
  22. package/dist/check.d.ts +4 -6
  23. package/dist/check.js +48 -11
  24. package/dist/cli-args.d.ts +1 -2
  25. package/dist/cli-args.js +1 -1
  26. package/dist/cli-dev-config.d.ts +12 -0
  27. package/dist/cli-dev-config.js +23 -0
  28. package/dist/cli.js +112 -96
  29. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  30. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  31. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  32. package/dist/{server → client}/dev-error-overlay.js +2 -2
  33. package/dist/client/navigation-runtime.d.ts +2 -0
  34. package/dist/client/navigation-runtime.js +3 -1
  35. package/dist/client/vinext-next-data.d.ts +4 -1
  36. package/dist/client/window-next.d.ts +2 -1
  37. package/dist/cloudflare/index.d.ts +2 -2
  38. package/dist/cloudflare/index.js +2 -2
  39. package/dist/config/config-matchers.js +45 -19
  40. package/dist/config/next-config.d.ts +41 -9
  41. package/dist/config/next-config.js +60 -3
  42. package/dist/config/prerender.d.ts +34 -0
  43. package/dist/config/prerender.js +55 -0
  44. package/dist/entries/app-browser-entry.js +5 -1
  45. package/dist/entries/app-rsc-entry.d.ts +5 -3
  46. package/dist/entries/app-rsc-entry.js +44 -10
  47. package/dist/entries/app-rsc-manifest.js +2 -0
  48. package/dist/entries/pages-client-entry.d.ts +3 -0
  49. package/dist/entries/pages-client-entry.js +28 -3
  50. package/dist/entries/pages-server-entry.js +23 -6
  51. package/dist/image/image-adapters-virtual.d.ts +59 -0
  52. package/dist/image/image-adapters-virtual.js +59 -0
  53. package/dist/index.d.ts +33 -0
  54. package/dist/index.js +482 -120
  55. package/dist/init-cloudflare.d.ts +43 -0
  56. package/dist/init-cloudflare.js +839 -0
  57. package/dist/init-platform.d.ts +40 -0
  58. package/dist/init-platform.js +195 -0
  59. package/dist/init.d.ts +16 -38
  60. package/dist/init.js +209 -99
  61. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  62. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  63. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  64. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  65. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
  66. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  67. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  68. package/dist/packages/cloudflare/src/deploy.js +272 -0
  69. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  70. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
  71. package/dist/plugins/ast-scope.d.ts +16 -0
  72. package/dist/plugins/ast-scope.js +62 -0
  73. package/dist/plugins/ast-utils.d.ts +27 -1
  74. package/dist/plugins/ast-utils.js +32 -1
  75. package/dist/plugins/css-module-imports.d.ts +14 -0
  76. package/dist/plugins/css-module-imports.js +59 -0
  77. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  78. package/dist/plugins/fonts.js +1 -1
  79. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  80. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  81. package/dist/plugins/og-assets.js +2 -1
  82. package/dist/plugins/optimize-imports.js +1 -1
  83. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  84. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  85. package/dist/plugins/sass.d.ts +17 -1
  86. package/dist/plugins/sass.js +74 -1
  87. package/dist/plugins/styled-jsx.d.ts +16 -0
  88. package/dist/plugins/styled-jsx.js +149 -0
  89. package/dist/plugins/typeof-window.d.ts +1 -1
  90. package/dist/plugins/typeof-window.js +28 -56
  91. package/dist/routing/app-route-graph.d.ts +23 -2
  92. package/dist/routing/app-route-graph.js +138 -38
  93. package/dist/routing/file-matcher.d.ts +11 -1
  94. package/dist/routing/file-matcher.js +18 -3
  95. package/dist/routing/pages-router.js +2 -2
  96. package/dist/server/api-handler.js +9 -14
  97. package/dist/server/app-browser-action-result.d.ts +4 -1
  98. package/dist/server/app-browser-action-result.js +8 -1
  99. package/dist/server/app-browser-entry.js +198 -57
  100. package/dist/server/app-browser-interception-context.d.ts +1 -0
  101. package/dist/server/app-browser-interception-context.js +4 -2
  102. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  103. package/dist/server/app-browser-navigation-controller.js +60 -31
  104. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  105. package/dist/server/app-browser-server-action-client.js +8 -7
  106. package/dist/server/app-browser-state.d.ts +12 -1
  107. package/dist/server/app-browser-state.js +25 -8
  108. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  109. package/dist/server/app-browser-visible-commit.js +42 -24
  110. package/dist/server/app-elements-wire.d.ts +9 -2
  111. package/dist/server/app-elements-wire.js +8 -1
  112. package/dist/server/app-elements.d.ts +2 -2
  113. package/dist/server/app-elements.js +4 -3
  114. package/dist/server/app-fallback-renderer.d.ts +2 -1
  115. package/dist/server/app-fallback-renderer.js +10 -6
  116. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  117. package/dist/server/app-hydration-cache-publication.js +43 -0
  118. package/dist/server/app-middleware.d.ts +4 -3
  119. package/dist/server/app-middleware.js +8 -3
  120. package/dist/server/app-optimistic-routing.js +11 -4
  121. package/dist/server/app-page-boundary.js +2 -1
  122. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  123. package/dist/server/app-page-cache-finalizer.js +5 -4
  124. package/dist/server/app-page-cache-render.d.ts +1 -0
  125. package/dist/server/app-page-cache-render.js +8 -4
  126. package/dist/server/app-page-cache.d.ts +1 -0
  127. package/dist/server/app-page-cache.js +27 -7
  128. package/dist/server/app-page-dispatch.d.ts +1 -0
  129. package/dist/server/app-page-dispatch.js +26 -8
  130. package/dist/server/app-page-element-builder.d.ts +2 -1
  131. package/dist/server/app-page-element-builder.js +59 -4
  132. package/dist/server/app-page-execution.js +2 -1
  133. package/dist/server/app-page-probe.js +5 -0
  134. package/dist/server/app-page-render-identity.d.ts +2 -0
  135. package/dist/server/app-page-render-identity.js +3 -2
  136. package/dist/server/app-page-render.d.ts +2 -0
  137. package/dist/server/app-page-render.js +85 -16
  138. package/dist/server/app-page-request.d.ts +14 -0
  139. package/dist/server/app-page-request.js +69 -4
  140. package/dist/server/app-page-response.d.ts +7 -0
  141. package/dist/server/app-page-response.js +16 -4
  142. package/dist/server/app-page-route-wiring.d.ts +8 -1
  143. package/dist/server/app-page-route-wiring.js +32 -18
  144. package/dist/server/app-page-segment-state.d.ts +2 -1
  145. package/dist/server/app-page-segment-state.js +3 -1
  146. package/dist/server/app-page-stream.d.ts +7 -1
  147. package/dist/server/app-page-stream.js +3 -1
  148. package/dist/server/app-route-handler-execution.js +5 -1
  149. package/dist/server/app-route-handler-response.js +1 -0
  150. package/dist/server/app-route-handler-runtime.js +1 -1
  151. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  152. package/dist/server/app-route-tree-prefetch.js +187 -0
  153. package/dist/server/app-router-entry.js +9 -2
  154. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  155. package/dist/server/app-rsc-cache-busting.js +9 -4
  156. package/dist/server/app-rsc-handler.d.ts +7 -0
  157. package/dist/server/app-rsc-handler.js +148 -39
  158. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  159. package/dist/server/app-rsc-render-mode.js +4 -1
  160. package/dist/server/app-rsc-request-normalization.d.ts +6 -6
  161. package/dist/server/app-rsc-request-normalization.js +10 -8
  162. package/dist/server/app-segment-config.d.ts +11 -0
  163. package/dist/server/app-segment-config.js +62 -6
  164. package/dist/server/app-server-action-execution.d.ts +1 -0
  165. package/dist/server/app-server-action-execution.js +61 -30
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +13 -5
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-visited-response-cache.d.ts +6 -0
  171. package/dist/server/app-visited-response-cache.js +3 -1
  172. package/dist/server/cache-control.d.ts +3 -1
  173. package/dist/server/cache-control.js +13 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.d.ts +11 -1
  179. package/dist/server/dev-server.js +94 -35
  180. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  181. package/dist/server/dev-stack-sourcemap.js +1 -1
  182. package/dist/server/fetch-handler.d.ts +2 -0
  183. package/dist/server/fetch-handler.js +18 -0
  184. package/dist/server/headers.d.ts +7 -15
  185. package/dist/server/headers.js +11 -18
  186. package/dist/server/image-optimization.d.ts +51 -1
  187. package/dist/server/image-optimization.js +52 -2
  188. package/dist/server/implicit-tags.js +1 -1
  189. package/dist/server/isr-cache.d.ts +3 -2
  190. package/dist/server/isr-cache.js +9 -5
  191. package/dist/server/metadata-routes.d.ts +3 -1
  192. package/dist/server/metadata-routes.js +12 -2
  193. package/dist/server/middleware-runtime.js +6 -1
  194. package/dist/server/navigation-planner.d.ts +1 -0
  195. package/dist/server/navigation-planner.js +14 -3
  196. package/dist/server/pages-api-route.js +2 -2
  197. package/dist/server/pages-asset-tags.d.ts +4 -6
  198. package/dist/server/pages-asset-tags.js +12 -12
  199. package/dist/server/pages-client-assets.d.ts +12 -0
  200. package/dist/server/pages-client-assets.js +10 -0
  201. package/dist/server/pages-data-route.d.ts +4 -2
  202. package/dist/server/pages-data-route.js +18 -4
  203. package/dist/server/pages-dev-module-url.d.ts +2 -1
  204. package/dist/server/pages-dev-module-url.js +6 -3
  205. package/dist/server/pages-node-compat.d.ts +19 -1
  206. package/dist/server/pages-node-compat.js +81 -4
  207. package/dist/server/pages-page-data.d.ts +33 -1
  208. package/dist/server/pages-page-data.js +62 -33
  209. package/dist/server/pages-page-handler.d.ts +2 -1
  210. package/dist/server/pages-page-handler.js +38 -19
  211. package/dist/server/pages-page-response.d.ts +8 -0
  212. package/dist/server/pages-page-response.js +7 -3
  213. package/dist/server/pages-request-pipeline.d.ts +9 -5
  214. package/dist/server/pages-request-pipeline.js +55 -7
  215. package/dist/server/pages-router-entry.d.ts +30 -0
  216. package/dist/server/pages-router-entry.js +108 -0
  217. package/dist/server/prerender-manifest.d.ts +3 -1
  218. package/dist/server/prerender-route-params.js +1 -1
  219. package/dist/server/prod-server.d.ts +5 -3
  220. package/dist/server/prod-server.js +68 -39
  221. package/dist/server/request-pipeline.js +2 -1
  222. package/dist/server/seed-cache.js +4 -4
  223. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  224. package/dist/shims/app-router-scroll-state.js +1 -0
  225. package/dist/shims/app-router-scroll.js +2 -1
  226. package/dist/shims/cache-handler.js +8 -1
  227. package/dist/shims/cache.js +22 -15
  228. package/dist/shims/cdn-cache.js +1 -1
  229. package/dist/shims/dynamic-preload-chunks.js +2 -1
  230. package/dist/shims/fetch-cache.d.ts +3 -1
  231. package/dist/shims/fetch-cache.js +77 -52
  232. package/dist/shims/form.d.ts +4 -2
  233. package/dist/shims/form.js +37 -43
  234. package/dist/shims/headers.d.ts +7 -1
  235. package/dist/shims/headers.js +17 -3
  236. package/dist/shims/image.js +75 -14
  237. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  238. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  239. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  240. package/dist/shims/internal/app-route-detection.js +4 -17
  241. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  242. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  243. package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
  244. package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
  245. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
  247. package/dist/shims/internal/pages-data-target.d.ts +18 -12
  248. package/dist/shims/internal/pages-data-target.js +97 -13
  249. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  250. package/dist/shims/internal/pages-router-components.js +13 -0
  251. package/dist/shims/layout-segment-context.d.ts +4 -1
  252. package/dist/shims/layout-segment-context.js +18 -4
  253. package/dist/shims/link.d.ts +1 -1
  254. package/dist/shims/link.js +224 -58
  255. package/dist/shims/navigation.d.ts +19 -3
  256. package/dist/shims/navigation.js +245 -47
  257. package/dist/shims/request-context.js +18 -0
  258. package/dist/shims/root-params.d.ts +15 -1
  259. package/dist/shims/root-params.js +21 -1
  260. package/dist/shims/router.d.ts +5 -7
  261. package/dist/shims/router.js +387 -102
  262. package/dist/shims/server.js +3 -2
  263. package/dist/shims/slot.js +3 -6
  264. package/dist/shims/unified-request-context.js +1 -0
  265. package/dist/typegen.js +1 -1
  266. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  267. package/dist/utils/client-runtime-metadata.js +31 -22
  268. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  269. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  270. package/dist/utils/domain-locale.d.ts +6 -3
  271. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  272. package/dist/{server → utils}/middleware-request-headers.js +3 -3
  273. package/dist/utils/project.d.ts +48 -2
  274. package/dist/utils/project.js +225 -4
  275. package/dist/utils/protocol-headers.d.ts +23 -0
  276. package/dist/utils/protocol-headers.js +23 -0
  277. package/dist/utils/react-version.d.ts +4 -0
  278. package/dist/utils/react-version.js +44 -0
  279. package/dist/utils/vite-version.d.ts +2 -0
  280. package/dist/utils/vite-version.js +11 -1
  281. package/package.json +47 -2
  282. package/dist/deploy.d.ts +0 -197
  283. package/dist/deploy.js +0 -1040
  284. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  285. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -1,7 +1,8 @@
1
1
  import { parseCookieHeader } from "../utils/parse-cookie.js";
2
+ import { getRevalidateSecret, isRevalidateSecret } from "./isr-cache.js";
2
3
  import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
3
- import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
4
4
  import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT } from "./pages-body-parser-config.js";
5
+ import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
5
6
  import { performOnDemandRevalidate } from "./pages-revalidate.js";
6
7
  import { decode } from "node:querystring";
7
8
  import { Readable, Writable } from "node:stream";
@@ -61,6 +62,72 @@ async function* requestBodyChunks(request) {
61
62
  function createRequestReadable(request) {
62
63
  return Readable.from(requestBodyChunks(request), { objectMode: false });
63
64
  }
65
+ function parsePagesRequestCookies(cookieHeader) {
66
+ return parseCookieHeader(Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader);
67
+ }
68
+ function serializePreviewCookie(name, value, options = {}) {
69
+ const parts = [
70
+ `${name}=${encodeURIComponent(value)}`,
71
+ "HttpOnly",
72
+ `Path=${options.path ?? "/"}`,
73
+ process.env.NODE_ENV !== "development" ? "SameSite=None" : "SameSite=Lax"
74
+ ];
75
+ if (process.env.NODE_ENV !== "development") parts.push("Secure");
76
+ if (options.maxAge !== void 0) parts.push(`Max-Age=${Math.trunc(options.maxAge)}`);
77
+ return parts.join("; ");
78
+ }
79
+ function decodePagesPreviewPayload(payload) {
80
+ try {
81
+ const decoded = Buffer.from(payload, "base64url").toString("utf8");
82
+ const value = JSON.parse(decoded);
83
+ return typeof value === "object" && value !== null ? value : String(value);
84
+ } catch {
85
+ return false;
86
+ }
87
+ }
88
+ function getPagesPreviewDataFromCookieHeader(cookieHeader, options = {}) {
89
+ if (options.isOnDemandRevalidate) return false;
90
+ const cookies = parsePagesRequestCookies(cookieHeader);
91
+ const bypass = cookies.__prerender_bypass;
92
+ const payload = cookies.__next_preview_data;
93
+ if (!bypass && !payload) return false;
94
+ if (!isRevalidateSecret(bypass)) return false;
95
+ if (!payload) return {};
96
+ return decodePagesPreviewPayload(payload);
97
+ }
98
+ function getPagesPreviewData(request, options = {}) {
99
+ return getPagesPreviewDataFromCookieHeader(request.headers.get("cookie"), options);
100
+ }
101
+ function normalizeSetCookieHeader(value) {
102
+ if (value === void 0) return [];
103
+ if (Array.isArray(value)) return value.map(String);
104
+ return [String(value)];
105
+ }
106
+ function attachPagesRequestCookies(req) {
107
+ if (Object.hasOwn(req, "cookies")) return;
108
+ Object.defineProperty(req, "cookies", {
109
+ configurable: true,
110
+ enumerable: true,
111
+ get() {
112
+ const cookies = parsePagesRequestCookies(req.headers.cookie);
113
+ Object.defineProperty(req, "cookies", {
114
+ configurable: true,
115
+ enumerable: true,
116
+ value: cookies,
117
+ writable: true
118
+ });
119
+ return cookies;
120
+ },
121
+ set(value) {
122
+ Object.defineProperty(req, "cookies", {
123
+ configurable: true,
124
+ enumerable: true,
125
+ value,
126
+ writable: true
127
+ });
128
+ }
129
+ });
130
+ }
64
131
  var PagesResponseStream = class extends Writable {
65
132
  resolveResponse;
66
133
  rejectResponse;
@@ -142,6 +209,16 @@ var PagesResponseStream = class extends Writable {
142
209
  async revalidate(urlPath, opts) {
143
210
  await performOnDemandRevalidate(this.requestHeaders, urlPath, opts);
144
211
  }
212
+ setPreviewData(data, options = {}) {
213
+ const payload = Buffer.from(JSON.stringify(data)).toString("base64url");
214
+ if (payload.length > 2048) throw new Error("Preview data is limited to 2KB currently, reduce how much data you are storing as preview data to continue");
215
+ this.setHeader("Set-Cookie", [
216
+ ...normalizeSetCookieHeader(this.getHeader("Set-Cookie")),
217
+ serializePreviewCookie("__prerender_bypass", getRevalidateSecret(), options),
218
+ serializePreviewCookie("__next_preview_data", payload, options)
219
+ ]);
220
+ return this;
221
+ }
145
222
  _write(chunk, encoding, callback) {
146
223
  const buffer = typeof chunk === "string" ? Buffer.from(chunk, encoding) : Buffer.from(chunk);
147
224
  if (this.controller && !this.streamEnded) try {
@@ -216,9 +293,9 @@ function createPagesReqRes(options) {
216
293
  url: options.url,
217
294
  headers: headersObj,
218
295
  query: options.query,
219
- body: options.body,
220
- cookies: parseCookieHeader(options.request.headers.get("cookie"))
296
+ body: options.body
221
297
  });
298
+ attachPagesRequestCookies(req);
222
299
  let resolveResponse;
223
300
  let rejectResponse;
224
301
  const responsePromise = new Promise((resolve, reject) => {
@@ -232,4 +309,4 @@ function createPagesReqRes(options) {
232
309
  };
233
310
  }
234
311
  //#endregion
235
- export { PagesBodyParseError as PagesApiBodyParseError, createPagesReqRes, parsePagesApiBody };
312
+ export { PagesBodyParseError as PagesApiBodyParseError, attachPagesRequestCookies, createPagesReqRes, getPagesPreviewData, getPagesPreviewDataFromCookieHeader, parsePagesApiBody };
@@ -2,6 +2,7 @@ import { Route } from "../routing/pages-router.js";
2
2
  import { VinextNextData } from "../client/vinext-next-data.js";
3
3
  import { CachedPagesValue } from "../shims/cache-handler.js";
4
4
  import { ISRCacheEntry } from "./isr-cache.js";
5
+ import { PagesPreviewData } from "./pages-node-compat.js";
5
6
  import { PagesGsspResponse, PagesI18nRenderContext, PagesNextDataExtras } from "./pages-page-response.js";
6
7
  import { ReactNode } from "react";
7
8
 
@@ -62,12 +63,18 @@ type PagesPageModule = {
62
63
  locale?: string;
63
64
  locales?: string[];
64
65
  defaultLocale?: string;
66
+ draftMode?: true;
67
+ preview?: true;
68
+ previewData?: PagesPreviewData;
65
69
  }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;
66
70
  getStaticProps?: (context: {
67
71
  params: Record<string, unknown> | null;
68
72
  locale?: string;
69
73
  locales?: string[];
70
74
  defaultLocale?: string;
75
+ draftMode?: true;
76
+ preview?: true;
77
+ previewData?: PagesPreviewData;
71
78
  /**
72
79
  * Indicates why `getStaticProps` was invoked.
73
80
  *
@@ -127,6 +134,7 @@ type ResolvePagesPageDataOptions = {
127
134
  * `.nextjs-ref/packages/next/src/server/render.tsx`.
128
135
  */
129
136
  isBuildTimePrerendering?: boolean;
137
+ validatePropsSerialization?: boolean;
130
138
  /**
131
139
  * When true, this dispatch was triggered by an on-demand revalidation
132
140
  * request (e.g. `res.revalidate()` in a Pages Router API route, or an
@@ -143,6 +151,7 @@ type ResolvePagesPageDataOptions = {
143
151
  * presence — see the security note in `isr-cache.ts`.
144
152
  */
145
153
  isOnDemandRevalidate?: boolean;
154
+ previewData?: PagesPreviewData | false;
146
155
  /**
147
156
  * The deployment ID used for deployment-skew protection. When set, it is
148
157
  * included as `x-nextjs-deployment-id` on all `_next/data` responses
@@ -197,6 +206,7 @@ type ResolvePagesPageDataOptions = {
197
206
  };
198
207
  type ResolvePagesPageDataRenderResult = {
199
208
  kind: "render";
209
+ documentReqRes: PagesGsspContextResponse | null;
200
210
  gsspRes: PagesGsspResponse | null;
201
211
  isrRevalidateSeconds: number | null;
202
212
  pageProps: Record<string, unknown>;
@@ -217,7 +227,29 @@ type ResolvePagesPageDataNotFoundResult = {
217
227
  kind: "notFound";
218
228
  };
219
229
  type ResolvePagesPageDataResult = ResolvePagesPageDataRenderResult | ResolvePagesPageDataResponseResult | ResolvePagesPageDataNotFoundResult;
230
+ /**
231
+ * Compare a `getStaticPaths` entry against the actual request params.
232
+ *
233
+ * Handles both shapes Next.js allows:
234
+ * - { params: { ... } }
235
+ * - "string-path"
236
+ *
237
+ * For a string entry, compare the entry against the current request URL using
238
+ * the shared `normalizeStaticPathname` helper from
239
+ * `../routing/route-pattern.ts` (which mirrors the Next.js
240
+ * `removeTrailingSlash` behaviour in
241
+ * `.nextjs-ref/packages/next/src/build/static-paths/pages.ts`). For an object
242
+ * entry with a missing `params` key, return false rather than throwing — the
243
+ * caller will respond with a 404 just like Next.js does for unlisted paths.
244
+ */
245
+ type PagesRouteParam = {
246
+ key: string;
247
+ repeat: boolean;
248
+ optional: boolean;
249
+ };
250
+ declare function getPagesRouteParams(routePattern: string): PagesRouteParam[];
251
+ declare function matchesPagesStaticPath(pathEntry: PagesStaticPathsEntry, params: Record<string, unknown>, routeParams: PagesRouteParam[], routeUrl: string): boolean;
220
252
  declare function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string>;
221
253
  declare function resolvePagesPageData(options: ResolvePagesPageDataOptions): Promise<ResolvePagesPageDataResult>;
222
254
  //#endregion
223
- export { PagesPageModule, ResolvePagesPageDataOptions, renderPagesIsrHtml, resolvePagesPageData };
255
+ export { PagesPageModule, PagesRouteParam, PagesStaticPathsEntry, ResolvePagesPageDataOptions, getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
@@ -1,15 +1,15 @@
1
1
  import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
2
- import { normalizeStaticPathname } from "../routing/route-pattern.js";
3
2
  import { buildCacheStateHeaders } from "./cache-headers.js";
4
3
  import { isUnknownRecord } from "../utils/record.js";
5
4
  import { applyCdnResponseHeaders } from "./cache-control.js";
6
5
  import { decideIsr } from "./isr-decision.js";
7
6
  import { buildPagesCacheValue } from "./isr-cache.js";
8
- import { isSerializableProps } from "./pages-serializable-props.js";
7
+ import { normalizeStaticPathname } from "../routing/route-pattern.js";
8
+ import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
9
9
  import { hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
10
- import { isBotUserAgent } from "../utils/html-limited-bots.js";
11
10
  import { buildNextDataPropsJsonResponse } from "./pages-data-route.js";
12
- import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
11
+ import { isSerializableProps } from "./pages-serializable-props.js";
12
+ import { isBotUserAgent } from "../utils/html-limited-bots.js";
13
13
  //#region src/server/pages-page-data.ts
14
14
  function buildPagesDataNotFoundResponse(deploymentId) {
15
15
  const headers = { "Content-Type": "application/json" };
@@ -128,28 +128,45 @@ function buildPagesRedirectResponse(redirect, options, props = { pageProps: {} }
128
128
  headers: { Location: destination }
129
129
  });
130
130
  }
131
- /**
132
- * Compare a `getStaticPaths` entry against the actual request params.
133
- *
134
- * Handles both shapes Next.js allows:
135
- * - { params: { ... } }
136
- * - "string-path"
137
- *
138
- * For a string entry, compare the entry against the current request URL using
139
- * the shared `normalizeStaticPathname` helper from
140
- * `../routing/route-pattern.ts` (which mirrors the Next.js
141
- * `removeTrailingSlash` behaviour in
142
- * `.nextjs-ref/packages/next/src/build/static-paths/pages.ts`). For an object
143
- * entry with a missing `params` key, return false rather than throwing — the
144
- * caller will respond with a 404 just like Next.js does for unlisted paths.
145
- */
146
- function matchesPagesStaticPath(pathEntry, params, routeUrl) {
131
+ function getPagesRouteParams(routePattern) {
132
+ return routePattern.split("/").map((segment) => {
133
+ const optionalCatchAll = segment.match(/^\[\[\.\.\.(.+)\]\]$/);
134
+ if (optionalCatchAll) return {
135
+ key: optionalCatchAll[1],
136
+ repeat: true,
137
+ optional: true
138
+ };
139
+ const requiredCatchAll = segment.match(/^\[\.\.\.(.+)\]$/);
140
+ if (requiredCatchAll) return {
141
+ key: requiredCatchAll[1],
142
+ repeat: true,
143
+ optional: false
144
+ };
145
+ const dynamic = segment.match(/^\[(.+)\]$/);
146
+ if (dynamic) return {
147
+ key: dynamic[1],
148
+ repeat: false,
149
+ optional: false
150
+ };
151
+ return null;
152
+ }).filter((param) => param !== null);
153
+ }
154
+ function matchesPagesStaticPath(pathEntry, params, routeParams, routeUrl) {
147
155
  if (typeof pathEntry === "string") return normalizeStaticPathname(pathEntry) === normalizeStaticPathname(routeUrl);
148
156
  const entryParams = pathEntry.params;
149
157
  if (entryParams === void 0 || entryParams === null) return false;
150
- return Object.entries(entryParams).every(([key, value]) => {
158
+ return routeParams.every(({ key, repeat, optional }) => {
159
+ if (!Object.hasOwn(entryParams, key)) return false;
160
+ let value = entryParams[key];
161
+ if (optional && (value === null || value === void 0 || value === false)) value = [];
162
+ if (repeat) {
163
+ if (!Array.isArray(value) || !optional && value.length === 0) return false;
164
+ } else if (typeof value !== "string") return false;
151
165
  const actual = params[key];
152
- if (Array.isArray(value)) return Array.isArray(actual) && value.join("/") === actual.join("/");
166
+ if (Array.isArray(value)) {
167
+ if (optional && value.length === 0 && actual === void 0) return true;
168
+ return Array.isArray(actual) && value.join("/") === actual.join("/");
169
+ }
153
170
  return String(value) === String(actual);
154
171
  });
155
172
  }
@@ -237,7 +254,9 @@ async function resolvePagesPageData(options) {
237
254
  defaultLocale: options.i18n.defaultLocale ?? ""
238
255
  });
239
256
  const fallback = pathsResult?.fallback ?? false;
240
- const isValidPath = (pathsResult?.paths ?? []).some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, options.routeUrl));
257
+ const paths = pathsResult?.paths ?? [];
258
+ const routeParams = getPagesRouteParams(options.routePattern);
259
+ const isValidPath = paths.some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, routeParams, options.routeUrl));
241
260
  if (fallback === false && !isValidPath) return buildPagesNotFoundResult(options);
242
261
  const isBotRequest = !!options.userAgent && isBotUserAgent(options.userAgent, options.htmlLimitedBots);
243
262
  if (fallback === true && !isValidPath && !options.isDataReq && !isBotRequest) isFallback = true;
@@ -245,6 +264,12 @@ async function resolvePagesPageData(options) {
245
264
  }
246
265
  let pageProps = {};
247
266
  let gsspRes = null;
267
+ const previewData = options.isOnDemandRevalidate ? false : options.previewData ?? false;
268
+ const previewContext = previewData === false ? {} : {
269
+ draftMode: true,
270
+ preview: true,
271
+ previewData
272
+ };
248
273
  let sharedReqRes = null;
249
274
  function getSharedReqRes() {
250
275
  sharedReqRes ??= options.createGsspReqRes();
@@ -273,6 +298,7 @@ async function resolvePagesPageData(options) {
273
298
  };
274
299
  return {
275
300
  kind: "render",
301
+ documentReqRes: sharedReqRes,
276
302
  gsspRes: null,
277
303
  isrRevalidateSeconds: null,
278
304
  pageProps,
@@ -297,7 +323,8 @@ async function resolvePagesPageData(options) {
297
323
  resolvedUrl: options.resolvedUrl ?? options.routeUrl,
298
324
  locale: options.i18n.locale,
299
325
  locales: options.i18n.locales,
300
- defaultLocale: options.i18n.defaultLocale
326
+ defaultLocale: options.i18n.defaultLocale,
327
+ ...previewContext
301
328
  });
302
329
  if (isResponseSent(res)) return {
303
330
  kind: "response",
@@ -318,7 +345,7 @@ async function resolvePagesPageData(options) {
318
345
  response: buildPagesRedirectResponse(result.redirect, options, renderProps)
319
346
  };
320
347
  if (result?.notFound) return buildPagesNotFoundResult(options);
321
- if (result?.props !== void 0) isSerializableProps(options.routePattern, "getServerSideProps", pageProps);
348
+ if (result?.props !== void 0 && options.validatePropsSerialization !== false) isSerializableProps(options.routePattern, "getServerSideProps", pageProps);
322
349
  gsspRes = res;
323
350
  }
324
351
  let isrRevalidateSeconds = null;
@@ -327,7 +354,7 @@ async function resolvePagesPageData(options) {
327
354
  const cacheKey = options.isrCacheKey("pages", pathname);
328
355
  const cached = await options.isrGet(cacheKey);
329
356
  const cachedValue = cached?.value.value;
330
- if (!options.isOnDemandRevalidate && cached?.isStale === false && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && !cached.isStale && !options.scriptNonce && !options.isDataReq) {
357
+ if (!options.isOnDemandRevalidate && cached?.isStale === false && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && !cached.isStale && !options.scriptNonce && !options.isDataReq && previewData === false) {
331
358
  const hitResponse = buildPagesCacheResponse(cachedValue.html, "HIT", options.fontLinkHeader, void 0, options.expireSeconds, cached.value.cacheControl, cachedValue.status);
332
359
  const hitBotResult = applyBotETagAndCheck(hitResponse, cachedValue.html, options);
333
360
  if (hitBotResult) return hitBotResult;
@@ -336,7 +363,7 @@ async function resolvePagesPageData(options) {
336
363
  response: hitResponse
337
364
  };
338
365
  }
339
- if (!options.isOnDemandRevalidate && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && cached.isStale && !options.scriptNonce && !options.isDataReq) {
366
+ if (!options.isOnDemandRevalidate && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && cached.isStale && !options.scriptNonce && !options.isDataReq && previewData === false) {
340
367
  options.triggerBackgroundRegeneration(cacheKey, async function() {
341
368
  return options.runInFreshUnifiedContext(async () => {
342
369
  options.applyRequestContexts();
@@ -393,7 +420,7 @@ async function resolvePagesPageData(options) {
393
420
  response: staleResponse
394
421
  };
395
422
  }
396
- const generatedPageData = !options.isOnDemandRevalidate && cached?.isStale === false && cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest && isUnknownRecord(cachedValue.pageData) ? cachedValue.pageData : null;
423
+ const generatedPageData = !options.isOnDemandRevalidate && previewData === false && cached?.isStale === false && cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest && isUnknownRecord(cachedValue.pageData) ? cachedValue.pageData : null;
397
424
  if (!generatedPageData) {
398
425
  const shortCircuit = await loadForegroundAppInitialRenderProps();
399
426
  if (shortCircuit) return shortCircuit;
@@ -403,6 +430,7 @@ async function resolvePagesPageData(options) {
403
430
  locale: options.i18n.locale,
404
431
  locales: options.i18n.locales,
405
432
  defaultLocale: options.i18n.defaultLocale,
433
+ ...previewContext,
406
434
  revalidateReason: options.isOnDemandRevalidate ? "on-demand" : options.isBuildTimePrerendering ? "build" : "stale"
407
435
  });
408
436
  if (generatedPageData) {
@@ -424,10 +452,10 @@ async function resolvePagesPageData(options) {
424
452
  response: buildPagesRedirectResponse(result.redirect, options, renderProps)
425
453
  };
426
454
  if (result?.notFound) return buildPagesNotFoundResult(options);
427
- if (result?.props !== void 0) isSerializableProps(options.routePattern, "getStaticProps", pageProps);
428
- if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
429
- else if (cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest) isrRevalidateSeconds = cached?.value.cacheControl?.revalidate ?? 31536e3;
430
- if (shouldPersistFallbackData) {
455
+ if (result?.props !== void 0 && options.validatePropsSerialization !== false) isSerializableProps(options.routePattern, "getStaticProps", pageProps);
456
+ if (previewData === false && typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
457
+ else if (previewData === false && cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest) isrRevalidateSeconds = cached?.value.cacheControl?.revalidate ?? 31536e3;
458
+ if (shouldPersistFallbackData && previewData === false) {
431
459
  const revalidateSeconds = isrRevalidateSeconds ?? 31536e3;
432
460
  await options.isrSet(cacheKey, {
433
461
  kind: "PAGES",
@@ -473,6 +501,7 @@ async function resolvePagesPageData(options) {
473
501
  }
474
502
  return {
475
503
  kind: "render",
504
+ documentReqRes: sharedReqRes,
476
505
  gsspRes,
477
506
  isrRevalidateSeconds,
478
507
  pageProps,
@@ -481,4 +510,4 @@ async function resolvePagesPageData(options) {
481
510
  };
482
511
  }
483
512
  //#endregion
484
- export { renderPagesIsrHtml, resolvePagesPageData };
513
+ export { getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
@@ -35,6 +35,7 @@ type VinextConfigSubset = {
35
35
  clientTraceMetadata?: readonly string[];
36
36
  disableOptimizedLoading: boolean;
37
37
  };
38
+ declare function shouldEmitPagesClientTraceMetadata(pageModule: PagesPageModule, appComponent: unknown): boolean;
38
39
  /**
39
40
  * Options accepted by `createPagesPageHandler`.
40
41
  *
@@ -97,4 +98,4 @@ type RenderPageOptions = {
97
98
  */
98
99
  declare function createPagesPageHandler(opts: CreatePagesPageHandlerOptions): (request: Request, url: string, manifest: Record<string, string[]> | null | undefined, middlewareHeaders: Headers | null | undefined, options: RenderPageOptions | null | undefined) => Promise<Response>;
99
100
  //#endregion
100
- export { CreatePagesPageHandlerOptions, createPagesPageHandler };
101
+ export { CreatePagesPageHandlerOptions, createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
@@ -3,8 +3,8 @@ import { patternToNextFormat } from "../routing/route-validation.js";
3
3
  import { getRequestExecutionContext } from "../shims/request-context.js";
4
4
  import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
5
5
  import { reportRequestError } from "./instrumentation.js";
6
- import { NEVER_CACHE_CONTROL } from "./cache-control.js";
7
- import "./isr-decision.js";
6
+ import { BROWSER_REVALIDATE_CACHE_CONTROL, NEVER_CACHE_CONTROL, applyCdnResponseHeaders, shouldUseNextDeployCacheControl } from "./cache-control.js";
7
+ import { buildMissIsrCacheControl } from "./isr-decision.js";
8
8
  import { PRERENDER_REVALIDATE_HEADER, isOnDemandRevalidateRequest, isrCacheKey, isrGet, isrSet, triggerBackgroundRegeneration } from "./isr-cache.js";
9
9
  import { ensureFetchPatch } from "../shims/fetch-cache.js";
10
10
  import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
@@ -14,12 +14,18 @@ import { resolvePagesI18nRequest } from "./pages-i18n.js";
14
14
  import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
15
15
  import { buildPagesReadinessNextData } from "./pages-readiness.js";
16
16
  import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
17
- import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
18
- import { createPagesReqRes } from "./pages-node-compat.js";
19
- import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
20
17
  import { renderPagesPageResponse } from "./pages-page-response.js";
18
+ import { hasPagesGetInitialProps } from "./pages-get-initial-props.js";
19
+ import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
21
20
  import { resolvePagesPageData } from "./pages-page-data.js";
21
+ import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
22
+ import { createPagesReqRes, getPagesPreviewData } from "./pages-node-compat.js";
22
23
  //#region src/server/pages-page-handler.ts
24
+ function shouldEmitPagesClientTraceMetadata(pageModule, appComponent) {
25
+ if (typeof pageModule.getServerSideProps === "function") return true;
26
+ if (typeof pageModule.getStaticProps === "function") return false;
27
+ return hasPagesGetInitialProps(pageModule.default) || hasPagesGetInitialProps(appComponent);
28
+ }
23
29
  function buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales) {
24
30
  return {
25
31
  locale,
@@ -55,7 +61,7 @@ function createPagesPageHandler(opts) {
55
61
  const originalRequestPathAndSearch = originalRequestUrl.pathname + originalRequestUrl.search;
56
62
  let dataRequestPathname = null;
57
63
  let dataRequestSearch = "";
58
- const initialDataNorm = normalizePagesDataRequest(request, buildId);
64
+ const initialDataNorm = normalizePagesDataRequest(request, buildId, vinextConfig.basePath, hasMiddleware && vinextConfig.trailingSlash);
59
65
  if (!isDataReq) {
60
66
  if (initialDataNorm.notFoundResponse) return initialDataNorm.notFoundResponse;
61
67
  if (initialDataNorm.isDataReq) {
@@ -127,6 +133,7 @@ function createPagesPageHandler(opts) {
127
133
  const renderStatusCode = renderStatusCodeOverride ?? (routePattern === "/404" ? 404 : void 0);
128
134
  const query = mergeRouteParamsIntoQuery(parseQueryString(routeUrl), params);
129
135
  const pageModule = route.module;
136
+ const isStaticPropsRoute = typeof pageModule.getStaticProps === "function";
130
137
  const pagesNextData = buildPagesReadinessNextData({
131
138
  pageModule,
132
139
  appComponent: AppComponent,
@@ -171,7 +178,8 @@ function createPagesPageHandler(opts) {
171
178
  ...pagesNextData.__vinext,
172
179
  pageModuleUrl,
173
180
  appModuleUrl,
174
- hasMiddleware
181
+ hasMiddleware,
182
+ routeUrl
175
183
  }
176
184
  };
177
185
  const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareHeaders);
@@ -182,6 +190,13 @@ function createPagesPageHandler(opts) {
182
190
  if (allFontPreloads.length > 0) fontLinkHeader = allFontPreloads.map((p) => "<" + appendAssetDeploymentIdQuery(p.href) + ">; rel=preload; as=font; type=" + p.type + "; crossorigin").join(", ");
183
191
  } catch {}
184
192
  const pagesResolvedUrl = (new URL(routeUrl, originalRequestUrl).pathname || "/") + originalRequestUrl.search;
193
+ const createPageReqRes = () => createPagesReqRes({
194
+ body: void 0,
195
+ query,
196
+ request,
197
+ url: originalRequestPathAndSearch
198
+ });
199
+ const isOnDemandRevalidate = isOnDemandRevalidateRequest(request.headers.get(PRERENDER_REVALIDATE_HEADER));
185
200
  const pageDataResult = await resolvePagesPageData({
186
201
  isDataReq,
187
202
  err: err instanceof Error ? err : void 0,
@@ -189,14 +204,7 @@ function createPagesPageHandler(opts) {
189
204
  buildId,
190
205
  deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
191
206
  htmlLimitedBots: vinextConfig.htmlLimitedBots,
192
- createGsspReqRes() {
193
- return createPagesReqRes({
194
- body: void 0,
195
- query,
196
- request,
197
- url: originalRequestPathAndSearch
198
- });
199
- },
207
+ createGsspReqRes: createPageReqRes,
200
208
  createAppTree(appTreeProps) {
201
209
  const el = createPageElement(PageComponent, AppComponent, appTreeProps);
202
210
  return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
@@ -212,7 +220,9 @@ function createPagesPageHandler(opts) {
212
220
  isrSet,
213
221
  expireSeconds: vinextConfig.expireTime,
214
222
  isBuildTimePrerendering: typeof process !== "undefined" && process.env && process.env.VINEXT_PRERENDER === "1",
215
- isOnDemandRevalidate: isOnDemandRevalidateRequest(request.headers.get(PRERENDER_REVALIDATE_HEADER)),
223
+ validatePropsSerialization: process.env.NODE_ENV !== "production" || process.env.VINEXT_PRERENDER === "1",
224
+ isOnDemandRevalidate,
225
+ previewData: getPagesPreviewData(request, { isOnDemandRevalidate }),
216
226
  pageModule,
217
227
  AppComponent,
218
228
  params,
@@ -264,6 +274,7 @@ function createPagesPageHandler(opts) {
264
274
  };
265
275
  }
266
276
  const gsspRes = pageDataResult.gsspRes;
277
+ const documentReqRes = serializedPagesNextData.autoExport === true ? null : pageDataResult.documentReqRes ?? createPageReqRes();
267
278
  const isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;
268
279
  const isFallbackRender = pageDataResult.isFallback === true;
269
280
  if (isFallbackRender && typeof setSSRContext === "function") setSSRContext({
@@ -294,6 +305,12 @@ function createPagesPageHandler(opts) {
294
305
  break;
295
306
  }
296
307
  if (!hasUserCacheControl) init.headers["Cache-Control"] = NEVER_CACHE_CONTROL;
308
+ } else if (isStaticPropsRoute) {
309
+ if (isrRevalidateSeconds) {
310
+ const headers = new Headers(init.headers);
311
+ applyCdnResponseHeaders(headers, { cacheControl: buildMissIsrCacheControl(isrRevalidateSeconds, vinextConfig.expireTime) });
312
+ for (const [key, value] of headers) init.headers[key] = value;
313
+ } else if (shouldUseNextDeployCacheControl()) init.headers["Cache-Control"] = BROWSER_REVALIDATE_CACHE_CONTROL;
297
314
  }
298
315
  if (routePattern !== "/_error" && routePattern !== "/500") {
299
316
  const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
@@ -302,8 +319,8 @@ function createPagesPageHandler(opts) {
302
319
  return buildNextDataPropsJsonResponse(renderProps, safeJsonStringify, init);
303
320
  }
304
321
  const pageModuleIds = [];
305
- if (route.filePath) pageModuleIds.push(route.filePath);
306
322
  if (appAssetPath) pageModuleIds.push(appAssetPath);
323
+ if (route.filePath) pageModuleIds.push(route.filePath);
307
324
  return await renderPagesPageResponse({
308
325
  assetTags: collectAssetTags({
309
326
  manifest,
@@ -334,11 +351,13 @@ function createPagesPageHandler(opts) {
334
351
  getFontLinks,
335
352
  getFontStyles,
336
353
  getSSRHeadHTML: typeof getSSRHeadHTML === "function" ? getSSRHeadHTML : void 0,
337
- clientTraceMetadata: vinextConfig.clientTraceMetadata,
354
+ clientTraceMetadata: shouldEmitPagesClientTraceMetadata(pageModule, AppComponent) ? vinextConfig.clientTraceMetadata : void 0,
355
+ documentReqRes,
338
356
  gsspRes,
339
357
  isrCacheKey: pageIsrCacheKey,
340
358
  expireSeconds: vinextConfig.expireTime,
341
359
  isrRevalidateSeconds,
360
+ isStaticPropsRoute,
342
361
  isrSet,
343
362
  i18n: buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales),
344
363
  isFallback: isFallbackRender,
@@ -400,4 +419,4 @@ function createPagesPageHandler(opts) {
400
419
  return renderPage;
401
420
  }
402
421
  //#endregion
403
- export { createPagesPageHandler };
422
+ export { createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
@@ -45,9 +45,15 @@ type PagesI18nRenderContext = {
45
45
  domainLocales?: unknown;
46
46
  };
47
47
  type PagesGsspResponse = {
48
+ headersSent?: boolean;
48
49
  statusCode: number;
49
50
  getHeaders(): Record<string, string | number | boolean | string[]>;
50
51
  };
52
+ type PagesDocumentReqRes = {
53
+ req: unknown;
54
+ res: PagesGsspResponse;
55
+ responsePromise?: Promise<Response>;
56
+ };
51
57
  type RenderPagesPageResponseOptions = {
52
58
  assetTags: string;
53
59
  buildId: string | null;
@@ -80,10 +86,12 @@ type RenderPagesPageResponseOptions = {
80
86
  */
81
87
  clientTraceMetadata?: readonly string[] | undefined;
82
88
  setDocumentInitialHead?: ((head: ReactNode[]) => void) | undefined;
89
+ documentReqRes?: PagesDocumentReqRes | null;
83
90
  gsspRes: PagesGsspResponse | null;
84
91
  isrCacheKey: (router: string, pathname: string) => string;
85
92
  expireSeconds?: number;
86
93
  isrRevalidateSeconds: number | null;
94
+ isStaticPropsRoute?: boolean;
87
95
  isrSet: (key: string, data: CachedPagesValue, revalidateSeconds: number, tags?: string[], expireSeconds?: number) => Promise<void>;
88
96
  i18n: PagesI18nRenderContext;
89
97
  /**
@@ -1,7 +1,7 @@
1
1
  import { getRequestExecutionContext } from "../shims/request-context.js";
2
2
  import { reportRequestError } from "./instrumentation.js";
3
3
  import { setCacheStateHeaders } from "./cache-headers.js";
4
- import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
4
+ import { BROWSER_REVALIDATE_CACHE_CONTROL, NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, shouldUseNextDeployCacheControl } from "./cache-control.js";
5
5
  import { buildMissIsrCacheControl } from "./isr-decision.js";
6
6
  import { fnv1a52 } from "../utils/hash.js";
7
7
  import { encodeCacheTag } from "../utils/encode-cache-tag.js";
@@ -197,11 +197,14 @@ async function renderPagesPageResponse(options) {
197
197
  scriptNonce: options.scriptNonce,
198
198
  context: {
199
199
  err: options.err,
200
+ req: options.documentReqRes?.req,
201
+ res: options.documentReqRes?.res,
200
202
  pathname: options.routePattern,
201
203
  query: options.query ?? options.params,
202
204
  asPath: options.routeUrl
203
205
  }
204
206
  });
207
+ if (options.documentReqRes?.res.headersSent && options.documentReqRes.responsePromise) return options.documentReqRes.responsePromise;
205
208
  let bodyStream;
206
209
  if (documentRenderPage.status === "rendered") bodyStream = new ReadableStream({ start(controller) {
207
210
  controller.enqueue(new TextEncoder().encode(documentRenderPage.bodyHtml));
@@ -230,7 +233,7 @@ async function renderPagesPageResponse(options) {
230
233
  const shellPrefix = shellHtml.slice(0, markerIndex);
231
234
  const shellSuffix = shellHtml.slice(markerIndex + 25);
232
235
  const responseHeaders = new Headers({ "Content-Type": "text/html" });
233
- const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes, options.statusCode);
236
+ const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes ?? options.documentReqRes?.res ?? null, options.statusCode);
234
237
  let responseBodyStream = bodyStream;
235
238
  if (!options.scriptNonce && options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {
236
239
  const cacheBodyStreamPair = bodyStream.tee();
@@ -261,7 +264,8 @@ async function renderPagesPageResponse(options) {
261
264
  tags: [encodeCacheTag(`_N_T_${stem || "/"}`)]
262
265
  });
263
266
  setCacheStateHeaders(responseHeaders, "MISS");
264
- } else if (options.gsspRes && !userSetCacheControl) responseHeaders.set("Cache-Control", NEVER_CACHE_CONTROL);
267
+ } else if (options.isStaticPropsRoute && shouldUseNextDeployCacheControl()) responseHeaders.set("Cache-Control", BROWSER_REVALIDATE_CACHE_CONTROL);
268
+ else if (options.gsspRes && !userSetCacheControl) responseHeaders.set("Cache-Control", NEVER_CACHE_CONTROL);
265
269
  if (options.fontLinkHeader) responseHeaders.set("Link", options.fontLinkHeader);
266
270
  if (options.userAgent && isPagesStreamingBot(options.userAgent)) {
267
271
  const fullHtml = await readStreamAsText(compositeStream);
@@ -8,6 +8,13 @@ type PagesRenderOptions = {
8
8
  originalUrl?: string;
9
9
  };
10
10
  type FilesystemRoutePhase = "direct" | "beforeFiles" | "afterFiles" | "fallback";
11
+ type PageRouteMatch = {
12
+ route: {
13
+ isDynamic: boolean;
14
+ pattern?: string;
15
+ dataKind?: "static" | "server" | "none";
16
+ };
17
+ };
11
18
  declare function fetchWorkerFilesystemRoute(request: Request, requestPathname: string, phase: FilesystemRoutePhase, fetchAsset: (request: Request) => Promise<Response>): Promise<Response | false>;
12
19
  type MiddlewareResult = {
13
20
  continue: boolean;
@@ -34,13 +41,10 @@ type PagesPipelineDeps = {
34
41
  hadBasePath: boolean;
35
42
  isDataReq: boolean;
36
43
  isDataRequest: boolean;
44
+ hasMiddleware: boolean;
37
45
  ctx?: unknown;
38
46
  rawSearch?: string;
39
- matchPageRoute?: ((pathname: string, request: Request) => {
40
- route: {
41
- isDynamic: boolean;
42
- };
43
- } | null) | null;
47
+ matchPageRoute?: ((pathname: string, request: Request) => PageRouteMatch | null) | null;
44
48
  runMiddleware?: ((request: Request, ctx: unknown, opts: {
45
49
  isDataRequest: boolean;
46
50
  }) => Promise<MiddlewareResult>) | null;