vinext 0.0.52 → 0.0.54

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 (330) hide show
  1. package/README.md +1 -1
  2. package/dist/build/clean-output.d.ts +14 -0
  3. package/dist/build/clean-output.js +36 -0
  4. package/dist/build/clean-output.js.map +1 -0
  5. package/dist/build/inline-css.d.ts +7 -0
  6. package/dist/build/inline-css.js +50 -0
  7. package/dist/build/inline-css.js.map +1 -0
  8. package/dist/build/prerender.d.ts +6 -2
  9. package/dist/build/prerender.js +51 -12
  10. package/dist/build/prerender.js.map +1 -1
  11. package/dist/build/run-prerender.js +10 -1
  12. package/dist/build/run-prerender.js.map +1 -1
  13. package/dist/build/static-export.d.ts +5 -0
  14. package/dist/build/static-export.js +8 -3
  15. package/dist/build/static-export.js.map +1 -1
  16. package/dist/check.js +4 -0
  17. package/dist/check.js.map +1 -1
  18. package/dist/cli.js +19 -4
  19. package/dist/cli.js.map +1 -1
  20. package/dist/client/instrumentation-client-inject.d.ts +34 -0
  21. package/dist/client/instrumentation-client-inject.js +57 -0
  22. package/dist/client/instrumentation-client-inject.js.map +1 -0
  23. package/dist/client/navigation-runtime.d.ts +16 -2
  24. package/dist/client/navigation-runtime.js +16 -1
  25. package/dist/client/navigation-runtime.js.map +1 -1
  26. package/dist/client/vinext-next-data.d.ts +2 -1
  27. package/dist/client/vinext-next-data.js.map +1 -1
  28. package/dist/client/window-next.d.ts +17 -2
  29. package/dist/client/window-next.js.map +1 -1
  30. package/dist/cloudflare/tpr.js +1 -1
  31. package/dist/cloudflare/tpr.js.map +1 -1
  32. package/dist/config/config-matchers.js +2 -1
  33. package/dist/config/config-matchers.js.map +1 -1
  34. package/dist/config/next-config.d.ts +95 -4
  35. package/dist/config/next-config.js +173 -14
  36. package/dist/config/next-config.js.map +1 -1
  37. package/dist/deploy.js +42 -7
  38. package/dist/deploy.js.map +1 -1
  39. package/dist/entries/app-browser-entry.d.ts +11 -1
  40. package/dist/entries/app-browser-entry.js +16 -6
  41. package/dist/entries/app-browser-entry.js.map +1 -1
  42. package/dist/entries/app-rsc-entry.d.ts +12 -3
  43. package/dist/entries/app-rsc-entry.js +41 -8
  44. package/dist/entries/app-rsc-entry.js.map +1 -1
  45. package/dist/entries/app-rsc-manifest.d.ts +21 -1
  46. package/dist/entries/app-rsc-manifest.js +6 -4
  47. package/dist/entries/app-rsc-manifest.js.map +1 -1
  48. package/dist/entries/pages-client-entry.d.ts +4 -1
  49. package/dist/entries/pages-client-entry.js +40 -3
  50. package/dist/entries/pages-client-entry.js.map +1 -1
  51. package/dist/entries/pages-server-entry.js +292 -34
  52. package/dist/entries/pages-server-entry.js.map +1 -1
  53. package/dist/entries/runtime-entry-module.d.ts +1 -10
  54. package/dist/entries/runtime-entry-module.js +2 -12
  55. package/dist/entries/runtime-entry-module.js.map +1 -1
  56. package/dist/index.js +91 -10
  57. package/dist/index.js.map +1 -1
  58. package/dist/plugins/fonts.js +25 -2
  59. package/dist/plugins/fonts.js.map +1 -1
  60. package/dist/plugins/remove-console.d.ts +16 -0
  61. package/dist/plugins/remove-console.js +176 -0
  62. package/dist/plugins/remove-console.js.map +1 -0
  63. package/dist/routing/app-route-graph.d.ts +24 -1
  64. package/dist/routing/app-route-graph.js +52 -4
  65. package/dist/routing/app-route-graph.js.map +1 -1
  66. package/dist/routing/app-router.d.ts +2 -2
  67. package/dist/routing/app-router.js +2 -2
  68. package/dist/routing/app-router.js.map +1 -1
  69. package/dist/routing/file-matcher.d.ts +21 -1
  70. package/dist/routing/file-matcher.js +39 -1
  71. package/dist/routing/file-matcher.js.map +1 -1
  72. package/dist/routing/pages-router.d.ts +1 -1
  73. package/dist/routing/pages-router.js +10 -3
  74. package/dist/routing/pages-router.js.map +1 -1
  75. package/dist/routing/route-trie.js +13 -18
  76. package/dist/routing/route-trie.js.map +1 -1
  77. package/dist/routing/utils.d.ts +11 -1
  78. package/dist/routing/utils.js +15 -1
  79. package/dist/routing/utils.js.map +1 -1
  80. package/dist/server/api-handler.js +19 -10
  81. package/dist/server/api-handler.js.map +1 -1
  82. package/dist/server/app-browser-action-result.d.ts +16 -1
  83. package/dist/server/app-browser-action-result.js +15 -1
  84. package/dist/server/app-browser-action-result.js.map +1 -1
  85. package/dist/server/app-browser-entry.js +47 -28
  86. package/dist/server/app-browser-entry.js.map +1 -1
  87. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  88. package/dist/server/app-browser-navigation-controller.js +4 -0
  89. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  90. package/dist/server/app-elements-wire.d.ts +13 -4
  91. package/dist/server/app-elements-wire.js +10 -1
  92. package/dist/server/app-elements-wire.js.map +1 -1
  93. package/dist/server/app-elements.d.ts +2 -2
  94. package/dist/server/app-elements.js +2 -2
  95. package/dist/server/app-elements.js.map +1 -1
  96. package/dist/server/app-fallback-renderer.d.ts +27 -8
  97. package/dist/server/app-fallback-renderer.js +19 -8
  98. package/dist/server/app-fallback-renderer.js.map +1 -1
  99. package/dist/server/app-history-state.js +6 -2
  100. package/dist/server/app-history-state.js.map +1 -1
  101. package/dist/server/app-inline-css-client.d.ts +7 -0
  102. package/dist/server/app-inline-css-client.js +37 -0
  103. package/dist/server/app-inline-css-client.js.map +1 -0
  104. package/dist/server/app-interception-context-header.d.ts +33 -0
  105. package/dist/server/app-interception-context-header.js +44 -0
  106. package/dist/server/app-interception-context-header.js.map +1 -0
  107. package/dist/server/app-mounted-slots-header.d.ts +19 -0
  108. package/dist/server/app-mounted-slots-header.js +40 -1
  109. package/dist/server/app-mounted-slots-header.js.map +1 -1
  110. package/dist/server/app-optimistic-routing.js +26 -18
  111. package/dist/server/app-optimistic-routing.js.map +1 -1
  112. package/dist/server/app-page-boundary-render.d.ts +1 -0
  113. package/dist/server/app-page-boundary-render.js +2 -0
  114. package/dist/server/app-page-boundary-render.js.map +1 -1
  115. package/dist/server/app-page-boundary.d.ts +22 -1
  116. package/dist/server/app-page-boundary.js +30 -3
  117. package/dist/server/app-page-boundary.js.map +1 -1
  118. package/dist/server/app-page-cache.d.ts +9 -3
  119. package/dist/server/app-page-cache.js +14 -8
  120. package/dist/server/app-page-cache.js.map +1 -1
  121. package/dist/server/app-page-dispatch.d.ts +13 -1
  122. package/dist/server/app-page-dispatch.js +136 -82
  123. package/dist/server/app-page-dispatch.js.map +1 -1
  124. package/dist/server/app-page-element-builder.d.ts +2 -1
  125. package/dist/server/app-page-element-builder.js +17 -30
  126. package/dist/server/app-page-element-builder.js.map +1 -1
  127. package/dist/server/app-page-execution.d.ts +1 -0
  128. package/dist/server/app-page-execution.js +2 -0
  129. package/dist/server/app-page-execution.js.map +1 -1
  130. package/dist/server/app-page-head.d.ts +1 -0
  131. package/dist/server/app-page-head.js +8 -0
  132. package/dist/server/app-page-head.js.map +1 -1
  133. package/dist/server/app-page-render-identity.d.ts +22 -0
  134. package/dist/server/app-page-render-identity.js +42 -0
  135. package/dist/server/app-page-render-identity.js.map +1 -0
  136. package/dist/server/app-page-render-observation.js +1 -1
  137. package/dist/server/app-page-render.d.ts +9 -1
  138. package/dist/server/app-page-render.js +8 -2
  139. package/dist/server/app-page-render.js.map +1 -1
  140. package/dist/server/app-page-request.d.ts +6 -3
  141. package/dist/server/app-page-request.js +5 -2
  142. package/dist/server/app-page-request.js.map +1 -1
  143. package/dist/server/app-page-response.d.ts +11 -1
  144. package/dist/server/app-page-response.js +16 -4
  145. package/dist/server/app-page-response.js.map +1 -1
  146. package/dist/server/app-page-route-wiring.d.ts +16 -0
  147. package/dist/server/app-page-route-wiring.js +25 -10
  148. package/dist/server/app-page-route-wiring.js.map +1 -1
  149. package/dist/server/app-page-stream.d.ts +12 -0
  150. package/dist/server/app-page-stream.js +3 -0
  151. package/dist/server/app-page-stream.js.map +1 -1
  152. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  153. package/dist/server/app-route-handler-dispatch.js +3 -0
  154. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  155. package/dist/server/app-route-handler-execution.d.ts +1 -0
  156. package/dist/server/app-route-handler-execution.js +1 -0
  157. package/dist/server/app-route-handler-execution.js.map +1 -1
  158. package/dist/server/app-route-handler-response.js +38 -6
  159. package/dist/server/app-route-handler-response.js.map +1 -1
  160. package/dist/server/app-rsc-handler.d.ts +16 -3
  161. package/dist/server/app-rsc-handler.js +60 -11
  162. package/dist/server/app-rsc-handler.js.map +1 -1
  163. package/dist/server/app-rsc-request-normalization.d.ts +2 -1
  164. package/dist/server/app-rsc-request-normalization.js +6 -4
  165. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  166. package/dist/server/app-segment-config.d.ts +4 -1
  167. package/dist/server/app-segment-config.js +6 -1
  168. package/dist/server/app-segment-config.js.map +1 -1
  169. package/dist/server/app-server-action-execution.d.ts +22 -3
  170. package/dist/server/app-server-action-execution.js +46 -7
  171. package/dist/server/app-server-action-execution.js.map +1 -1
  172. package/dist/server/app-ssr-entry.d.ts +6 -0
  173. package/dist/server/app-ssr-entry.js +57 -6
  174. package/dist/server/app-ssr-entry.js.map +1 -1
  175. package/dist/server/app-ssr-error-meta.js +3 -3
  176. package/dist/server/app-ssr-error-meta.js.map +1 -1
  177. package/dist/server/app-ssr-stream.d.ts +25 -1
  178. package/dist/server/app-ssr-stream.js +237 -19
  179. package/dist/server/app-ssr-stream.js.map +1 -1
  180. package/dist/server/app-static-generation.d.ts +1 -0
  181. package/dist/server/app-static-generation.js +2 -1
  182. package/dist/server/app-static-generation.js.map +1 -1
  183. package/dist/server/client-trace-metadata.d.ts +31 -0
  184. package/dist/server/client-trace-metadata.js +83 -0
  185. package/dist/server/client-trace-metadata.js.map +1 -0
  186. package/dist/server/cookie-utils.d.ts +13 -0
  187. package/dist/server/cookie-utils.js +20 -0
  188. package/dist/server/cookie-utils.js.map +1 -0
  189. package/dist/server/default-not-found-module.d.ts +20 -0
  190. package/dist/server/default-not-found-module.js +20 -0
  191. package/dist/server/default-not-found-module.js.map +1 -0
  192. package/dist/server/dev-server.d.ts +8 -1
  193. package/dist/server/dev-server.js +56 -11
  194. package/dist/server/dev-server.js.map +1 -1
  195. package/dist/server/headers.d.ts +5 -1
  196. package/dist/server/headers.js +5 -1
  197. package/dist/server/headers.js.map +1 -1
  198. package/dist/server/html.d.ts +2 -1
  199. package/dist/server/html.js +6 -1
  200. package/dist/server/html.js.map +1 -1
  201. package/dist/server/image-optimization.d.ts +13 -4
  202. package/dist/server/image-optimization.js +15 -4
  203. package/dist/server/image-optimization.js.map +1 -1
  204. package/dist/server/isr-cache.d.ts +7 -5
  205. package/dist/server/isr-cache.js +17 -6
  206. package/dist/server/isr-cache.js.map +1 -1
  207. package/dist/server/middleware-runtime.js +1 -2
  208. package/dist/server/middleware-runtime.js.map +1 -1
  209. package/dist/server/middleware.js +1 -1
  210. package/dist/server/middleware.js.map +1 -1
  211. package/dist/server/pages-api-route.d.ts +18 -0
  212. package/dist/server/pages-api-route.js +3 -1
  213. package/dist/server/pages-api-route.js.map +1 -1
  214. package/dist/server/pages-body-parser-config.d.ts +60 -0
  215. package/dist/server/pages-body-parser-config.js +79 -0
  216. package/dist/server/pages-body-parser-config.js.map +1 -0
  217. package/dist/server/pages-data-route.js +1 -0
  218. package/dist/server/pages-data-route.js.map +1 -1
  219. package/dist/server/pages-default-404.d.ts +31 -0
  220. package/dist/server/pages-default-404.js +40 -0
  221. package/dist/server/pages-default-404.js.map +1 -0
  222. package/dist/server/pages-document-initial-props.d.ts +7 -0
  223. package/dist/server/pages-document-initial-props.js +14 -0
  224. package/dist/server/pages-document-initial-props.js.map +1 -0
  225. package/dist/server/pages-node-compat.d.ts +10 -0
  226. package/dist/server/pages-node-compat.js +12 -1
  227. package/dist/server/pages-node-compat.js.map +1 -1
  228. package/dist/server/pages-page-data.d.ts +40 -0
  229. package/dist/server/pages-page-data.js +19 -14
  230. package/dist/server/pages-page-data.js.map +1 -1
  231. package/dist/server/pages-page-method.d.ts +48 -0
  232. package/dist/server/pages-page-method.js +19 -0
  233. package/dist/server/pages-page-method.js.map +1 -0
  234. package/dist/server/pages-page-response.d.ts +8 -0
  235. package/dist/server/pages-page-response.js +21 -11
  236. package/dist/server/pages-page-response.js.map +1 -1
  237. package/dist/server/pages-serializable-props.d.ts +25 -0
  238. package/dist/server/pages-serializable-props.js +69 -0
  239. package/dist/server/pages-serializable-props.js.map +1 -0
  240. package/dist/server/prerender-route-params.d.ts +14 -0
  241. package/dist/server/prerender-route-params.js +94 -0
  242. package/dist/server/prerender-route-params.js.map +1 -0
  243. package/dist/server/prod-server.d.ts +3 -23
  244. package/dist/server/prod-server.js +43 -57
  245. package/dist/server/prod-server.js.map +1 -1
  246. package/dist/server/proxy-trust.d.ts +41 -0
  247. package/dist/server/proxy-trust.js +70 -0
  248. package/dist/server/proxy-trust.js.map +1 -0
  249. package/dist/server/request-pipeline.d.ts +3 -3
  250. package/dist/server/request-pipeline.js +5 -4
  251. package/dist/server/request-pipeline.js.map +1 -1
  252. package/dist/server/seed-cache.js +12 -6
  253. package/dist/server/seed-cache.js.map +1 -1
  254. package/dist/server/server-action-not-found.js +3 -2
  255. package/dist/server/server-action-not-found.js.map +1 -1
  256. package/dist/server/static-file-cache.js +2 -1
  257. package/dist/server/static-file-cache.js.map +1 -1
  258. package/dist/server/streaming-metadata.d.ts +5 -0
  259. package/dist/server/streaming-metadata.js +10 -0
  260. package/dist/server/streaming-metadata.js.map +1 -0
  261. package/dist/shims/app-router-scroll-state.d.ts +14 -0
  262. package/dist/shims/app-router-scroll-state.js +51 -0
  263. package/dist/shims/app-router-scroll-state.js.map +1 -0
  264. package/dist/shims/app-router-scroll.d.ts +28 -0
  265. package/dist/shims/app-router-scroll.js +115 -0
  266. package/dist/shims/app-router-scroll.js.map +1 -0
  267. package/dist/shims/before-interactive-context.d.ts +30 -0
  268. package/dist/shims/before-interactive-context.js +10 -0
  269. package/dist/shims/before-interactive-context.js.map +1 -0
  270. package/dist/shims/cache-runtime.d.ts +1 -1
  271. package/dist/shims/cache-runtime.js +14 -1
  272. package/dist/shims/cache-runtime.js.map +1 -1
  273. package/dist/shims/cache.d.ts +6 -0
  274. package/dist/shims/cache.js +7 -0
  275. package/dist/shims/cache.js.map +1 -1
  276. package/dist/shims/default-not-found.d.ts +12 -0
  277. package/dist/shims/default-not-found.js +61 -0
  278. package/dist/shims/default-not-found.js.map +1 -0
  279. package/dist/shims/error.js +3 -0
  280. package/dist/shims/error.js.map +1 -1
  281. package/dist/shims/font-local.d.ts +5 -0
  282. package/dist/shims/font-local.js +6 -2
  283. package/dist/shims/font-local.js.map +1 -1
  284. package/dist/shims/head.js +4 -4
  285. package/dist/shims/head.js.map +1 -1
  286. package/dist/shims/headers.d.ts +13 -2
  287. package/dist/shims/headers.js +73 -22
  288. package/dist/shims/headers.js.map +1 -1
  289. package/dist/shims/image.d.ts +1 -1
  290. package/dist/shims/image.js +4 -4
  291. package/dist/shims/image.js.map +1 -1
  292. package/dist/shims/internal/app-route-detection.d.ts +37 -0
  293. package/dist/shims/internal/app-route-detection.js +69 -0
  294. package/dist/shims/internal/app-route-detection.js.map +1 -0
  295. package/dist/shims/internal/pages-data-target.d.ts +58 -0
  296. package/dist/shims/internal/pages-data-target.js +91 -0
  297. package/dist/shims/internal/pages-data-target.js.map +1 -0
  298. package/dist/shims/internal/pages-data-url.d.ts +42 -0
  299. package/dist/shims/internal/pages-data-url.js +73 -0
  300. package/dist/shims/internal/pages-data-url.js.map +1 -0
  301. package/dist/shims/link.d.ts +18 -2
  302. package/dist/shims/link.js +129 -15
  303. package/dist/shims/link.js.map +1 -1
  304. package/dist/shims/metadata.d.ts +9 -7
  305. package/dist/shims/metadata.js +70 -7
  306. package/dist/shims/metadata.js.map +1 -1
  307. package/dist/shims/navigation.d.ts +1 -2
  308. package/dist/shims/navigation.js +94 -20
  309. package/dist/shims/navigation.js.map +1 -1
  310. package/dist/shims/router.d.ts +5 -0
  311. package/dist/shims/router.js +389 -80
  312. package/dist/shims/router.js.map +1 -1
  313. package/dist/shims/script.d.ts +11 -1
  314. package/dist/shims/script.js +158 -15
  315. package/dist/shims/script.js.map +1 -1
  316. package/dist/shims/server.js +1 -0
  317. package/dist/shims/server.js.map +1 -1
  318. package/dist/shims/url-utils.d.ts +2 -1
  319. package/dist/shims/url-utils.js +15 -4
  320. package/dist/shims/url-utils.js.map +1 -1
  321. package/dist/utils/html-limited-bots.d.ts +5 -0
  322. package/dist/utils/html-limited-bots.js +15 -0
  323. package/dist/utils/html-limited-bots.js.map +1 -0
  324. package/dist/utils/path.d.ts +13 -0
  325. package/dist/utils/path.js +16 -0
  326. package/dist/utils/path.js.map +1 -0
  327. package/dist/utils/query.d.ts +6 -0
  328. package/dist/utils/query.js +10 -1
  329. package/dist/utils/query.js.map +1 -1
  330. package/package.json +1 -1
