vinext 0.1.2 → 0.1.4

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 (243) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/prerender.d.ts +9 -1
  4. package/dist/build/prerender.js +42 -12
  5. package/dist/build/run-prerender.d.ts +10 -2
  6. package/dist/build/run-prerender.js +15 -1
  7. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  8. package/dist/client/app-nav-failure-handler.js +44 -0
  9. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  10. package/dist/client/pages-router-link-navigation.js +32 -2
  11. package/dist/client/vinext-next-data.d.ts +18 -1
  12. package/dist/client/vinext-next-data.js +2 -0
  13. package/dist/client/window-next.d.ts +2 -1
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -1
  17. package/dist/config/config-matchers.js +87 -16
  18. package/dist/config/next-config.d.ts +46 -4
  19. package/dist/config/next-config.js +147 -48
  20. package/dist/config/tsconfig-paths.js +14 -1
  21. package/dist/deploy.d.ts +30 -11
  22. package/dist/deploy.js +200 -112
  23. package/dist/entries/app-browser-entry.d.ts +9 -3
  24. package/dist/entries/app-browser-entry.js +21 -3
  25. package/dist/entries/app-rsc-entry.d.ts +2 -0
  26. package/dist/entries/app-rsc-entry.js +65 -5
  27. package/dist/entries/app-rsc-manifest.js +2 -0
  28. package/dist/entries/app-ssr-entry.js +1 -1
  29. package/dist/entries/pages-client-entry.js +66 -20
  30. package/dist/entries/pages-server-entry.js +47 -31
  31. package/dist/index.js +417 -102
  32. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  33. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  34. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  35. package/dist/plugins/fonts.js +5 -4
  36. package/dist/plugins/optimize-imports.d.ts +2 -1
  37. package/dist/plugins/optimize-imports.js +11 -9
  38. package/dist/plugins/postcss.js +7 -7
  39. package/dist/plugins/strip-server-exports.d.ts +9 -7
  40. package/dist/plugins/strip-server-exports.js +493 -46
  41. package/dist/plugins/typeof-window.d.ts +14 -0
  42. package/dist/plugins/typeof-window.js +150 -0
  43. package/dist/routing/app-route-graph.d.ts +2 -1
  44. package/dist/routing/app-route-graph.js +46 -16
  45. package/dist/routing/file-matcher.d.ts +10 -1
  46. package/dist/routing/file-matcher.js +22 -1
  47. package/dist/routing/pages-router.js +3 -3
  48. package/dist/routing/utils.d.ts +35 -6
  49. package/dist/routing/utils.js +59 -7
  50. package/dist/server/api-handler.d.ts +6 -1
  51. package/dist/server/api-handler.js +21 -15
  52. package/dist/server/app-browser-action-result.d.ts +19 -6
  53. package/dist/server/app-browser-action-result.js +20 -11
  54. package/dist/server/app-browser-entry.js +175 -91
  55. package/dist/server/app-browser-error.d.ts +10 -6
  56. package/dist/server/app-browser-error.js +43 -8
  57. package/dist/server/app-browser-hydration.d.ts +2 -0
  58. package/dist/server/app-browser-hydration.js +1 -0
  59. package/dist/server/app-browser-navigation-controller.d.ts +5 -3
  60. package/dist/server/app-browser-navigation-controller.js +23 -2
  61. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  62. package/dist/server/app-browser-server-action-navigation.js +9 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js +19 -11
  65. package/dist/server/app-browser-stream.js +86 -43
  66. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  67. package/dist/server/app-elements-wire.d.ts +6 -1
  68. package/dist/server/app-elements-wire.js +14 -4
  69. package/dist/server/app-elements.d.ts +2 -2
  70. package/dist/server/app-elements.js +2 -2
  71. package/dist/server/app-fallback-renderer.d.ts +1 -0
  72. package/dist/server/app-fallback-renderer.js +3 -1
  73. package/dist/server/app-optimistic-routing.js +2 -2
  74. package/dist/server/app-page-boundary-render.d.ts +1 -0
  75. package/dist/server/app-page-boundary-render.js +27 -14
  76. package/dist/server/app-page-cache-render.d.ts +53 -0
  77. package/dist/server/app-page-cache-render.js +91 -0
  78. package/dist/server/app-page-cache.d.ts +16 -2
  79. package/dist/server/app-page-cache.js +62 -1
  80. package/dist/server/app-page-dispatch.d.ts +26 -0
  81. package/dist/server/app-page-dispatch.js +149 -92
  82. package/dist/server/app-page-element-builder.d.ts +1 -0
  83. package/dist/server/app-page-element-builder.js +5 -2
  84. package/dist/server/app-page-execution.d.ts +6 -1
  85. package/dist/server/app-page-execution.js +21 -1
  86. package/dist/server/app-page-probe.d.ts +1 -0
  87. package/dist/server/app-page-probe.js +4 -0
  88. package/dist/server/app-page-render-observation.d.ts +3 -1
  89. package/dist/server/app-page-render-observation.js +17 -1
  90. package/dist/server/app-page-render.d.ts +12 -1
  91. package/dist/server/app-page-render.js +42 -4
  92. package/dist/server/app-page-request.d.ts +2 -0
  93. package/dist/server/app-page-request.js +2 -1
  94. package/dist/server/app-page-route-wiring.d.ts +3 -1
  95. package/dist/server/app-page-route-wiring.js +14 -5
  96. package/dist/server/app-page-stream.d.ts +15 -3
  97. package/dist/server/app-page-stream.js +11 -5
  98. package/dist/server/app-pages-bridge.d.ts +23 -1
  99. package/dist/server/app-pages-bridge.js +26 -17
  100. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  101. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  102. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  103. package/dist/server/app-ppr-fallback-shell.js +8 -1
  104. package/dist/server/app-route-handler-dispatch.js +9 -2
  105. package/dist/server/app-route-handler-policy.d.ts +1 -0
  106. package/dist/server/app-router-entry.js +5 -0
  107. package/dist/server/app-rsc-cache-busting.js +2 -0
  108. package/dist/server/app-rsc-handler.d.ts +28 -0
  109. package/dist/server/app-rsc-handler.js +195 -59
  110. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  111. package/dist/server/app-rsc-route-matching.js +8 -2
  112. package/dist/server/app-segment-config.d.ts +9 -1
  113. package/dist/server/app-segment-config.js +12 -3
  114. package/dist/server/app-server-action-execution.d.ts +1 -0
  115. package/dist/server/app-server-action-execution.js +47 -15
  116. package/dist/server/app-ssr-entry.d.ts +2 -0
  117. package/dist/server/app-ssr-entry.js +84 -39
  118. package/dist/server/before-interactive-head.d.ts +17 -0
  119. package/dist/server/before-interactive-head.js +35 -0
  120. package/dist/server/cache-control.js +4 -0
  121. package/dist/server/csp.js +1 -4
  122. package/dist/server/dev-server.d.ts +2 -2
  123. package/dist/server/dev-server.js +321 -83
  124. package/dist/server/hybrid-route-priority.d.ts +22 -0
  125. package/dist/server/hybrid-route-priority.js +33 -0
  126. package/dist/server/image-optimization.d.ts +18 -9
  127. package/dist/server/image-optimization.js +37 -23
  128. package/dist/server/implicit-tags.d.ts +2 -1
  129. package/dist/server/implicit-tags.js +4 -1
  130. package/dist/server/middleware-matcher.js +12 -3
  131. package/dist/server/middleware-runtime.d.ts +3 -4
  132. package/dist/server/middleware-runtime.js +2 -0
  133. package/dist/server/navigation-planner.d.ts +135 -41
  134. package/dist/server/navigation-planner.js +138 -0
  135. package/dist/server/navigation-trace.d.ts +9 -1
  136. package/dist/server/navigation-trace.js +9 -1
  137. package/dist/server/operation-token.d.ts +40 -0
  138. package/dist/server/operation-token.js +85 -0
  139. package/dist/server/pages-api-route.d.ts +6 -0
  140. package/dist/server/pages-api-route.js +13 -2
  141. package/dist/server/pages-asset-tags.d.ts +2 -1
  142. package/dist/server/pages-asset-tags.js +6 -2
  143. package/dist/server/pages-data-route.d.ts +9 -2
  144. package/dist/server/pages-data-route.js +18 -6
  145. package/dist/server/pages-dev-module-url.d.ts +4 -0
  146. package/dist/server/pages-dev-module-url.js +15 -0
  147. package/dist/server/pages-document-initial-props.d.ts +4 -15
  148. package/dist/server/pages-document-initial-props.js +27 -56
  149. package/dist/server/pages-get-initial-props.d.ts +54 -4
  150. package/dist/server/pages-get-initial-props.js +43 -1
  151. package/dist/server/pages-i18n.js +2 -2
  152. package/dist/server/pages-node-compat.js +2 -2
  153. package/dist/server/pages-page-data.d.ts +11 -2
  154. package/dist/server/pages-page-data.js +207 -34
  155. package/dist/server/pages-page-handler.d.ts +4 -2
  156. package/dist/server/pages-page-handler.js +62 -23
  157. package/dist/server/pages-page-response.d.ts +4 -1
  158. package/dist/server/pages-page-response.js +11 -8
  159. package/dist/server/pages-readiness.js +1 -1
  160. package/dist/server/pages-request-pipeline.d.ts +8 -7
  161. package/dist/server/pages-request-pipeline.js +126 -47
  162. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  163. package/dist/server/pregenerated-concrete-paths.js +2 -19
  164. package/dist/server/prerender-manifest.d.ts +33 -0
  165. package/dist/server/prerender-manifest.js +54 -0
  166. package/dist/server/prerender-route-params.d.ts +1 -2
  167. package/dist/server/prod-server.d.ts +3 -1
  168. package/dist/server/prod-server.js +50 -13
  169. package/dist/server/request-pipeline.d.ts +3 -15
  170. package/dist/server/request-pipeline.js +58 -47
  171. package/dist/server/rsc-stream-hints.d.ts +5 -1
  172. package/dist/server/rsc-stream-hints.js +6 -1
  173. package/dist/server/seed-cache.js +10 -18
  174. package/dist/server/static-file-cache.js +16 -4
  175. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  176. package/dist/shims/app-router-scroll-state.js +14 -2
  177. package/dist/shims/app-router-scroll.d.ts +3 -0
  178. package/dist/shims/app-router-scroll.js +28 -18
  179. package/dist/shims/before-interactive-context.d.ts +14 -3
  180. package/dist/shims/cache-runtime.js +3 -2
  181. package/dist/shims/cache.d.ts +1 -0
  182. package/dist/shims/cache.js +1 -1
  183. package/dist/shims/cdn-cache.d.ts +5 -5
  184. package/dist/shims/document.d.ts +15 -20
  185. package/dist/shims/document.js +5 -8
  186. package/dist/shims/dynamic-preload-chunks.js +6 -4
  187. package/dist/shims/error-boundary.d.ts +2 -0
  188. package/dist/shims/error-boundary.js +7 -0
  189. package/dist/shims/error.js +3 -2
  190. package/dist/shims/error.react-server.d.ts +9 -0
  191. package/dist/shims/error.react-server.js +6 -0
  192. package/dist/shims/fetch-cache.d.ts +3 -1
  193. package/dist/shims/fetch-cache.js +45 -20
  194. package/dist/shims/hash-scroll.js +6 -1
  195. package/dist/shims/headers.js +29 -4
  196. package/dist/shims/image.js +9 -2
  197. package/dist/shims/internal/als-registry.js +28 -1
  198. package/dist/shims/internal/app-route-detection.js +8 -17
  199. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  201. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  202. package/dist/shims/internal/navigation-untracked.js +55 -0
  203. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  204. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  205. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  206. package/dist/shims/internal/pages-data-target.js +17 -8
  207. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  208. package/dist/shims/internal/pages-router-accessor.js +13 -0
  209. package/dist/shims/internal/router-context.d.ts +2 -1
  210. package/dist/shims/internal/router-context.js +3 -1
  211. package/dist/shims/link.js +47 -19
  212. package/dist/shims/metadata.js +4 -4
  213. package/dist/shims/navigation.d.ts +8 -2
  214. package/dist/shims/navigation.js +63 -31
  215. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  216. package/dist/shims/ppr-fallback-shell.js +28 -7
  217. package/dist/shims/router.d.ts +18 -3
  218. package/dist/shims/router.js +512 -142
  219. package/dist/shims/script.js +8 -4
  220. package/dist/shims/server.d.ts +16 -1
  221. package/dist/shims/server.js +44 -12
  222. package/dist/shims/unified-request-context.js +1 -0
  223. package/dist/utils/built-asset-url.d.ts +4 -0
  224. package/dist/utils/built-asset-url.js +11 -0
  225. package/dist/utils/commonjs-loader.d.ts +16 -0
  226. package/dist/utils/commonjs-loader.js +100 -0
  227. package/dist/utils/deployment-id.d.ts +8 -0
  228. package/dist/utils/deployment-id.js +22 -0
  229. package/dist/utils/has-trailing-comma.d.ts +24 -0
  230. package/dist/utils/has-trailing-comma.js +62 -0
  231. package/dist/utils/html-limited-bots.d.ts +18 -1
  232. package/dist/utils/html-limited-bots.js +23 -1
  233. package/dist/utils/parse-cookie.d.ts +13 -0
  234. package/dist/utils/parse-cookie.js +52 -0
  235. package/dist/utils/path.d.ts +7 -1
  236. package/dist/utils/path.js +9 -1
  237. package/dist/utils/text-stream.d.ts +1 -1
  238. package/dist/utils/text-stream.js +2 -2
  239. package/dist/utils/vite-version.d.ts +12 -1
  240. package/dist/utils/vite-version.js +9 -1
  241. package/package.json +2 -2
  242. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  243. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -6,6 +6,7 @@ import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
