vinext 0.2.1 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -30
- package/dist/build/assets-ignore.js +1 -1
- package/dist/build/clean-output.js +1 -1
- package/dist/build/client-build-config.d.ts +13 -92
- package/dist/build/client-build-config.js +23 -99
- package/dist/build/css-url-assets.js +3 -3
- package/dist/build/google-fonts/fallback-metrics.js +1 -1
- package/dist/build/google-fonts/font-metadata.js +1 -1
- package/dist/build/inject-pregenerated-paths.js +1 -1
- package/dist/build/inline-css.js +2 -5
- package/dist/build/module-dependency-cache.d.ts +4 -0
- package/dist/build/module-dependency-cache.js +13 -0
- package/dist/build/next-client-runtime-manifests.js +1 -1
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/precompress.js +7 -7
- package/dist/build/prerender-paths.d.ts +23 -0
- package/dist/build/prerender-paths.js +291 -0
- package/dist/build/prerender-server-pool.js +2 -2
- package/dist/build/prerender.d.ts +12 -1
- package/dist/build/prerender.js +2 -2
- package/dist/build/preview-credentials.d.ts +11 -0
- package/dist/build/preview-credentials.js +19 -0
- package/dist/build/report.d.ts +0 -3
- package/dist/build/report.js +2 -4
- package/dist/build/run-prerender.d.ts +2 -11
- package/dist/build/run-prerender.js +2 -10
- package/dist/build/server-manifest.js +1 -1
- package/dist/build/ssr-manifest.d.ts +4 -0
- package/dist/build/ssr-manifest.js +10 -6
- package/dist/build/standalone.js +37 -37
- package/dist/cache/cache-adapters-virtual.d.ts +7 -17
- package/dist/cache/cache-adapters-virtual.js +35 -2
- package/dist/check.d.ts +0 -16
- package/dist/check.js +17 -34
- package/dist/cli.js +86 -101
- package/dist/client/instrumentation-client-inject.js +1 -1
- package/dist/client/pages-router-link-navigation.js +1 -1
- package/dist/config/config-matchers.js +2 -2
- package/dist/config/dotenv.js +1 -1
- package/dist/config/next-config.d.ts +4 -1
- package/dist/config/next-config.js +82 -16
- package/dist/config/prerender.d.ts +12 -2
- package/dist/config/prerender.js +22 -12
- package/dist/config/server-external-packages.js +1 -1
- package/dist/config/tsconfig-paths.js +7 -3
- package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
- package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
- package/dist/entries/app-rsc-entry.js +12 -5
- package/dist/entries/app-rsc-manifest.js +4 -4
- package/dist/entries/pages-client-entry.js +6 -5
- package/dist/entries/pages-server-entry.js +15 -26
- package/dist/entries/runtime-entry-module.js +2 -2
- package/dist/image/image-adapters-virtual.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +500 -338
- package/dist/init-cloudflare.js +13 -4
- package/dist/init-platform.d.ts +10 -1
- package/dist/init-platform.js +79 -13
- package/dist/init.d.ts +11 -3
- package/dist/init.js +133 -35
- package/dist/plugins/ast-utils.js +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +7 -7
- package/dist/plugins/extensionless-dynamic-import.js +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +13 -8
- package/dist/plugins/import-meta-url.js +16 -17
- package/dist/plugins/middleware-export-validation.js +1 -1
- package/dist/plugins/middleware-server-only.js +2 -2
- package/dist/plugins/og-asset-ownership.js +7 -6
- package/dist/plugins/og-assets.js +4 -5
- package/dist/plugins/optimize-imports.js +12 -13
- package/dist/plugins/postcss.js +1 -1
- package/dist/plugins/remove-console.js +1 -1
- package/dist/plugins/require-context.js +1 -1
- package/dist/plugins/sass.js +2 -2
- package/dist/plugins/server-externals-manifest.js +1 -1
- package/dist/plugins/strip-server-exports.js +1 -1
- package/dist/plugins/styled-jsx.js +3 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/routing/app-route-graph.d.ts +3 -10
- package/dist/routing/app-route-graph.js +28 -76
- package/dist/routing/app-router.d.ts +0 -5
- package/dist/routing/app-router.js +0 -5
- package/dist/routing/file-matcher.d.ts +2 -6
- package/dist/routing/file-matcher.js +10 -11
- package/dist/routing/pages-router.js +3 -3
- package/dist/server/api-handler.js +41 -33
- package/dist/server/app-browser-entry.js +15 -11
- package/dist/server/app-browser-navigation-controller.js +9 -4
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-elements-wire.d.ts +2 -1
- package/dist/server/app-fallback-renderer.d.ts +8 -0
- package/dist/server/app-fallback-renderer.js +13 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-page-boundary-render.d.ts +14 -1
- package/dist/server/app-page-boundary-render.js +107 -54
- package/dist/server/app-page-cache-render.d.ts +1 -1
- package/dist/server/app-page-dispatch.d.ts +2 -1
- package/dist/server/app-page-dispatch.js +29 -40
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +3 -3
- package/dist/server/app-page-execution.d.ts +3 -1
- package/dist/server/app-page-execution.js +31 -39
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-request.js +1 -1
- package/dist/server/app-page-route-wiring.js +4 -4
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-tree-prefetch.js +1 -1
- package/dist/server/app-rsc-cache-busting.js +1 -2
- package/dist/server/app-rsc-handler.js +2 -2
- package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
- package/dist/server/app-rsc-redirect-flight.js +71 -0
- package/dist/server/app-rsc-render-mode.d.ts +2 -5
- package/dist/server/app-rsc-render-mode.js +2 -12
- package/dist/server/app-segment-config.js +2 -2
- package/dist/server/app-server-action-execution.js +3 -3
- package/dist/server/app-ssr-entry.js +4 -1
- package/dist/server/app-ssr-stream.d.ts +2 -1
- package/dist/server/app-ssr-stream.js +4 -1
- package/dist/server/cache-proof.js +1 -1
- package/dist/server/default-global-error-module.d.ts +3 -1
- package/dist/server/default-not-found-module.d.ts +3 -1
- package/dist/server/dev-lockfile.js +2 -3
- package/dist/server/dev-module-runner.js +1 -1
- package/dist/server/dev-origin-check.d.ts +2 -2
- package/dist/server/dev-origin-check.js +2 -2
- package/dist/server/dev-route-files.js +1 -1
- package/dist/server/dev-server.js +256 -164
- package/dist/server/dev-stack-sourcemap.js +4 -3
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +3 -1
- package/dist/server/image-optimization.d.ts +12 -1
- package/dist/server/image-optimization.js +15 -3
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/instrumentation.js +2 -2
- package/dist/server/isr-cache.d.ts +12 -4
- package/dist/server/isr-cache.js +3 -3
- package/dist/server/metadata-routes.js +4 -4
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-runtime.js +1 -1
- package/dist/server/middleware.d.ts +1 -0
- package/dist/server/middleware.js +1 -1
- package/dist/server/navigation-planner.d.ts +2 -0
- package/dist/server/navigation-planner.js +8 -2
- package/dist/server/next-error-digest.d.ts +9 -24
- package/dist/server/next-error-digest.js +23 -15
- package/dist/server/operation-token.js +1 -1
- package/dist/server/pages-body-parser-config.js +2 -1
- package/dist/server/pages-dev-hydration.d.ts +14 -0
- package/dist/server/pages-dev-hydration.js +83 -0
- package/dist/server/pages-dev-module-url.js +2 -2
- package/dist/server/pages-node-compat.d.ts +13 -6
- package/dist/server/pages-node-compat.js +44 -45
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-data.js +5 -4
- package/dist/server/pages-page-handler.js +61 -29
- package/dist/server/pages-page-response.d.ts +2 -2
- package/dist/server/pages-page-response.js +2 -2
- package/dist/server/pages-preview.d.ts +26 -0
- package/dist/server/pages-preview.js +165 -0
- package/dist/server/pages-readiness.d.ts +2 -1
- package/dist/server/pages-readiness.js +4 -2
- package/dist/server/pages-request-pipeline.js +1 -1
- package/dist/server/prerender-manifest.d.ts +15 -1
- package/dist/server/prerender-manifest.js +29 -1
- package/dist/server/prod-server.d.ts +6 -5
- package/dist/server/prod-server.js +15 -15
- package/dist/server/request-pipeline.js +1 -1
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/server/static-file-cache.js +8 -9
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache.d.ts +1 -1
- package/dist/shims/cache.js +2 -1
- package/dist/shims/cdn-cache.d.ts +2 -7
- package/dist/shims/cdn-cache.js +2 -14
- package/dist/shims/constants.js +1 -1
- package/dist/shims/error-boundary.d.ts +4 -4
- package/dist/shims/error.d.ts +21 -5
- package/dist/shims/error.js +52 -14
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-utils.js +1 -1
- package/dist/shims/form.d.ts +1 -1
- package/dist/shims/head.js +3 -3
- package/dist/shims/headers.js +6 -4
- package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/link.d.ts +3 -1
- package/dist/shims/link.js +6 -3
- package/dist/shims/navigation-errors.d.ts +2 -1
- package/dist/shims/navigation-errors.js +9 -13
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +5 -5
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router.d.ts +2 -1
- package/dist/shims/router.js +18 -11
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.js +2 -2
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/thenable-params.js +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/typegen.js +9 -11
- package/dist/utils/client-build-manifest.js +2 -2
- package/dist/utils/client-entry-manifest.js +1 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/commonjs-loader.js +3 -3
- package/dist/utils/mdx-scan.js +1 -1
- package/dist/utils/path.d.ts +1 -13
- package/dist/utils/path.js +1 -15
- package/dist/utils/plugin-options.d.ts +4 -0
- package/dist/utils/plugin-options.js +8 -0
- package/dist/utils/project.d.ts +1 -7
- package/dist/utils/project.js +2 -8
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/redirect-digest.d.ts +9 -0
- package/dist/utils/redirect-digest.js +25 -0
- package/dist/utils/vinext-root.js +1 -1
- package/dist/utils/vite-version.d.ts +6 -13
- package/dist/utils/vite-version.js +68 -34
- package/package.json +33 -14
- package/dist/cloudflare/index.d.ts +0 -3
- package/dist/cloudflare/index.js +0 -3
- package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -442
- package/dist/packages/cloudflare/src/deploy-config.js +0 -150
- package/dist/packages/cloudflare/src/deploy-help.js +0 -55
- package/dist/packages/cloudflare/src/deploy.js +0 -272
- package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
- package/dist/packages/cloudflare/src/tpr.js +0 -582
- package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
- /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
- /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
- /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
3
|
import { createValidFileMatcher, findFileWithExtensions, findFileWithExts } from "../routing/file-matcher.js";
|
|
3
4
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
4
5
|
import { matchRoute } from "../routing/pages-router.js";
|
|
@@ -32,9 +33,10 @@ import { isSerializableProps } from "./pages-serializable-props.js";
|
|
|
32
33
|
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
33
34
|
import { getPagesRouteParams, matchesPagesStaticPath } from "./pages-page-data.js";
|
|
34
35
|
import { createPagesDevAssetUrl, createPagesDevModuleUrl } from "./pages-dev-module-url.js";
|
|
36
|
+
import { createPagesDevHydrationScript } from "./pages-dev-hydration.js";
|
|
35
37
|
import { getManifestFilesForModule } from "./pages-asset-tags.js";
|
|
36
|
-
import {
|
|
37
|
-
import
|
|
38
|
+
import { PAGES_PREVIEW_CACHE_CONTROL, appendPagesPreviewClearCookies, getPagesPreviewState } from "./pages-preview.js";
|
|
39
|
+
import { attachPagesRequestCookies } from "./pages-node-compat.js";
|
|
38
40
|
import React from "react";
|
|
39
41
|
import { renderToReadableStream } from "react-dom/server.edge";
|
|
40
42
|
//#region src/server/dev-server.ts
|
|
@@ -50,10 +52,37 @@ async function renderToStringAsync(element) {
|
|
|
50
52
|
await stream.allReady;
|
|
51
53
|
return new Response(stream).text();
|
|
52
54
|
}
|
|
55
|
+
function applyDevPagesPreviewHeaders(headers, preview) {
|
|
56
|
+
const removeHeader = (name) => {
|
|
57
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() === name) delete headers[key];
|
|
58
|
+
};
|
|
59
|
+
if (preview.data !== false) {
|
|
60
|
+
removeHeader("cache-control");
|
|
61
|
+
headers["Cache-Control"] = PAGES_PREVIEW_CACHE_CONTROL;
|
|
62
|
+
}
|
|
63
|
+
if (preview.shouldClear) {
|
|
64
|
+
const clearHeaders = new Headers();
|
|
65
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
66
|
+
if (key.toLowerCase() !== "set-cookie") continue;
|
|
67
|
+
if (Array.isArray(value)) for (const cookie of value) clearHeaders.append("Set-Cookie", String(cookie));
|
|
68
|
+
else clearHeaders.append("Set-Cookie", String(value));
|
|
69
|
+
delete headers[key];
|
|
70
|
+
}
|
|
71
|
+
appendPagesPreviewClearCookies(clearHeaders);
|
|
72
|
+
headers["Set-Cookie"] = clearHeaders.getSetCookie();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function applyDevPagesPreviewResponse(res, preview) {
|
|
76
|
+
const headers = res.getHeaders();
|
|
77
|
+
applyDevPagesPreviewHeaders(headers, preview);
|
|
78
|
+
for (const [name, value] of Object.entries(headers)) res.setHeader(name, value);
|
|
79
|
+
}
|
|
53
80
|
async function renderIsrPassToStringAsync(element) {
|
|
54
81
|
return await runWithServerInsertedHTMLState(() => runWithHeadState(() => _runWithCacheState(() => runWithPrivateCache(() => runWithFetchCache(async () => renderToStringAsync(element))))));
|
|
55
82
|
}
|
|
56
83
|
const DEV_STYLESHEET_ASSET_RE = /\.(?:css|scss|sass)$/i;
|
|
84
|
+
const transformedStylesheetAssetsCache = /* @__PURE__ */ new WeakMap();
|
|
85
|
+
const transformedStylesheetAssetsWatchers = /* @__PURE__ */ new WeakSet();
|
|
57
86
|
function createDevInitialStylesheetHeadHTML(options) {
|
|
58
87
|
const { ssrManifest, moduleIds, nonceAttr } = options;
|
|
59
88
|
if (!ssrManifest || moduleIds.length === 0) return "";
|
|
@@ -71,16 +100,64 @@ function createDevInitialStylesheetHeadHTML(options) {
|
|
|
71
100
|
}
|
|
72
101
|
return html;
|
|
73
102
|
}
|
|
74
|
-
async function
|
|
103
|
+
async function collectTransformedStylesheetAssets(server, moduleIds) {
|
|
104
|
+
const clientEnvironment = server.environments.client;
|
|
105
|
+
if (!clientEnvironment) return [];
|
|
106
|
+
const cachedServerAssets = transformedStylesheetAssetsCache.get(server);
|
|
107
|
+
const cache = cachedServerAssets ?? /* @__PURE__ */ new Map();
|
|
108
|
+
if (!cachedServerAssets) transformedStylesheetAssetsCache.set(server, cache);
|
|
109
|
+
if (!transformedStylesheetAssetsWatchers.has(server)) {
|
|
110
|
+
transformedStylesheetAssetsWatchers.add(server);
|
|
111
|
+
const clearCache = () => cache.clear();
|
|
112
|
+
server.watcher.on("add", clearCache);
|
|
113
|
+
server.watcher.on("change", clearCache);
|
|
114
|
+
server.watcher.on("unlink", clearCache);
|
|
115
|
+
}
|
|
116
|
+
const cacheKey = moduleIds.filter((moduleId) => Boolean(moduleId)).join("\0");
|
|
117
|
+
const cachedAssets = cache.get(cacheKey);
|
|
118
|
+
if (cachedAssets) return cachedAssets;
|
|
119
|
+
const assets = /* @__PURE__ */ new Set();
|
|
120
|
+
const seenModules = /* @__PURE__ */ new Set();
|
|
121
|
+
async function visitModule(moduleUrl) {
|
|
122
|
+
if (seenModules.has(moduleUrl)) return;
|
|
123
|
+
seenModules.add(moduleUrl);
|
|
124
|
+
try {
|
|
125
|
+
await clientEnvironment.transformRequest(moduleUrl);
|
|
126
|
+
const moduleNode = await clientEnvironment.moduleGraph.getModuleByUrl(moduleUrl);
|
|
127
|
+
if (!moduleNode) return;
|
|
128
|
+
for (const importedModule of moduleNode.importedModules) if (importedModule.type === "css" || /\.(?:css|scss|sass)(?:$|[?#])/i.test(importedModule.url)) {
|
|
129
|
+
if (importedModule.url.startsWith("//")) continue;
|
|
130
|
+
const assetUrl = importedModule.url.startsWith("\0") ? `/@id/__x00__${importedModule.url.slice(1)}${importedModule.url.includes("?") ? "&" : "?"}direct` : importedModule.url;
|
|
131
|
+
assets.add(assetUrl);
|
|
132
|
+
} else if (importedModule.type === "js") await visitModule(importedModule.url);
|
|
133
|
+
} catch {}
|
|
134
|
+
}
|
|
135
|
+
for (const moduleId of moduleIds) {
|
|
136
|
+
if (!moduleId) continue;
|
|
137
|
+
await visitModule(createPagesDevModuleUrl(server.config.root, moduleId, "/"));
|
|
138
|
+
}
|
|
139
|
+
const result = [...assets];
|
|
140
|
+
cache.set(cacheKey, result);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
async function collectDevInitialStylesheetHeadHTML(server, runner, moduleIds, nonceAttr) {
|
|
144
|
+
let manifestHTML = "";
|
|
75
145
|
try {
|
|
76
|
-
|
|
146
|
+
manifestHTML = createDevInitialStylesheetHeadHTML({
|
|
77
147
|
ssrManifest: (await runner.import("virtual:vinext-pages-client-assets")).default?.ssrManifest,
|
|
78
148
|
moduleIds,
|
|
79
149
|
nonceAttr
|
|
80
150
|
});
|
|
81
|
-
} catch {
|
|
82
|
-
|
|
151
|
+
} catch {}
|
|
152
|
+
const transformedAssets = await collectTransformedStylesheetAssets(server, moduleIds);
|
|
153
|
+
if (transformedAssets.length === 0) return manifestHTML;
|
|
154
|
+
let html = manifestHTML;
|
|
155
|
+
for (const asset of transformedAssets) {
|
|
156
|
+
const href = asset.startsWith("/") ? asset : createPagesDevAssetUrl(asset);
|
|
157
|
+
if (html.includes(`href="${escapeHtmlAttr(href)}"`)) continue;
|
|
158
|
+
html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(href)}" />\n `;
|
|
83
159
|
}
|
|
160
|
+
return html;
|
|
84
161
|
}
|
|
85
162
|
/**
|
|
86
163
|
* Emit a `getServerSideProps` / `getStaticProps` `{ redirect }` result.
|
|
@@ -180,7 +257,7 @@ async function streamPageToResponse(res, element, options) {
|
|
|
180
257
|
const suffix = transformedShell.slice(markerIdx + 25);
|
|
181
258
|
const bufferedBody = bufferBodyBeforeHeaders ? await new Response(bodyStream).text() : null;
|
|
182
259
|
const headers = {
|
|
183
|
-
"Content-Type": "text/html",
|
|
260
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
184
261
|
"Transfer-Encoding": "chunked"
|
|
185
262
|
};
|
|
186
263
|
if (extraHeaders) for (const [key, val] of Object.entries(extraHeaders)) if (Array.isArray(val)) res.setHeader(key, val);
|
|
@@ -288,7 +365,10 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
288
365
|
res.end("{}");
|
|
289
366
|
return;
|
|
290
367
|
}
|
|
291
|
-
await
|
|
368
|
+
await runWithRequestContext(createRequestContext(), async () => {
|
|
369
|
+
await _alsRegistration;
|
|
370
|
+
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, void 0, matcher, void 0, reactStrictMode);
|
|
371
|
+
});
|
|
292
372
|
return;
|
|
293
373
|
}
|
|
294
374
|
const { route, params } = match;
|
|
@@ -296,7 +376,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
296
376
|
const parsedResolvedUrl = new URL(localeStrippedUrl, "http://vinext.local");
|
|
297
377
|
const originalRequestSearch = new URL(originalUrl, "http://vinext.local").search;
|
|
298
378
|
const gsspResolvedUrl = parsedResolvedUrl.pathname + originalRequestSearch;
|
|
299
|
-
const requestAsPath = isDataReq ? gsspResolvedUrl : originalUrl;
|
|
379
|
+
const requestAsPath = isDataReq ? gsspResolvedUrl : i18nConfig ? extractLocaleFromUrl$1(originalUrl, i18nConfig, locale).url : originalUrl;
|
|
300
380
|
const userFacingParams = route.isDynamic ? params : null;
|
|
301
381
|
const query = mergeRouteParamsIntoQuery(parseQueryString(url), params);
|
|
302
382
|
return runWithRequestContext(createRequestContext(), async () => {
|
|
@@ -316,16 +396,24 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
316
396
|
});
|
|
317
397
|
}
|
|
318
398
|
const pageModule = await importModule(runner, route.filePath);
|
|
399
|
+
const requestPreview = typeof pageModule.getStaticProps === "function" || typeof pageModule.getServerSideProps === "function" ? getPagesPreviewState(req.headers.cookie, { isOnDemandRevalidate: isOnDemandRevalidateRequest(req.headers[PRERENDER_REVALIDATE_HEADER]) }) : {
|
|
400
|
+
data: false,
|
|
401
|
+
shouldClear: false
|
|
402
|
+
};
|
|
403
|
+
const requestPreviewData = requestPreview.data;
|
|
319
404
|
let AppComponent = null;
|
|
320
405
|
const appPath = path.join(pagesDir, "_app");
|
|
321
406
|
if (findFileWithExtensions(appPath, matcher)) try {
|
|
322
407
|
AppComponent = (await importModule(runner, appPath)).default ?? null;
|
|
323
408
|
} catch {}
|
|
324
|
-
const pagesNextData =
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
409
|
+
const pagesNextData = {
|
|
410
|
+
...buildPagesReadinessNextData({
|
|
411
|
+
pageModule,
|
|
412
|
+
appComponent: AppComponent,
|
|
413
|
+
hasRewrites
|
|
414
|
+
}),
|
|
415
|
+
...requestPreviewData === false ? {} : { isPreview: true }
|
|
416
|
+
};
|
|
329
417
|
const navigationIsReady = typeof routerShim.getPagesNavigationIsReadyFromSerializedState === "function" ? routerShim.getPagesNavigationIsReadyFromSerializedState(patternToNextFormat(route.pattern), new URL(url, "http://_").search, pagesNextData) : true;
|
|
330
418
|
if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
|
|
331
419
|
pathname: patternToNextFormat(route.pattern),
|
|
@@ -336,7 +424,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
336
424
|
locale: locale ?? currentDefaultLocale,
|
|
337
425
|
locales: i18nConfig?.locales,
|
|
338
426
|
defaultLocale: currentDefaultLocale,
|
|
339
|
-
domainLocales
|
|
427
|
+
domainLocales,
|
|
428
|
+
isPreview: requestPreviewData !== false
|
|
340
429
|
});
|
|
341
430
|
_compileEnd = now();
|
|
342
431
|
const PageComponent = pageModule.default;
|
|
@@ -365,10 +454,11 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
365
454
|
}
|
|
366
455
|
let pageProps = {};
|
|
367
456
|
let renderProps = { pageProps };
|
|
457
|
+
if (requestPreviewData !== false) renderProps.__N_PREVIEW = true;
|
|
368
458
|
let isrRevalidateSeconds = null;
|
|
369
459
|
let isFallbackRender = false;
|
|
370
460
|
let shouldPersistFallbackData = false;
|
|
371
|
-
let staticPropsPreviewData =
|
|
461
|
+
let staticPropsPreviewData = requestPreviewData;
|
|
372
462
|
if (typeof pageModule.getStaticPaths === "function" && route.isDynamic) {
|
|
373
463
|
const pathsResult = await pageModule.getStaticPaths({
|
|
374
464
|
locales: i18nConfig?.locales ?? [],
|
|
@@ -378,7 +468,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
378
468
|
const paths = pathsResult?.paths ?? [];
|
|
379
469
|
const routeParams = getPagesRouteParams(patternToNextFormat(route.pattern));
|
|
380
470
|
const isValidPath = paths.some((pathEntry) => matchesPagesStaticPath(pathEntry, params, routeParams, url));
|
|
381
|
-
if (fallback === false && !isValidPath) {
|
|
471
|
+
if (fallback === false && !isValidPath && requestPreviewData === false) {
|
|
382
472
|
if (isDataReq) {
|
|
383
473
|
const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
|
|
384
474
|
const notFoundHeaders = { "Content-Type": "application/json" };
|
|
@@ -387,13 +477,13 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
387
477
|
res.end("{}");
|
|
388
478
|
return;
|
|
389
479
|
}
|
|
390
|
-
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, matcher);
|
|
480
|
+
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, matcher, void 0, reactStrictMode);
|
|
391
481
|
return;
|
|
392
482
|
}
|
|
393
483
|
const userAgentHeader = req.headers["user-agent"];
|
|
394
484
|
const userAgent = Array.isArray(userAgentHeader) ? userAgentHeader[0] : userAgentHeader;
|
|
395
485
|
const isBotRequest = !!userAgent && isBotUserAgent(userAgent, htmlLimitedBots);
|
|
396
|
-
if (fallback === true && !isValidPath && !isDataReq && !isBotRequest) {
|
|
486
|
+
if (fallback === true && !isValidPath && !isDataReq && !isBotRequest && requestPreviewData === false) {
|
|
397
487
|
isFallbackRender = (await isrGet(pagesIsrCacheKey(url.split("?")[0])))?.value.value?.kind !== "PAGES";
|
|
398
488
|
if (isFallbackRender && typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
|
|
399
489
|
pathname: patternToNextFormat(route.pattern),
|
|
@@ -438,6 +528,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
438
528
|
if (appResult.kind === "render") {
|
|
439
529
|
pageProps = appResult.pageProps;
|
|
440
530
|
renderProps = appResult.renderProps;
|
|
531
|
+
if (requestPreviewData !== false) renderProps.__N_PREVIEW = true;
|
|
441
532
|
}
|
|
442
533
|
return false;
|
|
443
534
|
}
|
|
@@ -448,7 +539,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
448
539
|
__N_SSP: true
|
|
449
540
|
};
|
|
450
541
|
const headersBeforeGSSP = new Set(Object.keys(res.getHeaders()));
|
|
451
|
-
const previewData =
|
|
542
|
+
const previewData = requestPreviewData;
|
|
452
543
|
const previewContext = previewData === false ? {} : {
|
|
453
544
|
draftMode: true,
|
|
454
545
|
preview: true,
|
|
@@ -482,6 +573,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
482
573
|
return;
|
|
483
574
|
}
|
|
484
575
|
if (result && "notFound" in result && result.notFound) {
|
|
576
|
+
applyDevPagesPreviewResponse(res, requestPreview);
|
|
485
577
|
if (isDataReq) {
|
|
486
578
|
const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
|
|
487
579
|
const notFoundHeaders = { "Content-Type": "application/json" };
|
|
@@ -490,7 +582,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
490
582
|
res.end("{}");
|
|
491
583
|
return;
|
|
492
584
|
}
|
|
493
|
-
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
585
|
+
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, void 0, void 0, reactStrictMode);
|
|
494
586
|
return;
|
|
495
587
|
}
|
|
496
588
|
if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getServerSideProps", pageProps);
|
|
@@ -519,7 +611,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
519
611
|
const cacheKey = pagesIsrCacheKey(url.split("?")[0]);
|
|
520
612
|
const cached = await isrGet(cacheKey);
|
|
521
613
|
const isOnDemandRevalidate = isOnDemandRevalidateRequest(req.headers[PRERENDER_REVALIDATE_HEADER]);
|
|
522
|
-
const previewData =
|
|
614
|
+
const previewData = requestPreviewData;
|
|
523
615
|
staticPropsPreviewData = previewData;
|
|
524
616
|
const previewContext = previewData === false ? {} : {
|
|
525
617
|
draftMode: true,
|
|
@@ -535,7 +627,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
535
627
|
revalidateSeconds: getRevalidateDuration(cacheKey) ?? 60
|
|
536
628
|
});
|
|
537
629
|
const hitHeaders = {
|
|
538
|
-
"Content-Type": "text/html",
|
|
630
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
539
631
|
...buildCacheStateHeaders("HIT"),
|
|
540
632
|
"Cache-Control": hitCacheControl
|
|
541
633
|
};
|
|
@@ -682,7 +774,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
682
774
|
hasMiddleware
|
|
683
775
|
}
|
|
684
776
|
};
|
|
685
|
-
|
|
777
|
+
const freshHtml = `<!DOCTYPE html><html><head></head><body><div id="__next">${freshBody}</div>${`<script id="__NEXT_DATA__" type="application/json">${safeJsonStringify({
|
|
686
778
|
props: freshRenderProps,
|
|
687
779
|
page: patternToNextFormat(route.pattern),
|
|
688
780
|
query: params,
|
|
@@ -693,7 +785,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
693
785
|
defaultLocale: currentDefaultLocale,
|
|
694
786
|
domainLocales,
|
|
695
787
|
...freshPagesNextData
|
|
696
|
-
})}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html
|
|
788
|
+
})}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html>`;
|
|
789
|
+
await isrSet(cacheKey, buildPagesCacheValue(freshHtml, freshRenderProps), revalidate);
|
|
697
790
|
setRevalidateDuration(cacheKey, revalidate);
|
|
698
791
|
}
|
|
699
792
|
}
|
|
@@ -709,7 +802,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
709
802
|
revalidateSeconds: getRevalidateDuration(cacheKey) ?? 60
|
|
710
803
|
});
|
|
711
804
|
const staleHeaders = {
|
|
712
|
-
"Content-Type": "text/html",
|
|
805
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
713
806
|
...buildCacheStateHeaders("STALE"),
|
|
714
807
|
"Cache-Control": staleCacheControl
|
|
715
808
|
};
|
|
@@ -748,6 +841,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
748
841
|
return;
|
|
749
842
|
}
|
|
750
843
|
if (result && "notFound" in result && result.notFound) {
|
|
844
|
+
applyDevPagesPreviewResponse(res, requestPreview);
|
|
751
845
|
if (isDataReq) {
|
|
752
846
|
const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
|
|
753
847
|
const notFoundHeaders = { "Content-Type": "application/json" };
|
|
@@ -756,7 +850,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
756
850
|
res.end("{}");
|
|
757
851
|
return;
|
|
758
852
|
}
|
|
759
|
-
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
853
|
+
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, void 0, void 0, reactStrictMode);
|
|
760
854
|
return;
|
|
761
855
|
}
|
|
762
856
|
if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getStaticProps", pageProps);
|
|
@@ -806,6 +900,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
806
900
|
const dataHeaders = { "Content-Type": "application/json" };
|
|
807
901
|
if ((statusCode ?? 200) === 200) dataHeaders["x-nextjs-matched-path"] = `${locale ? `/${locale}` : ""}${patternToNextFormat(route.pattern)}`;
|
|
808
902
|
if (gsspExtraHeaders) for (const [k, v] of Object.entries(gsspExtraHeaders)) dataHeaders[k] = v;
|
|
903
|
+
applyDevPagesPreviewHeaders(dataHeaders, requestPreview);
|
|
809
904
|
const dataRoutePattern = patternToNextFormat(route.pattern);
|
|
810
905
|
if (dataRoutePattern !== "/_error" && dataRoutePattern !== "/500") {
|
|
811
906
|
const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
|
|
@@ -833,7 +928,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
833
928
|
if (typeof dynamicShim.flushPreloads === "function") await dynamicShim.flushPreloads();
|
|
834
929
|
const nonceAttr = createNonceAttribute(scriptNonce);
|
|
835
930
|
let fontHeadHTML = "";
|
|
836
|
-
const assetHeadHTML = await collectDevInitialStylesheetHeadHTML(runner, [AppComponent ? findFileWithExts(pagesDir, "_app", matcher) : null, route.filePath], nonceAttr);
|
|
931
|
+
const assetHeadHTML = await collectDevInitialStylesheetHeadHTML(server, runner, [AppComponent ? findFileWithExts(pagesDir, "_app", matcher) : null, route.filePath], nonceAttr);
|
|
837
932
|
const allFontStyles = [];
|
|
838
933
|
const allFontPreloads = [];
|
|
839
934
|
try {
|
|
@@ -874,77 +969,13 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
874
969
|
hasMiddleware
|
|
875
970
|
}
|
|
876
971
|
};
|
|
877
|
-
const hydrationScript =
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
const nextDataElement = document.getElementById("__NEXT_DATA__");
|
|
885
|
-
if (nextDataElement?.textContent) {
|
|
886
|
-
window.__NEXT_DATA__ = JSON.parse(nextDataElement.textContent);
|
|
887
|
-
window.__VINEXT_LOCALE__ = window.__NEXT_DATA__.locale;
|
|
888
|
-
window.__VINEXT_LOCALES__ = window.__NEXT_DATA__.locales;
|
|
889
|
-
window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
|
|
890
|
-
}
|
|
891
|
-
const nextData = window.__NEXT_DATA__;
|
|
892
|
-
_initializePagesRouterReadyFromNextData(nextData);
|
|
893
|
-
const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
|
|
894
|
-
const rawPageProps = props.pageProps;
|
|
895
|
-
const pageProps = rawPageProps && typeof rawPageProps === "object" ? rawPageProps : {};
|
|
896
|
-
window.__VINEXT_PAGE_LOADERS__ = { [nextData.page]: () => import("${pageModuleSource}") };
|
|
897
|
-
window.__VINEXT_APP_LOADER__ = ${appModuleSource ? `() => import("${appModuleSource}")` : "undefined"};
|
|
898
|
-
// reactStrictMode flag — read by wrapWithRouterContext so the <React.StrictMode>
|
|
899
|
-
// wrap is applied on initial hydration and every navigation (matches Next.js).
|
|
900
|
-
window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(reactStrictMode === true)};
|
|
901
|
-
|
|
902
|
-
async function hydrate() {
|
|
903
|
-
let hydrateRootOptions;
|
|
904
|
-
if (import.meta.env.DEV) {
|
|
905
|
-
const overlay = await import("vinext/dev-error-overlay");
|
|
906
|
-
overlay.installDevErrorOverlay();
|
|
907
|
-
overlay.installViteHmrErrorHandler(import.meta.hot);
|
|
908
|
-
overlay.reportInitialDevServerErrors();
|
|
909
|
-
hydrateRootOptions = {
|
|
910
|
-
onCaughtError: overlay.devOnCaughtError,
|
|
911
|
-
onUncaughtError: overlay.devOnUncaughtError,
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
const pageModule = await import("${pageModuleSource}");
|
|
916
|
-
const PageComponent = pageModule.default;
|
|
917
|
-
let element;
|
|
918
|
-
${appModuleSource ? `
|
|
919
|
-
const appModule = await import("${appModuleSource}");
|
|
920
|
-
const AppComponent = appModule.default;
|
|
921
|
-
window.__VINEXT_APP__ = AppComponent;
|
|
922
|
-
element = React.createElement(AppComponent, {
|
|
923
|
-
...props,
|
|
924
|
-
Component: PageComponent,
|
|
925
|
-
pageProps: rawPageProps,
|
|
926
|
-
router: Router,
|
|
927
|
-
});
|
|
928
|
-
` : `
|
|
929
|
-
element = React.createElement(PageComponent, pageProps);
|
|
930
|
-
`}
|
|
931
|
-
let resolveHydrationCommit;
|
|
932
|
-
const hydrationCommitted = new Promise((resolve) => { resolveHydrationCommit = resolve; });
|
|
933
|
-
element = wrapWithRouterContext(element, resolveHydrationCommit);
|
|
934
|
-
const root = hydrateRoot(document.getElementById("__next"), element, hydrateRootOptions);
|
|
935
|
-
window.__VINEXT_ROOT__ = root;
|
|
936
|
-
await hydrationCommitted;
|
|
937
|
-
const hydratedAt = performance.now();
|
|
938
|
-
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
939
|
-
window.__NEXT_HYDRATED = true;
|
|
940
|
-
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
941
|
-
window.__NEXT_HYDRATED_CB?.();
|
|
942
|
-
if (nextData.isFallback) {
|
|
943
|
-
await Router.replace(window.location.pathname + window.location.search + window.location.hash, undefined, { _h: 1, scroll: false });
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
hydrate();
|
|
947
|
-
<\/script>`;
|
|
972
|
+
const hydrationScript = createPagesDevHydrationScript({
|
|
973
|
+
appModuleSource,
|
|
974
|
+
pageModuleSource,
|
|
975
|
+
reactStrictMode: reactStrictMode === true,
|
|
976
|
+
replaceFallbackRoute: true,
|
|
977
|
+
scriptNonce
|
|
978
|
+
});
|
|
948
979
|
const nextDataScript = `<script id="__NEXT_DATA__" type="application/json"${nonceAttr}>${safeJsonStringify({
|
|
949
980
|
props: renderProps,
|
|
950
981
|
page: patternToNextFormat(route.pattern),
|
|
@@ -964,11 +995,12 @@ hydrate();
|
|
|
964
995
|
} catch {}
|
|
965
996
|
const allScripts = `${nextDataScript}\n ${createInlineScriptTag(`window.__VINEXT_PAGE_PATTERNS__=${safeJsonStringify(pagePatterns)}`, scriptNonce)}\n ${hydrationScript}`;
|
|
966
997
|
const extraHeaders = { ...gsspExtraHeaders };
|
|
967
|
-
if (isrRevalidateSeconds) if (scriptNonce) extraHeaders["Cache-Control"] = NO_STORE_CACHE_CONTROL;
|
|
998
|
+
if (requestPreviewData === false && isrRevalidateSeconds) if (scriptNonce) extraHeaders["Cache-Control"] = NO_STORE_CACHE_CONTROL;
|
|
968
999
|
else {
|
|
969
1000
|
extraHeaders["Cache-Control"] = buildMissIsrCacheControl(isrRevalidateSeconds);
|
|
970
1001
|
Object.assign(extraHeaders, buildCacheStateHeaders("MISS"));
|
|
971
1002
|
}
|
|
1003
|
+
applyDevPagesPreviewHeaders(extraHeaders, requestPreview);
|
|
972
1004
|
if (allFontPreloads.length > 0) extraHeaders["Link"] = allFontPreloads.map((p) => `<${p.href}>; rel=preload; as=font; type=${p.type}; crossorigin`).join(", ");
|
|
973
1005
|
await streamPageToResponse(res, withScriptNonce(element, scriptNonce), {
|
|
974
1006
|
url,
|
|
@@ -1038,7 +1070,7 @@ hydrate();
|
|
|
1038
1070
|
routeType: "render"
|
|
1039
1071
|
}).catch(() => {});
|
|
1040
1072
|
try {
|
|
1041
|
-
await renderErrorPage(server, runner, req, res, url, pagesDir, 500, void 0, matcher, e instanceof Error ? e : new Error(String(e)));
|
|
1073
|
+
await renderErrorPage(server, runner, req, res, url, pagesDir, 500, void 0, matcher, e instanceof Error ? e : new Error(String(e)), reactStrictMode);
|
|
1042
1074
|
} catch (fallbackErr) {
|
|
1043
1075
|
res.statusCode = 500;
|
|
1044
1076
|
res.end(`Internal Server Error: ${fallbackErr.message}`);
|
|
@@ -1055,71 +1087,127 @@ hydrate();
|
|
|
1055
1087
|
* - 500: pages/500.tsx -> pages/_error.tsx -> default
|
|
1056
1088
|
* - other: pages/_error.tsx -> default
|
|
1057
1089
|
*/
|
|
1058
|
-
async function renderErrorPage(server, runner, req, res, url, pagesDir, statusCode, wrapWithRouterContext, fileMatcher, err) {
|
|
1090
|
+
async function renderErrorPage(server, runner, req, res, url, pagesDir, statusCode, wrapWithRouterContext, fileMatcher, err, reactStrictMode = false) {
|
|
1059
1091
|
attachPagesRequestCookies(req);
|
|
1060
1092
|
const matcher = fileMatcher ?? createValidFileMatcher();
|
|
1061
1093
|
const candidates = statusCode === 404 ? ["404", "_error"] : statusCode === 500 ? ["500", "_error"] : ["_error"];
|
|
1062
|
-
for (const candidate of candidates)
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
res
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1094
|
+
for (const candidate of candidates) {
|
|
1095
|
+
let errorRouterShim = null;
|
|
1096
|
+
try {
|
|
1097
|
+
const errorAssetPath = findFileWithExts(pagesDir, candidate, matcher);
|
|
1098
|
+
if (!errorAssetPath && candidate !== "_error") continue;
|
|
1099
|
+
const ErrorComponent = (await importModule(runner, errorAssetPath ?? "next/error")).default;
|
|
1100
|
+
if (!ErrorComponent) continue;
|
|
1101
|
+
let AppComponent = null;
|
|
1102
|
+
const appPathErr = path.join(pagesDir, "_app");
|
|
1103
|
+
const appAssetPath = findFileWithExts(pagesDir, "_app", matcher);
|
|
1104
|
+
if (findFileWithExtensions(appPathErr, matcher)) try {
|
|
1105
|
+
AppComponent = (await importModule(runner, appAssetPath ?? appPathErr)).default ?? null;
|
|
1106
|
+
} catch {}
|
|
1107
|
+
const createElement = React.createElement;
|
|
1108
|
+
res.statusCode = statusCode;
|
|
1109
|
+
const errorPage = candidate === "_error" ? "/_error" : `/${candidate}`;
|
|
1110
|
+
const errorRouter = {
|
|
1111
|
+
pathname: errorPage,
|
|
1112
|
+
query: parseQueryString(url),
|
|
1113
|
+
asPath: url
|
|
1114
|
+
};
|
|
1115
|
+
try {
|
|
1116
|
+
errorRouterShim = await importModule(runner, "next/router");
|
|
1117
|
+
if (typeof errorRouterShim.setSSRContext === "function") errorRouterShim.setSSRContext({
|
|
1118
|
+
...errorRouter,
|
|
1119
|
+
navigationIsReady: true
|
|
1120
|
+
});
|
|
1121
|
+
} catch {}
|
|
1122
|
+
const serverRouter = errorRouterShim?.default ?? errorRouter;
|
|
1123
|
+
const wrapFn = wrapWithRouterContext ?? errorRouterShim?.wrapWithRouterContext;
|
|
1124
|
+
const initialErrorProps = await loadPagesGetInitialProps(ErrorComponent, {
|
|
1125
|
+
req,
|
|
1126
|
+
res,
|
|
1127
|
+
err,
|
|
1128
|
+
pathname: errorPage,
|
|
1129
|
+
query: errorRouter.query,
|
|
1130
|
+
asPath: url
|
|
1131
|
+
});
|
|
1132
|
+
if (res.headersSent || res.writableEnded) return;
|
|
1133
|
+
const errorProps = {
|
|
1134
|
+
...initialErrorProps,
|
|
1135
|
+
statusCode
|
|
1136
|
+
};
|
|
1137
|
+
let renderProps;
|
|
1138
|
+
if (AppComponent && hasPagesGetInitialProps(AppComponent)) {
|
|
1139
|
+
const appInitialProps = await loadPagesGetInitialProps(AppComponent, {
|
|
1140
|
+
AppTree: (appTreeProps) => {
|
|
1141
|
+
const appTree = createElement(AppComponent, {
|
|
1142
|
+
...appTreeProps,
|
|
1143
|
+
Component: ErrorComponent,
|
|
1144
|
+
router: serverRouter
|
|
1145
|
+
});
|
|
1146
|
+
return wrapFn ? wrapFn(appTree) : appTree;
|
|
1147
|
+
},
|
|
1148
|
+
Component: ErrorComponent,
|
|
1149
|
+
router: serverRouter,
|
|
1150
|
+
ctx: {
|
|
1151
|
+
req,
|
|
1152
|
+
res,
|
|
1153
|
+
err,
|
|
1154
|
+
pathname: errorPage,
|
|
1155
|
+
query: errorRouter.query,
|
|
1156
|
+
asPath: url
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
if (res.headersSent || res.writableEnded) return;
|
|
1160
|
+
renderProps = appInitialProps ?? {};
|
|
1161
|
+
} else renderProps = { pageProps: errorProps };
|
|
1162
|
+
let DocumentComponent = null;
|
|
1163
|
+
const docPathErr = path.join(pagesDir, "_document");
|
|
1164
|
+
if (findFileWithExtensions(docPathErr, matcher)) try {
|
|
1165
|
+
DocumentComponent = (await importModule(runner, docPathErr)).default ?? null;
|
|
1166
|
+
} catch {}
|
|
1167
|
+
const createErrorElement = (FinalApp, FinalComponent) => {
|
|
1168
|
+
let errorElement = FinalApp ? createElement(FinalApp, {
|
|
1169
|
+
...renderProps,
|
|
1170
|
+
Component: FinalComponent,
|
|
1171
|
+
router: serverRouter
|
|
1172
|
+
}) : createElement(FinalComponent, errorProps);
|
|
1173
|
+
if (wrapFn) errorElement = wrapFn(errorElement);
|
|
1174
|
+
return errorElement;
|
|
1175
|
+
};
|
|
1176
|
+
const element = createErrorElement(AppComponent, ErrorComponent);
|
|
1177
|
+
const headShim = await importModule(runner, "next/head");
|
|
1178
|
+
if (typeof headShim.resetSSRHead === "function") headShim.resetSSRHead();
|
|
1179
|
+
const responseHeaders = typeof res.getHeaders === "function" ? res.getHeaders() : void 0;
|
|
1180
|
+
const scriptNonce = getScriptNonceFromNodeHeaderSources(req.headers, responseHeaders);
|
|
1181
|
+
const nonceAttr = createNonceAttribute(scriptNonce);
|
|
1182
|
+
const assetHeadHTML = await collectDevInitialStylesheetHeadHTML(server, runner, [appAssetPath, errorAssetPath], nonceAttr);
|
|
1183
|
+
const errorModuleSource = errorAssetPath ? createPagesDevModuleUrl(server.config.root, errorAssetPath, "/") : "next/error";
|
|
1184
|
+
const appModuleSource = appAssetPath ? createPagesDevModuleUrl(server.config.root, appAssetPath, "/") : null;
|
|
1185
|
+
const errorScripts = `${`<script id="__NEXT_DATA__" type="application/json"${nonceAttr}>${safeJsonStringify({
|
|
1186
|
+
props: renderProps,
|
|
1187
|
+
page: errorPage,
|
|
1188
|
+
query: parseQueryString(url),
|
|
1189
|
+
buildId: process.env.__VINEXT_BUILD_ID,
|
|
1190
|
+
isFallback: false
|
|
1191
|
+
})}<\/script>`}\n${createPagesDevHydrationScript({
|
|
1192
|
+
appModuleSource,
|
|
1193
|
+
forceRouterReady: true,
|
|
1194
|
+
normalizePageProps: false,
|
|
1195
|
+
pageModuleSource: errorModuleSource,
|
|
1196
|
+
reactStrictMode: reactStrictMode === true,
|
|
1197
|
+
scriptNonce,
|
|
1198
|
+
setPagePatternsFromNextData: true
|
|
1199
|
+
})}`;
|
|
1200
|
+
if (DocumentComponent) await streamPageToResponse(res, element, {
|
|
1113
1201
|
url,
|
|
1114
1202
|
server,
|
|
1115
1203
|
fontHeadHTML: "",
|
|
1116
1204
|
assetHeadHTML,
|
|
1117
|
-
scripts:
|
|
1205
|
+
scripts: errorScripts,
|
|
1118
1206
|
DocumentComponent,
|
|
1119
1207
|
statusCode,
|
|
1120
1208
|
documentContext: {
|
|
1121
1209
|
err,
|
|
1122
|
-
pathname:
|
|
1210
|
+
pathname: errorPage,
|
|
1123
1211
|
query: parseQueryString(url),
|
|
1124
1212
|
asPath: url,
|
|
1125
1213
|
req,
|
|
@@ -1135,8 +1223,8 @@ async function renderErrorPage(server, runner, req, res, url, pagesDir, statusCo
|
|
|
1135
1223
|
getHeadHTML: () => typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : "",
|
|
1136
1224
|
setDocumentInitialHead: typeof headShim.setDocumentInitialHead === "function" ? headShim.setDocumentInitialHead : void 0
|
|
1137
1225
|
});
|
|
1138
|
-
|
|
1139
|
-
|
|
1226
|
+
else {
|
|
1227
|
+
const html = `<!DOCTYPE html>
|
|
1140
1228
|
<html>
|
|
1141
1229
|
<head>
|
|
1142
1230
|
<meta charset="utf-8" />
|
|
@@ -1145,16 +1233,20 @@ async function renderErrorPage(server, runner, req, res, url, pagesDir, statusCo
|
|
|
1145
1233
|
</head>
|
|
1146
1234
|
<body>
|
|
1147
1235
|
<div id="__next">${await renderToStringAsync(element)}</div>
|
|
1236
|
+
${errorScripts}
|
|
1148
1237
|
</body>
|
|
1149
1238
|
</html>`;
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1239
|
+
const transformedHtml = await server.transformIndexHtml(url, html);
|
|
1240
|
+
res.writeHead(statusCode, { "Content-Type": "text/html; charset=utf-8" });
|
|
1241
|
+
res.end(transformedHtml);
|
|
1242
|
+
}
|
|
1243
|
+
return;
|
|
1244
|
+
} catch {
|
|
1245
|
+
if (res.headersSent || res.writableEnded) return;
|
|
1246
|
+
continue;
|
|
1247
|
+
} finally {
|
|
1248
|
+
if (typeof errorRouterShim?.setSSRContext === "function") errorRouterShim.setSSRContext(null);
|
|
1153
1249
|
}
|
|
1154
|
-
return;
|
|
1155
|
-
} catch {
|
|
1156
|
-
if (res.headersSent || res.writableEnded) return;
|
|
1157
|
-
continue;
|
|
1158
1250
|
}
|
|
1159
1251
|
if (statusCode === 404) {
|
|
1160
1252
|
const defaultResponse = buildDefaultPagesNotFoundResponse();
|