@@ -0,0 +1,31 @@
1
+ //#region src/server/client-trace-metadata.d.ts
2
+ type ClientTraceDataEntry = {
3
+ key: string;
4
+ value: string;
5
+ };
6
+ /**
7
+ * Filter an entry list against the configured `clientTraceMetadata` allow-list.
8
+ * Returns `undefined` when the allow-list is unset so callers can skip
9
+ * rendering altogether.
10
+ */
11
+ declare function filterClientTraceMetadata(entries: readonly ClientTraceDataEntry[], allowList: readonly string[] | undefined): ClientTraceDataEntry[] | undefined;
12
+ /**
13
+ * Render the filtered entries as a sequence of self-closing `<meta>` tags.
14
+ * Names and values are HTML-attribute escaped. Returns an empty string when
15
+ * `entries` is empty or undefined so callers can append unconditionally.
16
+ */
17
+ declare function renderClientTraceMetadataTags(entries: readonly ClientTraceDataEntry[] | undefined): string;
18
+ /**
19
+ * Convenience helper: read OTel propagation data, filter against the
20
+ * configured allow-list, and render the resulting `<meta>` tags. Returns an
21
+ * empty string when the allow-list is unset, OTel is not installed, or no
22
+ * matching keys were emitted by the propagator.
23
+ *
24
+ * Safe to call unconditionally on every SSR render — when nothing is
25
+ * configured/active this is a few `try/catch`-bounded operations and returns
26
+ * `""`.
27
+ */
28
+ declare function getClientTraceMetadataHTML(allowList: readonly string[] | undefined): string;
29
+ //#endregion
30
+ export { ClientTraceDataEntry, filterClientTraceMetadata, getClientTraceMetadataHTML, renderClientTraceMetadataTags };
31
+ //# sourceMappingURL=client-trace-metadata.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { escapeHtmlAttr } from "./html.js";
2
+ //#region src/server/client-trace-metadata.ts
3
+ /**
4
+ * Client trace metadata renderer.
5
+ *
6
+ * When `experimental.clientTraceMetadata` is configured in `next.config`,
7
+ * vinext emits `<meta name="..." content="...">` tags in the SSR HTML head
8
+ * for each configured key. The values are sourced from the active
9
+ * OpenTelemetry context via the registered propagator.
10
+ *
11
+ * This mirrors Next.js' implementation:
12
+ * - packages/next/src/server/lib/trace/utils.ts (getTracedMetadata)
13
+ * - packages/next/src/server/app-render/make-get-server-inserted-html.tsx (traceMetaTags)
14
+ *
15
+ * OpenTelemetry is an optional peer — we resolve `@opentelemetry/api` at
16
+ * runtime and silently no-op when it is not installed. This matches user
17
+ * expectations: apps that don't configure OTel get no meta tags, and apps
18
+ * that do get the filtered subset they asked for in `clientTraceMetadata`.
19
+ */
20
+ const carrierSetter = { set(carrier, key, value) {
21
+ if (typeof key !== "string" || typeof value !== "string") return;
22
+ carrier.push({
23
+ key,
24
+ value
25
+ });
26
+ } };
27
+ function getOpenTelemetryTraceData() {
28
+ let api;
29
+ try {
30
+ const req = globalThis.require;
31
+ if (typeof req === "function") api = req("@opentelemetry/api");
32
+ } catch {
33
+ return [];
34
+ }
35
+ if (!api) return [];
36
+ try {
37
+ const activeContext = api.context.active();
38
+ const entries = [];
39
+ api.propagation.inject(activeContext, entries, carrierSetter);
40
+ return entries;
41
+ } catch {
42
+ return [];
43
+ }
44
+ }
45
+ /**
46
+ * Filter an entry list against the configured `clientTraceMetadata` allow-list.
47
+ * Returns `undefined` when the allow-list is unset so callers can skip
48
+ * rendering altogether.
49
+ */
50
+ function filterClientTraceMetadata(entries, allowList) {
51
+ if (!allowList || allowList.length === 0) return void 0;
52
+ const allowSet = new Set(allowList);
53
+ return entries.filter(({ key }) => allowSet.has(key));
54
+ }
55
+ /**
56
+ * Render the filtered entries as a sequence of self-closing `<meta>` tags.
57
+ * Names and values are HTML-attribute escaped. Returns an empty string when
58
+ * `entries` is empty or undefined so callers can append unconditionally.
59
+ */
60
+ function renderClientTraceMetadataTags(entries) {
61
+ if (!entries || entries.length === 0) return "";
62
+ let html = "";
63
+ for (const { key, value } of entries) html += `<meta name="${escapeHtmlAttr(key)}" content="${escapeHtmlAttr(value)}"/>`;
64
+ return html;
65
+ }
66
+ /**
67
+ * Convenience helper: read OTel propagation data, filter against the
68
+ * configured allow-list, and render the resulting `<meta>` tags. Returns an
69
+ * empty string when the allow-list is unset, OTel is not installed, or no
70
+ * matching keys were emitted by the propagator.
71
+ *
72
+ * Safe to call unconditionally on every SSR render — when nothing is
73
+ * configured/active this is a few `try/catch`-bounded operations and returns
74
+ * `""`.
75
+ */
76
+ function getClientTraceMetadataHTML(allowList) {
77
+ if (!allowList || allowList.length === 0) return "";
78
+ return renderClientTraceMetadataTags(filterClientTraceMetadata(getOpenTelemetryTraceData(), allowList));
79
+ }
80
+ //#endregion
81
+ export { filterClientTraceMetadata, getClientTraceMetadataHTML, renderClientTraceMetadataTags };
82
+
83
+ //# sourceMappingURL=client-trace-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-trace-metadata.js","names":[],"sources":["../../src/server/client-trace-metadata.ts"],"sourcesContent":["/**\n * Client trace metadata renderer.\n *\n * When `experimental.clientTraceMetadata` is configured in `next.config`,\n * vinext emits `<meta name=\"...\" content=\"...\">` tags in the SSR HTML head\n * for each configured key. The values are sourced from the active\n * OpenTelemetry context via the registered propagator.\n *\n * This mirrors Next.js' implementation:\n * - packages/next/src/server/lib/trace/utils.ts (getTracedMetadata)\n * - packages/next/src/server/app-render/make-get-server-inserted-html.tsx (traceMetaTags)\n *\n * OpenTelemetry is an optional peer — we resolve `@opentelemetry/api` at\n * runtime and silently no-op when it is not installed. This matches user\n * expectations: apps that don't configure OTel get no meta tags, and apps\n * that do get the filtered subset they asked for in `clientTraceMetadata`.\n */\nimport { escapeHtmlAttr } from \"./html.js\";\n\nexport type ClientTraceDataEntry = {\n key: string;\n value: string;\n};\n\ntype TextMapSetter = {\n set(carrier: ClientTraceDataEntry[], key: string, value: string): void;\n};\n\nconst carrierSetter: TextMapSetter = {\n set(carrier, key, value) {\n if (typeof key !== \"string\" || typeof value !== \"string\") return;\n carrier.push({ key, value });\n },\n};\n\n/**\n * Pull entries off the active OpenTelemetry context via the registered\n * propagator. Returns an empty array when `@opentelemetry/api` is not\n * installed or when no propagator has been registered.\n *\n * The implementation mirrors Next.js's `NextTracerImpl.getTracePropagationData`:\n * we call `propagation.inject(activeContext, entries, setter)` and let the\n * setter push entries into our carrier array.\n */\ntype OpenTelemetryApi = {\n context: { active(): unknown };\n propagation: {\n inject(context: unknown, carrier: ClientTraceDataEntry[], setter: TextMapSetter): void;\n };\n};\n\nfunction getOpenTelemetryTraceData(): ClientTraceDataEntry[] {\n let api: OpenTelemetryApi | undefined;\n try {\n // Use require() at runtime so `@opentelemetry/api` is an optional peer.\n // Bundlers (Vite/esbuild) leave the `require` reference alone, so apps\n // that don't install the package never hit this branch.\n const req = (globalThis as { require?: (id: string) => unknown }).require;\n if (typeof req === \"function\") {\n api = req(\"@opentelemetry/api\") as OpenTelemetryApi;\n }\n } catch {\n return [];\n }\n\n if (!api) return [];\n\n try {\n const activeContext = api.context.active();\n const entries: ClientTraceDataEntry[] = [];\n api.propagation.inject(activeContext, entries, carrierSetter);\n return entries;\n } catch {\n return [];\n }\n}\n\n/**\n * Filter an entry list against the configured `clientTraceMetadata` allow-list.\n * Returns `undefined` when the allow-list is unset so callers can skip\n * rendering altogether.\n */\nexport function filterClientTraceMetadata(\n entries: readonly ClientTraceDataEntry[],\n allowList: readonly string[] | undefined,\n): ClientTraceDataEntry[] | undefined {\n if (!allowList || allowList.length === 0) return undefined;\n const allowSet = new Set(allowList);\n return entries.filter(({ key }) => allowSet.has(key));\n}\n\n/**\n * Render the filtered entries as a sequence of self-closing `<meta>` tags.\n * Names and values are HTML-attribute escaped. Returns an empty string when\n * `entries` is empty or undefined so callers can append unconditionally.\n */\nexport function renderClientTraceMetadataTags(\n entries: readonly ClientTraceDataEntry[] | undefined,\n): string {\n if (!entries || entries.length === 0) return \"\";\n let html = \"\";\n for (const { key, value } of entries) {\n html += `<meta name=\"${escapeHtmlAttr(key)}\" content=\"${escapeHtmlAttr(value)}\"/>`;\n }\n return html;\n}\n\n/**\n * Convenience helper: read OTel propagation data, filter against the\n * configured allow-list, and render the resulting `<meta>` tags. Returns an\n * empty string when the allow-list is unset, OTel is not installed, or no\n * matching keys were emitted by the propagator.\n *\n * Safe to call unconditionally on every SSR render — when nothing is\n * configured/active this is a few `try/catch`-bounded operations and returns\n * `\"\"`.\n */\nexport function getClientTraceMetadataHTML(allowList: readonly string[] | undefined): string {\n if (!allowList || allowList.length === 0) return \"\";\n const entries = getOpenTelemetryTraceData();\n const filtered = filterClientTraceMetadata(entries, allowList);\n return renderClientTraceMetadataTags(filtered);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA4BA,MAAM,gBAA+B,EACnC,IAAI,SAAS,KAAK,OAAO;CACvB,IAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,UAAU;CAC1D,QAAQ,KAAK;EAAE;EAAK;EAAO,CAAC;GAE/B;AAkBD,SAAS,4BAAoD;CAC3D,IAAI;CACJ,IAAI;EAIF,MAAM,MAAO,WAAqD;EAClE,IAAI,OAAO,QAAQ,YACjB,MAAM,IAAI,qBAAqB;SAE3B;EACN,OAAO,EAAE;;CAGX,IAAI,CAAC,KAAK,OAAO,EAAE;CAEnB,IAAI;EACF,MAAM,gBAAgB,IAAI,QAAQ,QAAQ;EAC1C,MAAM,UAAkC,EAAE;EAC1C,IAAI,YAAY,OAAO,eAAe,SAAS,cAAc;EAC7D,OAAO;SACD;EACN,OAAO,EAAE;;;;;;;;AASb,SAAgB,0BACd,SACA,WACoC;CACpC,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO,KAAA;CACjD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,OAAO,QAAQ,QAAQ,EAAE,UAAU,SAAS,IAAI,IAAI,CAAC;;;;;;;AAQvD,SAAgB,8BACd,SACQ;CACR,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,OAAO;CAC7C,IAAI,OAAO;CACX,KAAK,MAAM,EAAE,KAAK,WAAW,SAC3B,QAAQ,eAAe,eAAe,IAAI,CAAC,aAAa,eAAe,MAAM,CAAC;CAEhF,OAAO;;;;;;;;;;;;AAaT,SAAgB,2BAA2B,WAAkD;CAC3F,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAGjD,OAAO,8BADU,0BADD,2BACkC,EAAE,UACP,CAAC"}
@@ -0,0 +1,13 @@
1
+ //#region src/server/cookie-utils.d.ts
2
+ /**
3
+ * Parse the cookie name out of a serialised Set-Cookie line.
4
+ *
5
+ * Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never
6
+ * mistaken for part of the name when the value happens to contain another
7
+ * `=`. Returns null when the line is not parseable (defensive — callers keep
8
+ * unparseable entries verbatim so they don't drop user-supplied cookies).
9
+ */
10
+ declare function getSetCookieName(cookie: string): string | null;
11
+ //#endregion
12
+ export { getSetCookieName };
13
+ //# sourceMappingURL=cookie-utils.d.ts.map
@@ -0,0 +1,20 @@
1
+ //#region src/server/cookie-utils.ts
2
+ /**
3
+ * Parse the cookie name out of a serialised Set-Cookie line.
4
+ *
5
+ * Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never
6
+ * mistaken for part of the name when the value happens to contain another
7
+ * `=`. Returns null when the line is not parseable (defensive — callers keep
8
+ * unparseable entries verbatim so they don't drop user-supplied cookies).
9
+ */
10
+ function getSetCookieName(cookie) {
11
+ const equalsIndex = cookie.indexOf("=");
12
+ if (equalsIndex <= 0) return null;
13
+ const semicolonIndex = cookie.indexOf(";");
14
+ const end = semicolonIndex === -1 ? equalsIndex : Math.min(equalsIndex, semicolonIndex);
15
+ return cookie.slice(0, end);
16
+ }
17
+ //#endregion
18
+ export { getSetCookieName };
19
+
20
+ //# sourceMappingURL=cookie-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-utils.js","names":[],"sources":["../../src/server/cookie-utils.ts"],"sourcesContent":["/**\n * Parse the cookie name out of a serialised Set-Cookie line.\n *\n * Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never\n * mistaken for part of the name when the value happens to contain another\n * `=`. Returns null when the line is not parseable (defensive — callers keep\n * unparseable entries verbatim so they don't drop user-supplied cookies).\n */\nexport function getSetCookieName(cookie: string): string | null {\n const equalsIndex = cookie.indexOf(\"=\");\n if (equalsIndex <= 0) {\n return null;\n }\n const semicolonIndex = cookie.indexOf(\";\");\n const end = semicolonIndex === -1 ? equalsIndex : Math.min(equalsIndex, semicolonIndex);\n return cookie.slice(0, end);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,iBAAiB,QAA+B;CAC9D,MAAM,cAAc,OAAO,QAAQ,IAAI;CACvC,IAAI,eAAe,GACjB,OAAO;CAET,MAAM,iBAAiB,OAAO,QAAQ,IAAI;CAC1C,MAAM,MAAM,mBAAmB,KAAK,cAAc,KAAK,IAAI,aAAa,eAAe;CACvF,OAAO,OAAO,MAAM,GAAG,IAAI"}
@@ -0,0 +1,20 @@
1
+ //#region src/server/default-not-found-module.d.ts
2
+ /**
3
+ * Module-shaped wrapper around vinext's built-in default not-found component.
4
+ * Used as the fallback when an app does not define its own `app/not-found.tsx`
5
+ * (and has not opted into `app/global-not-found.tsx`). The runtime treats any
6
+ * `{ default: Component }` record as a "not-found module", so wrapping the
7
+ * component this way lets us thread the default through the existing
8
+ * `rootNotFoundModule` plumbing without introducing a parallel code path.
9
+ *
10
+ * Mirrors Next.js's `defaultNotFoundPath`
11
+ * (`next/dist/client/components/builtin/not-found.js`), which is selected
12
+ * automatically when the user has not supplied a custom not-found file:
13
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
14
+ */
15
+ declare const DEFAULT_NOT_FOUND_MODULE: {
16
+ readonly default: any;
17
+ };
18
+ //#endregion
19
+ export { DEFAULT_NOT_FOUND_MODULE };
20
+ //# sourceMappingURL=default-not-found-module.d.ts.map
@@ -0,0 +1,20 @@
1
+ import DefaultNotFound from "../shims/default-not-found.js";
2
+ //#region src/server/default-not-found-module.ts
3
+ /**
4
+ * Module-shaped wrapper around vinext's built-in default not-found component.
5
+ * Used as the fallback when an app does not define its own `app/not-found.tsx`
6
+ * (and has not opted into `app/global-not-found.tsx`). The runtime treats any
7
+ * `{ default: Component }` record as a "not-found module", so wrapping the
8
+ * component this way lets us thread the default through the existing
9
+ * `rootNotFoundModule` plumbing without introducing a parallel code path.
10
+ *
11
+ * Mirrors Next.js's `defaultNotFoundPath`
12
+ * (`next/dist/client/components/builtin/not-found.js`), which is selected
13
+ * automatically when the user has not supplied a custom not-found file:
14
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
15
+ */
16
+ const DEFAULT_NOT_FOUND_MODULE = { default: DefaultNotFound };
17
+ //#endregion
18
+ export { DEFAULT_NOT_FOUND_MODULE };
19
+
20
+ //# sourceMappingURL=default-not-found-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-not-found-module.js","names":[],"sources":["../../src/server/default-not-found-module.ts"],"sourcesContent":["import DefaultNotFound from \"vinext/shims/default-not-found\";\n\n/**\n * Module-shaped wrapper around vinext's built-in default not-found component.\n * Used as the fallback when an app does not define its own `app/not-found.tsx`\n * (and has not opted into `app/global-not-found.tsx`). The runtime treats any\n * `{ default: Component }` record as a \"not-found module\", so wrapping the\n * component this way lets us thread the default through the existing\n * `rootNotFoundModule` plumbing without introducing a parallel code path.\n *\n * Mirrors Next.js's `defaultNotFoundPath`\n * (`next/dist/client/components/builtin/not-found.js`), which is selected\n * automatically when the user has not supplied a custom not-found file:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts\n */\nexport const DEFAULT_NOT_FOUND_MODULE = {\n default: DefaultNotFound,\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,2BAA2B,EACtC,SAAS,iBACV"}
@@ -36,7 +36,14 @@ declare function parseCookieLocale(req: IncomingMessage, i18nConfig: NextI18nCon
36
36
  * 4. Render the component to HTML
37
37
  * 5. Wrap in _document shell and send response
38
38
  */
39
- declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter, routes: Route[], pagesDir: string, i18nConfig?: NextI18nConfig | null, fileMatcher?: ValidFileMatcher, basePath?: string, trailingSlash?: boolean): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
39
+ declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter, routes: Route[], pagesDir: string, i18nConfig?: NextI18nConfig | null, fileMatcher?: ValidFileMatcher, basePath?: string, trailingSlash?: boolean, hasMiddleware?: boolean,
40
+ /**
41
+ * Allow-list of OpenTelemetry propagation keys to emit as `<meta>` tags
42
+ * in the SSR head. Sourced from `experimental.clientTraceMetadata` in
43
+ * `next.config`. When undefined or empty, no meta tags are emitted.
44
+ */
45
+
46
+ clientTraceMetadata?: readonly string[]): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
40
47
 