6
6
  import { normalizeStaticPathname } from "../routing/route-pattern.js";
7
7
  import { importModule, reportRequestError } from "./instrumentation.js";
8
8
  import { buildCacheStateHeaders } from "./cache-headers.js";
9
+ import { isUnknownRecord } from "../utils/record.js";
9
10
  import { _runWithCacheState } from "../shims/cache.js";
10
11
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL } from "./cache-control.js";
11
12
  import { buildMissIsrCacheControl, decideIsr } from "./isr-decision.js";
@@ -25,10 +26,12 @@ import { detectLocaleFromAcceptLanguage, extractLocaleFromUrl as extractLocaleFr
25
26
  import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
26
27
  import { buildPagesReadinessNextData } from "./pages-readiness.js";
27
28
  import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
29
+ import { createPagesDevModuleUrl } from "./pages-dev-module-url.js";
28
30
  import { isSerializableProps } from "./pages-serializable-props.js";
29
31
  import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
30
32
  import { callDocumentGetInitialProps } from "./document-initial-head.js";
31
- import { loadPagesGetInitialProps } from "./pages-get-initial-props.js";
33
+ import { hasPagesGetInitialProps, loadDevAppInitialProps, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
34
+ import { isBotUserAgent } from "../utils/html-limited-bots.js";
32
35
  import path from "node:path";
33
36
  import React from "react";
34
37
  import { renderToReadableStream } from "react-dom/server.edge";
@@ -60,7 +63,7 @@ async function renderIsrPassToStringAsync(element) {
60
63
  * (`buildPagesRedirectResponse`) and Next.js's `render.tsx` `__N_REDIRECT`
61
64
  * handling. See AGENTS.md "dev and prod server parity".
62
65
  */
63
- function writeGsspRedirect(res, redirect, isDataReq) {
66
+ function writeGsspRedirect(res, redirect, isDataReq, props) {
64
67
  const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
65
68
  let dest = redirect.destination;
66
69
  if (!dest.startsWith("http://") && !dest.startsWith("https://")) dest = dest.replace(/^[\\/]+/, "/");
@@ -69,10 +72,14 @@ function writeGsspRedirect(res, redirect, isDataReq) {
69
72
  const dataHeaders = { "Content-Type": "application/json" };
70
73
  if (deploymentId) dataHeaders[NEXTJS_DEPLOYMENT_ID_HEADER] = deploymentId;
71
74
  res.writeHead(200, dataHeaders);
72
- res.end(JSON.stringify({ pageProps: {
73
- __N_REDIRECT: dest,
74
- __N_REDIRECT_STATUS: status
75
- } }));
75
+ res.end(JSON.stringify({
76
+ ...props,
77
+ pageProps: {
78
+ ...isUnknownRecord(props.pageProps) ? props.pageProps : {},
79
+ __N_REDIRECT: dest,
80
+ __N_REDIRECT_STATUS: status
81
+ }
82
+ }));
76
83
  return;
77
84
  }
78
85
  res.writeHead(status, { Location: dest });
@@ -94,7 +101,7 @@ const STREAM_BODY_MARKER = "<!--VINEXT_STREAM_BODY-->";
94
101
  * shell sooner).
95
102
  */
96
103
  async function streamPageToResponse(res, element, options) {
97
- const { url, server, fontHeadHTML, scripts, DocumentComponent, statusCode = 200, extraHeaders, getHeadHTML, enhancePageElement, scriptNonce, documentContext, setDocumentInitialHead } = options;
104
+ const { url, server, fontHeadHTML, scripts, DocumentComponent, statusCode = 200, extraHeaders, getHeadHTML, enhancePageElement, scriptNonce, documentContext, setDocumentInitialHead, bufferBodyBeforeHeaders = false } = options;
98
105
  const documentRenderPage = await runDocumentRenderPage({
99
106
  DocumentComponent,
100
107
  enhancePageElement,
@@ -138,6 +145,7 @@ async function streamPageToResponse(res, element, options) {
138
145
  const markerIdx = transformedShell.indexOf(STREAM_BODY_MARKER);
139
146
  const prefix = transformedShell.slice(0, markerIdx);
140
147
  const suffix = transformedShell.slice(markerIdx + 25);
148
+ const bufferedBody = bufferBodyBeforeHeaders ? await new Response(bodyStream).text() : null;
141
149
  const headers = {
142
150
  "Content-Type": "text/html",
143
151
  "Transfer-Encoding": "chunked"
@@ -146,6 +154,10 @@ async function streamPageToResponse(res, element, options) {
146
154
  else headers[key] = val;
147
155
  res.writeHead(statusCode, headers);
148
156
  res.write(prefix);
157
+ if (bufferedBody !== null) {
158
+ res.end(bufferedBody + suffix);
159
+ return;
160
+ }
149
161
  const reader = bodyStream.getReader();
150
162
  try {
151
163
  for (;;) {
@@ -190,12 +202,12 @@ function parseCookieLocale(req, i18nConfig) {
190
202
  * 4. Render the component to HTML
191
203
  * 5. Wrap in _document shell and send response
192
204
  */
193
- function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false, hasMiddleware = false, hasRewrites = false, clientTraceMetadata) {
205
+ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false, hasMiddleware = false, hasRewrites = false, clientTraceMetadata, htmlLimitedBots) {
194
206
  const matcher = fileMatcher ?? createValidFileMatcher();
195
207
  const pagePatterns = routes.map((r) => patternToNextFormat(r.pattern));
196
208
  const _alsRegistration = Promise.all([runner.import("vinext/head-state"), runner.import("vinext/router-state")]);
197
209
  _alsRegistration.catch(() => {});
198
- return async (req, res, url, statusCode, isDataReq = false) => {
210
+ return async (req, res, url, statusCode, isDataReq = false, originalUrl = url) => {
199
211
  const _reqStart = now();
200
212
  let _compileEnd;
201
213
  let _renderEnd;
@@ -245,6 +257,11 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
245
257
  return;
246
258
  }
247
259
  const { route, params } = match;
260
+ req.url = originalUrl;
261
+ const parsedResolvedUrl = new URL(localeStrippedUrl, "http://vinext.local");
262
+ const originalRequestSearch = new URL(originalUrl, "http://vinext.local").search;
263
+ const gsspResolvedUrl = parsedResolvedUrl.pathname + originalRequestSearch;
264
+ const requestAsPath = isDataReq ? gsspResolvedUrl : originalUrl;
248
265
  const userFacingParams = route.isDynamic ? params : null;
249
266
  const query = mergeRouteParamsIntoQuery(parseQueryString(url), params);
250
267
  return runWithRequestContext(createRequestContext(), async () => {
@@ -278,7 +295,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
278
295
  if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
279
296
  pathname: patternToNextFormat(route.pattern),
280
297
  query,
281
- asPath: url,
298
+ asPath: requestAsPath,
282
299
  navigationIsReady,
283
300
  nextData: pagesNextData,
284
301
  locale: locale ?? currentDefaultLocale,
@@ -312,8 +329,10 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
312
329
  }
313
330
  }
314
331
  let pageProps = {};
332
+ let renderProps = { pageProps };
315
333
  let isrRevalidateSeconds = null;
316
334
  let isFallbackRender = false;
335
+ let shouldPersistFallbackData = false;
317
336
  if (typeof pageModule.getStaticPaths === "function" && route.isDynamic) {
318
337
  const pathsResult = await pageModule.getStaticPaths({
319
338
  locales: i18nConfig?.locales ?? [],
@@ -344,12 +363,15 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
344
363
  await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, matcher);
345
364
  return;
346
365
  }
347
- if (fallback === true && !isValidPath && !isDataReq) {
348
- isFallbackRender = true;
349
- if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
366
+ const userAgentHeader = req.headers["user-agent"];
367
+ const userAgent = Array.isArray(userAgentHeader) ? userAgentHeader[0] : userAgentHeader;
368
+ const isBotRequest = !!userAgent && isBotUserAgent(userAgent, htmlLimitedBots);
369
+ if (fallback === true && !isValidPath && !isDataReq && !isBotRequest) {
370
+ isFallbackRender = (await isrGet(pagesIsrCacheKey(url.split("?")[0])))?.value.value?.kind !== "PAGES";
371
+ if (isFallbackRender && typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
350
372
  pathname: patternToNextFormat(route.pattern),
351
373
  query,
352
- asPath: url,
374
+ asPath: requestAsPath,
353
375
  navigationIsReady: false,
354
376
  locale: locale ?? currentDefaultLocale,
355
377
  locales: i18nConfig?.locales,
@@ -358,25 +380,71 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
358
380
  isFallback: true
359
381
  });
360
382
  }
383
+ shouldPersistFallbackData = fallback === true && !isValidPath && isDataReq;
361
384
  }
362
385
  const gsspExtraHeaders = {};
386
+ const hasAppGetInitialProps = hasPagesGetInitialProps(AppComponent);
387
+ async function loadAppInitialProps() {
388
+ if (!hasAppGetInitialProps) return false;
389
+ const appResult = await loadDevAppInitialProps({
390
+ appComponent: AppComponent,
391
+ appTree: (appTreeProps) => {
392
+ const appTree = React.createElement(AppComponent, {
393
+ ...appTreeProps,
394
+ Component: PageComponent,
395
+ pageProps: appTreeProps.pageProps,
396
+ router: routerShim.default
397
+ });
398
+ return typeof routerShim.wrapWithRouterContext === "function" ? routerShim.wrapWithRouterContext(appTree) : appTree;
399
+ },
400
+ component: PageComponent,
401
+ req,
402
+ res,
403
+ pathname: patternToNextFormat(route.pattern),
404
+ query,
405
+ asPath: requestAsPath,
406
+ locale: locale ?? currentDefaultLocale,
407
+ locales: i18nConfig?.locales,
408
+ defaultLocale: currentDefaultLocale
409
+ });
410
+ if (appResult.kind === "response-sent") return true;
411
+ if (appResult.kind === "render") {
412
+ pageProps = appResult.pageProps;
413
+ renderProps = appResult.renderProps;
414
+ }
415
+ return false;
416
+ }
363
417
  if (typeof pageModule.getServerSideProps === "function" && !isFallbackRender) {
418
+ if (await loadAppInitialProps()) return;
419
+ renderProps = {
420
+ ...renderProps,
421
+ __N_SSP: true
422
+ };
364
423
  const headersBeforeGSSP = new Set(Object.keys(res.getHeaders()));
365
424
  const context = {
366
425
  params: userFacingParams,
367
426
  req,
368
427
  res,
369
428
  query,
370
- resolvedUrl: localeStrippedUrl,
429
+ resolvedUrl: gsspResolvedUrl,
371
430
  locale: locale ?? currentDefaultLocale,
372
431
  locales: i18nConfig?.locales,
373
432
  defaultLocale: currentDefaultLocale
374
433
  };
375
434
  const result = await pageModule.getServerSideProps(context);
376
435
  if (res.writableEnded) return;
377
- if (result && "props" in result) pageProps = await Promise.resolve(result.props);
436
+ if (result && "props" in result) {
437
+ pageProps = {
438
+ ...pageProps,
439
+ ...await Promise.resolve(result.props)
440
+ };
441
+ renderProps = {
442
+ ...renderProps,
443
+ pageProps
444
+ };
445
+ }
378
446
  if (result && "redirect" in result) {
379
- writeGsspRedirect(res, result.redirect, isDataReq);
447
+ writeGsspRedirect(res, result.redirect, isDataReq, renderProps);
380
448
  return;
381
449
  }
382
450
  if (result && "notFound" in result && result.notFound) {
@@ -417,7 +485,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
417
485
  const cacheKey = pagesIsrCacheKey(url.split("?")[0]);
418
486
  const cached = await isrGet(cacheKey);
419
487
  const isOnDemandRevalidate = isOnDemandRevalidateRequest(req.headers[PRERENDER_REVALIDATE_HEADER]);
420
- if (!isOnDemandRevalidate && cached && !cached.isStale && cached.value.value?.kind === "PAGES" && !scriptNonce && !isDataReq) {
488
+ if (!isOnDemandRevalidate && cached && !cached.isStale && cached.value.value?.kind === "PAGES" && !cached.value.value.generatedFromDataRequest && !scriptNonce && !isDataReq) {
421
489
  const cachedHtml = cached.value.value.html;
422
490
  const transformedHtml = await server.transformIndexHtml(url, cachedHtml);
423
491
  const { cacheControl: hitCacheControl } = decideIsr({
@@ -435,12 +503,84 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
435
503
  res.end(transformedHtml);
436
504
  return;
437
505
  }
438
- if (!isOnDemandRevalidate && cached && cached.isStale && cached.value.value?.kind === "PAGES" && !scriptNonce && !isDataReq) {
506
+ if (!isOnDemandRevalidate && cached && cached.isStale && cached.value.value?.kind === "PAGES" && !cached.value.value.generatedFromDataRequest && !scriptNonce && !isDataReq) {
439
507
  const cachedHtml = cached.value.value.html;
440
508
  const transformedHtml = await server.transformIndexHtml(url, cachedHtml);
441
509
  triggerBackgroundRegeneration(cacheKey, async () => {
442
- return runWithRequestContext(createRequestContext({ executionContext: null }), async () => {
510
+ return runWithRequestContext(createRequestContext({
511
+ executionContext: null,
512
+ ssrContext: {
513
+ pathname: patternToNextFormat(route.pattern),
514
+ query,
515
+ asPath: requestAsPath,
516
+ navigationIsReady,
517
+ locale: locale ?? currentDefaultLocale,
518
+ locales: i18nConfig?.locales,
519
+ defaultLocale: currentDefaultLocale
520
+ },
521
+ i18nContext: i18nConfig ? {
522
+ locale: locale ?? currentDefaultLocale,
523
+ locales: i18nConfig.locales,
524
+ defaultLocale: currentDefaultLocale,
525
+ domainLocales,
526
+ hostname: req.headers.host?.split(":", 1)[0]
527
+ } : null
528
+ }), async () => {
443
529
  ensureFetchPatch();
530
+ let freshPageProps = {};
531
+ let freshRenderProps = { pageProps: freshPageProps };
532
+ let RegenApp = null;
533
+ const appPath = path.join(pagesDir, "_app");
534
+ if (findFileWithExtensions(appPath, matcher)) try {
535
+ RegenApp = (await runner.import(appPath)).default ?? null;
536
+ } catch {}
537
+ if (RegenApp && hasPagesGetInitialProps(RegenApp)) {
538
+ const regenReq = {
539
+ url: req.url,
540
+ headers: req.headers,
541
+ method: req.method
542
+ };
543
+ const regenRes = {
544
+ headersSent: false,
545
+ writableEnded: false,
546
+ statusCode: 200,
547
+ getHeaders() {
548
+ return {};
549
+ }
550
+ };
551
+ const initialProps = await loadPagesGetInitialProps(RegenApp, {
552
+ AppTree: (appTreeProps) => {
553
+ const appTree = React.createElement(RegenApp, {
554
+ ...appTreeProps,
555
+ Component: pageModule.default,
556
+ pageProps: appTreeProps.pageProps,
557
+ router: routerShim.default
558
+ });
559
+ return typeof routerShim.wrapWithRouterContext === "function" ? routerShim.wrapWithRouterContext(appTree) : appTree;
560
+ },
561
+ Component: pageModule.default,
562
+ router: {
563
+ pathname: patternToNextFormat(route.pattern),
564
+ query,
565
+ asPath: requestAsPath
566
+ },
567
+ ctx: {
568
+ req: regenReq,
569
+ res: regenRes,
570
+ pathname: patternToNextFormat(route.pattern),
571
+ query,
572
+ asPath: requestAsPath,
573
+ locale: locale ?? currentDefaultLocale,
574
+ locales: i18nConfig?.locales,
575
+ defaultLocale: currentDefaultLocale
576
+ }
577
+ });
578
+ if (regenRes.headersSent || regenRes.writableEnded) return;
579
+ if (initialProps) {
580
+ freshRenderProps = initialProps;
581
+ freshPageProps = isUnknownRecord(initialProps.pageProps) ? initialProps.pageProps : {};
582
+ }
583
+ }
444
584
  const freshResult = await pageModule.getStaticProps({
445
585
  params: userFacingParams,
446
586
  locale: locale ?? currentDefaultLocale,
@@ -449,13 +589,20 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
449
589
  revalidateReason: "stale"
450
590
  });
451
591
  if (freshResult && "props" in freshResult) {
452
- const revalidate = typeof freshResult.revalidate === "number" ? freshResult.revalidate : 0;
592
+ const revalidate = typeof freshResult.revalidate === "number" ? freshResult.revalidate : cached.value.cacheControl?.revalidate ?? 0;
453
593
  if (revalidate > 0) {
454
- const freshProps = freshResult.props;
594
+ freshPageProps = {
595
+ ...freshPageProps,
596
+ ...freshResult.props
597
+ };
598
+ freshRenderProps = {
599
+ ...freshRenderProps,
600
+ pageProps: freshPageProps
601
+ };
455
602
  if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
456
603
  pathname: patternToNextFormat(route.pattern),
457
604
  query,
458
- asPath: url,
605
+ asPath: requestAsPath,
459
606
  navigationIsReady,
460
607
  locale: locale ?? currentDefaultLocale,
461
608
  locales: i18nConfig?.locales,
@@ -473,20 +620,18 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
473
620
  hostname: req.headers.host?.split(":", 1)[0]
474
621
  });
475
622
  }
476
- let RegenApp = null;
477
- const appPath = path.join(pagesDir, "_app");
478
- if (findFileWithExtensions(appPath, matcher)) try {
479
- RegenApp = (await runner.import(appPath)).default ?? null;
480
- } catch {}
481
623
  let el = RegenApp ? React.createElement(RegenApp, {
624
+ ...freshRenderProps,
482
625
  Component: pageModule.default,
483
- pageProps: freshProps
484
- }) : React.createElement(pageModule.default, freshProps);
626
+ pageProps: freshRenderProps.pageProps,
627
+ router: routerShim.default
628
+ }) : React.createElement(pageModule.default, freshPageProps);
485
629
  if (routerShim.wrapWithRouterContext) el = routerShim.wrapWithRouterContext(el);
486
630
  const freshBody = await renderIsrPassToStringAsync(withScriptNonce(el, scriptNonce));
487
- const viteRoot = server.config?.root;
488
- const regenPageUrl = viteRoot ? "/" + path.relative(viteRoot, route.filePath) : route.filePath;
489
- const regenAppUrl = RegenApp ? viteRoot ? "/" + path.relative(viteRoot, path.join(pagesDir, "_app")) : path.join(pagesDir, "_app") : null;
631
+ const viteRoot = server.config.root;
632
+ const viteBase = server.config.base;
633
+ const regenPageUrl = createPagesDevModuleUrl(viteRoot, route.filePath, viteBase);
634
+ const regenAppUrl = RegenApp ? createPagesDevModuleUrl(viteRoot, path.join(pagesDir, "_app"), viteBase) : null;
490
635
  const freshPagesNextData = {
491
636
  ...pagesNextData,
492
637
  __vinext: {
@@ -496,8 +641,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
496
641
  hasMiddleware
497
642
  }
498
643
  };
499
- await isrSet(cacheKey, buildPagesCacheValue(`<!DOCTYPE html><html><head></head><body><div id="__next">${freshBody}</div>${`<script>window.__NEXT_DATA__ = ${safeJsonStringify({
500
- props: { pageProps: freshProps },
644
+ await isrSet(cacheKey, buildPagesCacheValue(`<!DOCTYPE html><html><head></head><body><div id="__next">${freshBody}</div>${`<script id="__NEXT_DATA__" type="application/json">${safeJsonStringify({
645
+ props: freshRenderProps,
501
646
  page: patternToNextFormat(route.pattern),
502
647
  query: params,
503
648
  buildId: process.env.__VINEXT_BUILD_ID,
@@ -507,7 +652,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
507
652
  defaultLocale: currentDefaultLocale,
508
653
  domainLocales,
509
654
  ...freshPagesNextData
510
- })}${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);
655
+ })}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html>`, freshRenderProps), revalidate);
511
656
  setRevalidateDuration(cacheKey, revalidate);
512
657
  }
513
658
  }
@@ -539,10 +684,25 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
539
684
  defaultLocale: currentDefaultLocale,
540
685
  revalidateReason: isOnDemandRevalidate ? "on-demand" : "stale"
541
686
  };
542
- const result = await pageModule.getStaticProps(context);
543
- if (result && "props" in result) pageProps = result.props;
687
+ const generatedPageData = !isOnDemandRevalidate && cached?.isStale === false && cached?.value.value?.kind === "PAGES" && cached.value.value.generatedFromDataRequest && isUnknownRecord(cached.value.value.pageData) ? cached.value.value.pageData : null;
688
+ if (!generatedPageData && await loadAppInitialProps()) return;
689
+ const result = generatedPageData ? null : await pageModule.getStaticProps(context);
690
+ if (generatedPageData) {
691
+ renderProps = generatedPageData;
692
+ pageProps = isUnknownRecord(renderProps.pageProps) ? renderProps.pageProps : {};
693
+ }
694
+ if (result && "props" in result) {
695
+ pageProps = {
696
+ ...pageProps,
697
+ ...await Promise.resolve(result.props)
698
+ };
699
+ renderProps = {
700
+ ...renderProps,
701
+ pageProps
702
+ };
703
+ }
544
704
  if (result && "redirect" in result) {
545
- writeGsspRedirect(res, result.redirect, isDataReq);
705
+ writeGsspRedirect(res, result.redirect, isDataReq, renderProps);
546
706
  return;
547
707
  }
548
708
  if (result && "notFound" in result && result.notFound) {
@@ -559,25 +719,48 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
559
719
  }
560
720
  if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getStaticProps", pageProps);
561
721
  if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
722
+ else if (cached?.value.value?.kind === "PAGES" && cached.value.value.generatedFromDataRequest) isrRevalidateSeconds = cached.value.cacheControl?.revalidate ?? 31536e3;
723
+ }
724
+ if (typeof pageModule.getServerSideProps !== "function" && typeof pageModule.getStaticProps !== "function" && hasAppGetInitialProps) {
725
+ if (await loadAppInitialProps()) return;
562
726
  }
563
- if (typeof pageModule.getServerSideProps !== "function" && typeof pageModule.getStaticProps !== "function") {
727
+ if (typeof pageModule.getServerSideProps !== "function" && typeof pageModule.getStaticProps !== "function" && !hasAppGetInitialProps) {
564
728
  const initialProps = await loadPagesGetInitialProps(PageComponent, {
565
729
  req,
566
730
  res,
567
731
  pathname: patternToNextFormat(route.pattern),
568
732
  query,
569
- asPath: url,
733
+ asPath: requestAsPath,
570
734
  locale: locale ?? currentDefaultLocale,
571
735
  locales: i18nConfig?.locales,
572
736
  defaultLocale: currentDefaultLocale
573
737
  });
574
738
  if (res.headersSent || res.writableEnded) return;
575
- if (initialProps) pageProps = {
576
- ...pageProps,
577
- ...initialProps
578
- };
739
+ if (initialProps) {
740
+ pageProps = {
741
+ ...pageProps,
742
+ ...initialProps
743
+ };
744
+ renderProps = {
745
+ ...renderProps,
746
+ pageProps
747
+ };
748
+ }
579
749
  }
580
750
  if (isDataReq) {
751
+ if (shouldPersistFallbackData) {
752
+ const cacheKey = pagesIsrCacheKey(url.split("?")[0]);
753
+ const revalidateSeconds = isrRevalidateSeconds ?? 31536e3;
754
+ await isrSet(cacheKey, {
755
+ kind: "PAGES",
756
+ html: "",
757
+ pageData: renderProps,
758
+ generatedFromDataRequest: true,
759
+ headers: void 0,
760
+ status: void 0
761
+ }, revalidateSeconds);
762
+ setRevalidateDuration(cacheKey, revalidateSeconds);
763
+ }
581
764
  const dataHeaders = { "Content-Type": "application/json" };
582
765
  if (gsspExtraHeaders) for (const [k, v] of Object.entries(gsspExtraHeaders)) dataHeaders[k] = v;
583
766
  const dataRoutePattern = patternToNextFormat(route.pattern);
@@ -586,7 +769,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
586
769
  if (deploymentId) dataHeaders[NEXTJS_DEPLOYMENT_ID_HEADER] = deploymentId;
587
770
  }
588
771
  res.writeHead(statusCode ?? 200, dataHeaders);
589
- res.end(JSON.stringify({ pageProps }));
772
+ res.end(JSON.stringify(renderProps));
590
773
  _renderEnd = now();
591
774
  return;
592
775
  }
@@ -594,8 +777,10 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
594
777
  let element;
595
778
  const wrapWithRouterContext = routerShim.wrapWithRouterContext;
596
779
  if (AppComponent) element = createElement(AppComponent, {
780
+ ...renderProps,
597
781
  Component: PageComponent,
598
- pageProps
782
+ pageProps: renderProps.pageProps,
783
+ router: routerShim.default
599
784
  });
600
785
  else element = createElement(PageComponent, pageProps);
601
786
  if (wrapWithRouterContext) element = wrapWithRouterContext(element);
@@ -631,8 +816,11 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
631
816
  }
632
817
  if (allFontStyles.length > 0) fontHeadHTML += `<style data-vinext-fonts${nonceAttr}>${allFontStyles.join("\n")}</style>\n `;
633
818
  const viteRoot = server.config.root;
634
- const pageModuleUrl = "/" + path.relative(viteRoot, route.filePath);
635
- const appModuleUrl = AppComponent ? "/" + path.relative(viteRoot, path.join(pagesDir, "_app")) : null;
819
+ const viteBase = server.config.base;
820
+ const pageModuleUrl = createPagesDevModuleUrl(viteRoot, route.filePath, viteBase);
821
+ const pageModuleSource = createPagesDevModuleUrl(viteRoot, route.filePath, "/");
822
+ const appModuleUrl = AppComponent ? createPagesDevModuleUrl(viteRoot, path.join(pagesDir, "_app"), viteBase) : null;
823
+ const appModuleSource = AppComponent ? createPagesDevModuleUrl(viteRoot, path.join(pagesDir, "_app"), "/") : null;
636
824
  const serializedPagesNextData = {
637
825
  ...pagesNextData,
638
826
  __vinext: {
@@ -647,11 +835,22 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
647
835
  import "vinext/instrumentation-client";
648
836
  import React from "react";
649
837
  import { hydrateRoot } from "react-dom/client";
650
- import { installPagesRouterRuntime } from "vinext/pages-router-runtime";
651
- import { wrapWithRouterContext } from "next/router";
838
+ import Router, { wrapWithRouterContext, _initializePagesRouterReadyFromNextData } from "next/router";
652
839
 
840
+ const nextDataElement = document.getElementById("__NEXT_DATA__");
841
+ if (nextDataElement?.textContent) {
842
+ window.__NEXT_DATA__ = JSON.parse(nextDataElement.textContent);
843
+ window.__VINEXT_LOCALE__ = window.__NEXT_DATA__.locale;
844
+ window.__VINEXT_LOCALES__ = window.__NEXT_DATA__.locales;
845
+ window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
846
+ }
653
847
  const nextData = window.__NEXT_DATA__;
654
- const { pageProps } = nextData.props;
848
+ _initializePagesRouterReadyFromNextData(nextData);
849
+ const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
850
+ const rawPageProps = props.pageProps;
851
+ const pageProps = rawPageProps && typeof rawPageProps === "object" ? rawPageProps : {};
852
+ window.__VINEXT_PAGE_LOADERS__ = { [nextData.page]: () => import("${pageModuleSource}") };
853
+ window.__VINEXT_APP_LOADER__ = ${appModuleSource ? `() => import("${appModuleSource}")` : "undefined"};
655
854
 
656
855
  async function hydrate() {
657
856
  let hydrateRootOptions;
@@ -666,31 +865,41 @@ async function hydrate() {
666
865
  };
667
866
  }
668
867
 
669
- const pageModule = await import("${pageModuleUrl}");
868
+ const pageModule = await import("${pageModuleSource}");
670
869
  const PageComponent = pageModule.default;
671
870
  let element;
672
- ${appModuleUrl ? `
673
- const appModule = await import("${appModuleUrl}");
871
+ ${appModuleSource ? `
872
+ const appModule = await import("${appModuleSource}");
674
873
  const AppComponent = appModule.default;
675
874
  window.__VINEXT_APP__ = AppComponent;
676
- element = React.createElement(AppComponent, { Component: PageComponent, pageProps });
875
+ element = React.createElement(AppComponent, {
876
+ ...props,
877
+ Component: PageComponent,
878
+ pageProps: rawPageProps,
879
+ router: Router,
880
+ });
677
881
  ` : `
678
882
  element = React.createElement(PageComponent, pageProps);
679
883
  `}
680
- element = wrapWithRouterContext(element);
884
+ let resolveHydrationCommit;
885
+ const hydrationCommitted = new Promise((resolve) => { resolveHydrationCommit = resolve; });
886
+ element = wrapWithRouterContext(element, resolveHydrationCommit);
681
887
  const root = hydrateRoot(document.getElementById("__next"), element, hydrateRootOptions);
682
888
  window.__VINEXT_ROOT__ = root;
683
- installPagesRouterRuntime();
889
+ await hydrationCommitted;
684
890
  const hydratedAt = performance.now();
685
891
  window.__VINEXT_HYDRATED_AT = hydratedAt;
686
892
  window.__NEXT_HYDRATED = true;
687
893
  window.__NEXT_HYDRATED_AT = hydratedAt;
688
894
  window.__NEXT_HYDRATED_CB?.();
895
+ if (nextData.isFallback) {
896
+ await Router.replace(window.location.pathname + window.location.search + window.location.hash, undefined, { _h: 1, scroll: false });
897
+ }
689
898
  }
690
899
  hydrate();
691
900
  <\/script>`;
692
- const nextDataScript = createInlineScriptTag(`window.__NEXT_DATA__ = ${safeJsonStringify({
693
- props: { pageProps },
901
+ const nextDataScript = `<script id="__NEXT_DATA__" type="application/json"${nonceAttr}>${safeJsonStringify({
902
+ props: renderProps,
694
903
  page: patternToNextFormat(route.pattern),
695
904
  query: params,
696
905
  buildId: process.env.__VINEXT_BUILD_ID,
@@ -700,7 +909,7 @@ hydrate();
700
909
  defaultLocale: currentDefaultLocale,
701
910
  domainLocales,
702
911
  ...serializedPagesNextData
703
- })}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}`, scriptNonce);
912
+ })}<\/script>`;
704
913
  const docPath = path.join(pagesDir, "_document");
705
914
  let DocumentComponent = null;
706
915
  if (findFileWithExtensions(docPath, matcher)) try {
@@ -726,7 +935,7 @@ hydrate();
726
935
  documentContext: {
727
936
  pathname: patternToNextFormat(route.pattern),
728
937
  query,
729
- asPath: url
938
+ asPath: requestAsPath
730
939
  },
731
940
  enhancePageElement: (renderPageOpts) => {
732
941
  let FinalApp = AppComponent;
@@ -735,6 +944,7 @@ hydrate();
735
944
  if (renderPageOpts && typeof renderPageOpts.enhanceComponent === "function") FinalComp = renderPageOpts.enhanceComponent(FinalComp);
736
945
  let enhancedElement;
737
946
  if (FinalApp) enhancedElement = createElement(FinalApp, {
947
+ ...renderProps,
738
948
  Component: FinalComp,
739
949
  pageProps
740
950
  });
@@ -747,12 +957,14 @@ hydrate();
747
957
  const traceHTML = getClientTraceMetadataHTML(clientTraceMetadata);
748
958
  return traceHTML ? `${headHTML}\n ${traceHTML}` : headHTML;
749
959
  },
750
- setDocumentInitialHead: typeof headShim.setDocumentInitialHead === "function" ? headShim.setDocumentInitialHead : void 0
960
+ setDocumentInitialHead: typeof headShim.setDocumentInitialHead === "function" ? headShim.setDocumentInitialHead : void 0,
961
+ bufferBodyBeforeHeaders: true
751
962
  });
752
963
  _renderEnd = now();
753
964
  if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext(null);
754
965
  if (!scriptNonce && isrRevalidateSeconds !== null && isrRevalidateSeconds > 0) {
755
966
  let isrElement = AppComponent ? createElement(AppComponent, {
967
+ ...renderProps,
756
968
  Component: pageModule.default,
757
969
  pageProps
758
970
  }) : createElement(pageModule.default, pageProps);
@@ -767,7 +979,7 @@ hydrate();
767
979
  reportRequestError(e instanceof Error ? e : new Error(String(e)), {
768
980
  path: url,
769
981
  method: req.method ?? "GET",
770
- headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v ?? "")]))
982
+ headers: Object.fromEntries(Object.entries(req.headers).filter(([k]) => !k.startsWith(":")).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v ?? "")]))
771
983
  }, {
772
984
  routerKind: "Pages Router",
773
985
  routePath: route.pattern,
@@ -822,41 +1034,67 @@ async function renderErrorPage(server, runner, req, res, url, pagesDir, statusCo
822
1034
  if (!wrapFn) try {
823
1035
  wrapFn = (await importModule(runner, "next/router")).wrapWithRouterContext;
824
1036
  } catch {}
825
- let element;
826
- if (AppComponent) element = createElement(AppComponent, {
827
- Component: ErrorComponent,
828
- pageProps: errorProps
829
- });
830
- else element = createElement(ErrorComponent, errorProps);
831
- if (wrapFn) element = wrapFn(element);
832
- const bodyHtml = await renderToStringAsync(element);
833
- let html;
834
1037
  let DocumentComponent = null;
835
1038
  const docPathErr = path.join(pagesDir, "_document");
836
1039
  if (findFileWithExtensions(docPathErr, matcher)) try {
837
1040
  DocumentComponent = (await importModule(runner, docPathErr)).default ?? null;
838
1041
  } catch {}
1042
+ const createErrorElement = (FinalApp, FinalComponent) => {
1043
+ let errorElement = FinalApp ? createElement(FinalApp, {
1044
+ Component: FinalComponent,
1045
+ pageProps: errorProps
1046
+ }) : createElement(FinalComponent, errorProps);
1047
+ if (wrapFn) errorElement = wrapFn(errorElement);
1048
+ return errorElement;
1049
+ };
1050
+ const element = createErrorElement(AppComponent, ErrorComponent);
1051
+ const headShim = await importModule(runner, "next/head");
1052
+ if (typeof headShim.resetSSRHead === "function") headShim.resetSSRHead();
839
1053
  if (DocumentComponent) {
840
- const docProps = await loadUserDocumentInitialProps(DocumentComponent);
841
- let docHtml = await renderToStringAsync(docProps ? createElement(DocumentComponent, docProps) : createElement(DocumentComponent));
842
- docHtml = docHtml.replace("__NEXT_MAIN__", bodyHtml);
843
- docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", "");
844
- html = docHtml;
845
- } else html = `<!DOCTYPE html>
1054
+ const errorPathname = candidate === "_error" ? "/_error" : `/${candidate}`;
1055
+ await streamPageToResponse(res, element, {
1056
+ url,
1057
+ server,
1058
+ fontHeadHTML: "",
1059
+ scripts: "",
1060
+ DocumentComponent,
1061
+ statusCode,
1062
+ documentContext: {
1063
+ err,
1064
+ pathname: errorPathname,
1065
+ query: parseQueryString(url),
1066
+ asPath: url,
1067
+ req,
1068
+ res
1069
+ },
1070
+ enhancePageElement: (renderPageOpts) => {
1071
+ let FinalApp = AppComponent;
1072
+ let FinalComponent = ErrorComponent;
1073
+ if (renderPageOpts.enhanceApp && FinalApp) FinalApp = renderPageOpts.enhanceApp(FinalApp);
1074
+ if (renderPageOpts.enhanceComponent) FinalComponent = renderPageOpts.enhanceComponent(FinalComponent);
1075
+ return createErrorElement(FinalApp, FinalComponent);
1076
+ },
1077
+ getHeadHTML: () => typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : "",
1078
+ setDocumentInitialHead: typeof headShim.setDocumentInitialHead === "function" ? headShim.setDocumentInitialHead : void 0
1079
+ });
1080
+ } else {
1081
+ const html = `<!DOCTYPE html>
846
1082
  <html>
847
1083
  <head>
848
1084
  <meta charset="utf-8" />
849
1085
  <meta name="viewport" content="width=device-width, initial-scale=1" />
850
1086
  </head>
851
1087
  <body>
852
- <div id="__next">${bodyHtml}</div>
1088
+ <div id="__next">${await renderToStringAsync(element)}</div>
853
1089
  </body>
854
1090
  </html>`;
855
- const transformedHtml = await server.transformIndexHtml(url, html);
856
- res.writeHead(statusCode, { "Content-Type": "text/html" });
857
- res.end(transformedHtml);
1091
+ const transformedHtml = await server.transformIndexHtml(url, html);
1092
+ res.writeHead(statusCode, { "Content-Type": "text/html" });
1093
+ res.end(transformedHtml);
1094
+ }
858
1095
  return;
859
1096
  } catch {
1097
+ if (res.headersSent || res.writableEnded) return;
860
1098
  continue;
861
1099
  }
862
1100
  if (statusCode === 404) {