41
48
  statusCode?: number,
42
49
  /**
@@ -2,7 +2,6 @@ import { createRequestContext, runWithRequestContext } from "../shims/unified-re
2
2
  import { createValidFileMatcher, findFileWithExtensions } from "../routing/file-matcher.js";
3
3
  import { patternToNextFormat } from "../routing/route-validation.js";
4
4
  import { matchRoute } from "../routing/pages-router.js";
5
- import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
6
5
  import { normalizeStaticPathname } from "../routing/route-pattern.js";
7
6
  import { importModule, reportRequestError } from "./instrumentation.js";
8
7
  import { buildCacheStateHeaders } from "./cache-headers.js";
@@ -10,14 +9,20 @@ import { _runWithCacheState } from "../shims/cache.js";
10
9
  import { buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, setRevalidateDuration, triggerBackgroundRegeneration } from "./isr-cache.js";
11
10
  import { runWithPrivateCache } from "../shims/cache-runtime.js";
12
11
  import { ensureFetchPatch, runWithFetchCache } from "../shims/fetch-cache.js";
12
+ import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
13
13
  import "../shims/router-state.js";
14
14
  import { runWithHeadState } from "../shims/head-state.js";
15
15
  import { runWithServerInsertedHTMLState } from "../shims/navigation-state.js";
16
16
  import { withScriptNonce } from "../shims/script-nonce-context.js";
17
17
  import { createInlineScriptTag, createNonceAttribute, safeJsonStringify } from "./html.js";
18
+ import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
18
19
  import { getScriptNonceFromNodeHeaderSources } from "./csp.js";
19
20
  import { logRequest, now } from "./request-log.js";
20
21
  import { detectLocaleFromAcceptLanguage, extractLocaleFromUrl as extractLocaleFromUrl$1, parseCookieLocaleFromHeader, resolvePagesI18nRequest } from "./pages-i18n.js";
22
+ import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
23
+ import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
24
+ import { isSerializableProps } from "./pages-serializable-props.js";
25
+ import { loadUserDocumentInitialProps } from "./pages-document-initial-props.js";
21
26
  import path from "node:path";
22
27
  import React from "react";
23
28
  import { renderToReadableStream } from "react-dom/server.edge";
@@ -58,7 +63,8 @@ async function streamPageToResponse(res, element, options) {
58
63
  const headHTML = getHeadHTML();
59
64
  let shellTemplate;
60
65
  if (DocumentComponent) {
61
- let docHtml = await renderToStringAsync(React.createElement(DocumentComponent));
66
+ const docProps = await loadUserDocumentInitialProps(DocumentComponent);
67
+ let docHtml = await renderToStringAsync(docProps ? React.createElement(DocumentComponent, docProps) : React.createElement(DocumentComponent));
62
68
  docHtml = docHtml.replace("__NEXT_MAIN__", STREAM_BODY_MARKER);
63
69
  if (headHTML || fontHeadHTML) docHtml = docHtml.replace("</head>", ` ${fontHeadHTML}${headHTML}\n</head>`);
64
70
  docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", scripts);
@@ -132,7 +138,7 @@ function parseCookieLocale(req, i18nConfig) {
132
138
  * 4. Render the component to HTML
133
139
  * 5. Wrap in _document shell and send response
134
140
  */
135
- function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false) {
141
+ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false, hasMiddleware = false, clientTraceMetadata) {
136
142
  const matcher = fileMatcher ?? createValidFileMatcher();
137
143
  const _alsRegistration = Promise.all([runner.import("vinext/head-state"), runner.import("vinext/router-state")]);
138
144
  _alsRegistration.catch(() => {});
@@ -215,6 +221,23 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
215
221
  res.end("Page has no default export");
216
222
  return;
217
223
  }
224
+ {
225
+ const routePattern = patternToNextFormat(route.pattern);
226
+ if (!isDataReq && routePattern !== "/_error" && routePattern !== "/404" && routePattern !== "/500" && statusCode === void 0) {
227
+ const methodResponse = resolvePagesPageMethodResponse({
228
+ hasGetServerSideProps: typeof pageModule.getServerSideProps === "function",
229
+ method: req.method ?? "GET"
230
+ });
231
+ if (methodResponse) {
232
+ res.statusCode = methodResponse.status;
233
+ const allow = methodResponse.headers.get("allow");
234
+ if (allow) res.setHeader("Allow", allow);
235
+ res.setHeader("Content-Type", "text/plain;charset=UTF-8");
236
+ res.end(await methodResponse.text());
237
+ return;
238
+ }
239
+ }
240
+ }
218
241
  let pageProps = {};
219
242
  let isrRevalidateSeconds = null;
220
243
  let isFallbackRender = false;
@@ -274,7 +297,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
274
297
  };
275
298
  const result = await pageModule.getServerSideProps(context);
276
299
  if (res.writableEnded) return;
277
- if (result && "props" in result) pageProps = result.props;
300
+ if (result && "props" in result) pageProps = await Promise.resolve(result.props);
278
301
  if (result && "redirect" in result) {
279
302
  const { redirect } = result;
280
303
  const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
@@ -293,6 +316,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
293
316
  await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
294
317
  return;
295
318
  }
319
+ if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getServerSideProps", pageProps);
296
320
  if (!statusCode && res.statusCode !== 200) statusCode = res.statusCode;
297
321
  const headersAfterGSSP = res.getHeaders();
298
322
  for (const [key, val] of Object.entries(headersAfterGSSP)) {
@@ -301,6 +325,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
301
325
  if (Array.isArray(val)) gsspExtraHeaders[key] = val.map(String);
302
326
  else gsspExtraHeaders[key] = String(val);
303
327
  }
328
+ if (!Object.keys(gsspExtraHeaders).some((k) => k.toLowerCase() === "cache-control")) gsspExtraHeaders["Cache-Control"] = "private, no-cache, no-store, max-age=0, must-revalidate";
304
329
  }
305
330
  const responseHeaders = typeof res.getHeaders === "function" ? res.getHeaders() : void 0;
306
331
  const scriptNonce = getScriptNonceFromNodeHeaderSources(req.headers, responseHeaders);
@@ -340,7 +365,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
340
365
  params: userFacingParams,
341
366
  locale: locale ?? currentDefaultLocale,
342
367
  locales: i18nConfig?.locales,
343
- defaultLocale: currentDefaultLocale
368
+ defaultLocale: currentDefaultLocale,
369
+ revalidateReason: "stale"
344
370
  });
345
371
  if (freshResult && "props" in freshResult) {
346
372
  const revalidate = typeof freshResult.revalidate === "number" ? freshResult.revalidate : 0;
@@ -392,7 +418,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
392
418
  domainLocales,
393
419
  __vinext: {
394
420
  pageModuleUrl: regenPageUrl,
395
- appModuleUrl: regenAppUrl
421
+ appModuleUrl: regenAppUrl,
422
+ hasMiddleware
396
423
  }
397
424
  })}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html>`, freshProps), revalidate);
398
425
  setRevalidateDuration(cacheKey, revalidate);
@@ -419,7 +446,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
419
446
  params: userFacingParams,
420
447
  locale: locale ?? currentDefaultLocale,
421
448
  locales: i18nConfig?.locales,
422
- defaultLocale: currentDefaultLocale
449
+ defaultLocale: currentDefaultLocale,
450
+ revalidateReason: "stale"
423
451
  };
424
452
  const result = await pageModule.getStaticProps(context);
425
453
  if (result && "props" in result) pageProps = result.props;
@@ -441,6 +469,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
441
469
  await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
442
470
  return;
443
471
  }
472
+ if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getStaticProps", pageProps);
444
473
  if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
445
474
  }
446
475
  if (isDataReq) {
@@ -546,7 +575,8 @@ hydrate();
546
575
  domainLocales,
547
576
  __vinext: {
548
577
  pageModuleUrl,
549
- appModuleUrl
578
+ appModuleUrl,
579
+ hasMiddleware
550
580
  }
551
581
  })}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}`, scriptNonce);
552
582
  const docPath = path.join(pagesDir, "_document");
@@ -570,7 +600,11 @@ hydrate();
570
600
  DocumentComponent,
571
601
  statusCode,
572
602
  extraHeaders,
573
- getHeadHTML: () => typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : ""
603
+ getHeadHTML: () => {
604
+ const headHTML = typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : "";
605
+ const traceHTML = getClientTraceMetadataHTML(clientTraceMetadata);
606
+ return traceHTML ? `${headHTML}\n ${traceHTML}` : headHTML;
607
+ }
574
608
  });
575
609
  _renderEnd = now();
576
610
  if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext(null);
@@ -648,7 +682,8 @@ async function renderErrorPage(server, runner, _req, res, url, pagesDir, statusC
648
682
  DocumentComponent = (await importModule(runner, docPathErr)).default ?? null;
649
683
  } catch {}
650
684
  if (DocumentComponent) {
651
- let docHtml = await renderToStringAsync(createElement(DocumentComponent));
685
+ const docProps = await loadUserDocumentInitialProps(DocumentComponent);
686
+ let docHtml = await renderToStringAsync(docProps ? createElement(DocumentComponent, docProps) : createElement(DocumentComponent));
652
687
  docHtml = docHtml.replace("__NEXT_MAIN__", bodyHtml);
653
688
  docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", "");
654
689
  html = docHtml;
@@ -669,8 +704,18 @@ async function renderErrorPage(server, runner, _req, res, url, pagesDir, statusC
669
704
  } catch {
670
705
  continue;
671
706
  }
707
+ if (statusCode === 404) {
708
+ const defaultResponse = buildDefaultPagesNotFoundResponse();
709
+ const headers = {};
710
+ defaultResponse.headers.forEach((value, key) => {
711
+ headers[key] = value;
712
+ });
713
+ res.writeHead(defaultResponse.status, headers);
714
+ res.end(await defaultResponse.text());
715
+ return;
716
+ }
672
717
  res.writeHead(statusCode, { "Content-Type": "text/plain" });
673
- res.end(`${statusCode} - ${statusCode === 404 ? "Page not found" : "Internal Server Error"}`);
718
+ res.end(`${statusCode} - Internal Server Error`);
674
719
  }
675
720
  //#endregion
676
721
  export { createSSRHandler, detectLocaleFromHeaders, extractLocaleFromUrl, parseCookieLocale };