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.
- package/dist/build/client-build-config.d.ts +11 -2
- package/dist/build/client-build-config.js +17 -6
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +42 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/pages-router-link-navigation.d.ts +33 -7
- package/dist/client/pages-router-link-navigation.js +32 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/client/window-next.d.ts +2 -1
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -1
- package/dist/config/config-matchers.js +87 -16
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/config/tsconfig-paths.js +14 -1
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +200 -112
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +65 -5
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +66 -20
- package/dist/entries/pages-server-entry.js +47 -31
- package/dist/index.js +417 -102
- package/dist/plugins/dynamic-preload-metadata.js +2 -4
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/fonts.js +5 -4
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +11 -9
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/strip-server-exports.d.ts +9 -7
- package/dist/plugins/strip-server-exports.js +493 -46
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/routing/app-route-graph.d.ts +2 -1
- package/dist/routing/app-route-graph.js +46 -16
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +22 -1
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +20 -11
- package/dist/server/app-browser-entry.js +175 -91
- package/dist/server/app-browser-error.d.ts +10 -6
- package/dist/server/app-browser-error.js +43 -8
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +5 -3
- package/dist/server/app-browser-navigation-controller.js +23 -2
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.d.ts +1 -1
- package/dist/server/app-browser-state.js +19 -11
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -0
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-optimistic-routing.js +2 -2
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +27 -14
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +62 -1
- package/dist/server/app-page-dispatch.d.ts +26 -0
- package/dist/server/app-page-dispatch.js +149 -92
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +5 -2
- package/dist/server/app-page-execution.d.ts +6 -1
- package/dist/server/app-page-execution.js +21 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +12 -1
- package/dist/server/app-page-render.js +42 -4
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +14 -5
- package/dist/server/app-page-stream.d.ts +15 -3
- package/dist/server/app-page-stream.js +11 -5
- package/dist/server/app-pages-bridge.d.ts +23 -1
- package/dist/server/app-pages-bridge.js +26 -17
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +28 -0
- package/dist/server/app-rsc-handler.js +195 -59
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +8 -2
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +84 -39
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/cache-control.js +4 -0
- package/dist/server/csp.js +1 -4
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +321 -83
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/middleware-matcher.js +12 -3
- package/dist/server/middleware-runtime.d.ts +3 -4
- package/dist/server/middleware-runtime.js +2 -0
- package/dist/server/navigation-planner.d.ts +135 -41
- package/dist/server/navigation-planner.js +138 -0
- package/dist/server/navigation-trace.d.ts +9 -1
- package/dist/server/navigation-trace.js +9 -1
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/pages-api-route.d.ts +6 -0
- package/dist/server/pages-api-route.js +13 -2
- package/dist/server/pages-asset-tags.d.ts +2 -1
- package/dist/server/pages-asset-tags.js +6 -2
- package/dist/server/pages-data-route.d.ts +9 -2
- package/dist/server/pages-data-route.js +18 -6
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +4 -15
- package/dist/server/pages-document-initial-props.js +27 -56
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-i18n.js +2 -2
- package/dist/server/pages-node-compat.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +207 -34
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +62 -23
- package/dist/server/pages-page-response.d.ts +4 -1
- package/dist/server/pages-page-response.js +11 -8
- package/dist/server/pages-readiness.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +8 -7
- package/dist/server/pages-request-pipeline.js +126 -47
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +3 -1
- package/dist/server/prod-server.js +50 -13
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/server/static-file-cache.js +16 -4
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/before-interactive-context.d.ts +14 -3
- package/dist/shims/cache-runtime.js +3 -2
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/document.d.ts +15 -20
- package/dist/shims/document.js +5 -8
- package/dist/shims/dynamic-preload-chunks.js +6 -4
- package/dist/shims/error-boundary.d.ts +2 -0
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +3 -2
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +45 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/headers.js +29 -4
- package/dist/shims/image.js +9 -2
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.js +8 -17
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
- package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +47 -19
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +63 -31
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +18 -3
- package/dist/shims/router.js +512 -142
- package/dist/shims/script.js +8 -4
- package/dist/shims/server.d.ts +16 -1
- package/dist/shims/server.js +44 -12
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +7 -1
- package/dist/utils/path.js +9 -1
- package/dist/utils/text-stream.d.ts +1 -1
- package/dist/utils/text-stream.js +2 -2
- package/dist/utils/vite-version.d.ts +12 -1
- package/dist/utils/vite-version.js +9 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -7,7 +7,7 @@ import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipel
|
|
|
7
7
|
import { headersContextFromRequest, setHeadersContext } from "../shims/headers.js";
|
|
8
8
|
import { getAndClearActionRevalidationKind } from "../shims/cache.js";
|
|
9
9
|
import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
|
|
10
|
-
import { setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
10
|
+
import { setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
11
11
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
12
12
|
import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
|
|
13
13
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
@@ -15,9 +15,9 @@ import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
|
15
15
|
import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
16
16
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
|
|
17
17
|
import { deferUntilStreamConsumed } from "./app-page-stream.js";
|
|
18
|
+
import { buildAppPageTags } from "./implicit-tags.js";
|
|
18
19
|
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
19
20
|
import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
|
|
20
|
-
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
21
21
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
22
22
|
//#region src/server/app-server-action-execution.ts
|
|
23
23
|
/**
|
|
@@ -46,6 +46,10 @@ function resolveActionRevalidationKind(hasModifiedCookies) {
|
|
|
46
46
|
if (hasModifiedCookies) return ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC;
|
|
47
47
|
return revalidationKind;
|
|
48
48
|
}
|
|
49
|
+
function clearRejectedActionSideEffects(getAndClearPendingCookies) {
|
|
50
|
+
getAndClearPendingCookies();
|
|
51
|
+
getAndClearActionRevalidationKind();
|
|
52
|
+
}
|
|
49
53
|
function cloneActionRedirectHeaders(requestHeaders) {
|
|
50
54
|
const headers = new Headers(requestHeaders);
|
|
51
55
|
for (const header of ACTION_REDIRECT_RENDER_STRIPPED_HEADERS) headers.delete(header);
|
|
@@ -173,7 +177,7 @@ async function readActionFormDataWithLimit(request, maxBytes) {
|
|
|
173
177
|
if (result.done) break;
|
|
174
178
|
totalSize += result.value.byteLength;
|
|
175
179
|
if (totalSize > maxBytes) {
|
|
176
|
-
|
|
180
|
+
reader.cancel();
|
|
177
181
|
throw new Error("Request body too large");
|
|
178
182
|
}
|
|
179
183
|
chunks.push(result.value);
|
|
@@ -233,7 +237,7 @@ function applyActionRedirectBasePath(url, basePath) {
|
|
|
233
237
|
return `${addBasePathToPathname(pathname, basePath)}${suffix}`;
|
|
234
238
|
}
|
|
235
239
|
function buildServerActionPageTags(route, pathname) {
|
|
236
|
-
return
|
|
240
|
+
return buildAppPageTags(pathname, [], route.routeSegments ?? []);
|
|
237
241
|
}
|
|
238
242
|
function resolveInternalActionRedirectTarget(redirectUrl, requestUrl, basePath) {
|
|
239
243
|
if (isExternalUrl(redirectUrl)) {
|
|
@@ -331,6 +335,7 @@ async function handleProgressiveServerActionRequest(options) {
|
|
|
331
335
|
}
|
|
332
336
|
const payloadResponse = await validateServerActionPayload(body);
|
|
333
337
|
if (payloadResponse) {
|
|
338
|
+
clearRejectedActionSideEffects(options.getAndClearPendingCookies);
|
|
334
339
|
options.clearRequestContext();
|
|
335
340
|
return payloadResponse;
|
|
336
341
|
}
|
|
@@ -480,8 +485,29 @@ async function handleServerActionRscRequest(options) {
|
|
|
480
485
|
if (options.request.method.toUpperCase() !== "POST" || !options.actionId) return null;
|
|
481
486
|
const csrfResponse = validateCsrfOrigin(options.request, options.allowedOrigins);
|
|
482
487
|
if (csrfResponse) return csrfResponse;
|
|
483
|
-
if (parseInt(options.request.headers.get("content-length") || "0", 10) > options.maxActionBodySize)
|
|
488
|
+
if (parseInt(options.request.headers.get("content-length") || "0", 10) > options.maxActionBodySize) {
|
|
489
|
+
if (options.request.body) options.request.body.cancel().catch(() => {});
|
|
490
|
+
return renderFetchActionBodyExceededResponse(options);
|
|
491
|
+
}
|
|
484
492
|
try {
|
|
493
|
+
let action;
|
|
494
|
+
if (options.contentType.startsWith("multipart/form-data")) {
|
|
495
|
+
let loadedAction;
|
|
496
|
+
try {
|
|
497
|
+
loadedAction = await options.loadServerAction(options.actionId);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
if (isServerActionNotFoundError(error, options.actionId)) return createActionNotFoundResponse(options.actionId, {
|
|
500
|
+
clearRequestContext: options.clearRequestContext,
|
|
501
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
502
|
+
});
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
if (!isAppServerActionFunction(loadedAction)) return createActionNotFoundResponse(options.actionId, {
|
|
506
|
+
clearRequestContext: options.clearRequestContext,
|
|
507
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
508
|
+
});
|
|
509
|
+
action = loadedAction;
|
|
510
|
+
}
|
|
485
511
|
let body;
|
|
486
512
|
try {
|
|
487
513
|
body = options.contentType.startsWith("multipart/form-data") ? await options.readFormDataWithLimit(options.request, options.maxActionBodySize) : await options.readBodyWithLimit(options.request, options.maxActionBodySize);
|
|
@@ -491,23 +517,27 @@ async function handleServerActionRscRequest(options) {
|
|
|
491
517
|
}
|
|
492
518
|
const payloadResponse = await validateServerActionPayload(body);
|
|
493
519
|
if (payloadResponse) {
|
|
520
|
+
clearRejectedActionSideEffects(options.getAndClearPendingCookies);
|
|
494
521
|
options.clearRequestContext();
|
|
495
522
|
return payloadResponse;
|
|
496
523
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
524
|
+
if (action === void 0) {
|
|
525
|
+
let loadedAction;
|
|
526
|
+
try {
|
|
527
|
+
loadedAction = await options.loadServerAction(options.actionId);
|
|
528
|
+
} catch (error) {
|
|
529
|
+
if (isServerActionNotFoundError(error, options.actionId)) return createActionNotFoundResponse(options.actionId, {
|
|
530
|
+
clearRequestContext: options.clearRequestContext,
|
|
531
|
+
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
532
|
+
});
|
|
533
|
+
throw error;
|
|
534
|
+
}
|
|
535
|
+
if (!isAppServerActionFunction(loadedAction)) return createActionNotFoundResponse(options.actionId, {
|
|
502
536
|
clearRequestContext: options.clearRequestContext,
|
|
503
537
|
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
504
538
|
});
|
|
505
|
-
|
|
539
|
+
action = loadedAction;
|
|
506
540
|
}
|
|
507
|
-
if (!isAppServerActionFunction(action)) return createActionNotFoundResponse(options.actionId, {
|
|
508
|
-
clearRequestContext: options.clearRequestContext,
|
|
509
|
-
getAndClearPendingCookies: options.getAndClearPendingCookies
|
|
510
|
-
});
|
|
511
541
|
const temporaryReferences = options.createTemporaryReferenceSet();
|
|
512
542
|
const args = await options.decodeReply(body, { temporaryReferences });
|
|
513
543
|
let returnValue;
|
|
@@ -599,6 +629,7 @@ async function handleServerActionRscRequest(options) {
|
|
|
599
629
|
params: redirectNavigationParams
|
|
600
630
|
});
|
|
601
631
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(targetMatch.route) ?? null);
|
|
632
|
+
setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(targetMatch.route) === "force-dynamic");
|
|
602
633
|
setCurrentFetchSoftTags(buildServerActionPageTags(targetMatch.route, targetPathname));
|
|
603
634
|
const element = options.buildPageElement({
|
|
604
635
|
cleanPathname: targetPathname,
|
|
@@ -677,6 +708,7 @@ async function handleServerActionRscRequest(options) {
|
|
|
677
708
|
});
|
|
678
709
|
await options.ensureRouteLoaded?.(actionRerenderTarget.route);
|
|
679
710
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(actionRerenderTarget.route) ?? null);
|
|
711
|
+
setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(actionRerenderTarget.route) === "force-dynamic");
|
|
680
712
|
setCurrentFetchSoftTags(buildServerActionPageTags(actionRerenderTarget.route, options.cleanPathname));
|
|
681
713
|
element = options.buildPageElement({
|
|
682
714
|
cleanPathname: options.cleanPathname,
|
|
@@ -22,6 +22,7 @@ declare function handleSsr(rscStream: ReadableStream<Uint8Array>, navContext: Na
|
|
|
22
22
|
capturedRscDataRef?: {
|
|
23
23
|
value: Promise<ArrayBuffer> | null;
|
|
24
24
|
};
|
|
25
|
+
pprFallbackShellSignal?: AbortSignal;
|
|
25
26
|
formState?: ReactFormState | null;
|
|
26
27
|
basePath?: string;
|
|
27
28
|
/**
|
|
@@ -42,6 +43,7 @@ declare function handleSsr(rscStream: ReadableStream<Uint8Array>, navContext: Na
|
|
|
42
43
|
* to resolve before returning the HTML stream. Used for static prerender
|
|
43
44
|
* and ISR cache writes to avoid caching fallback content. */
|
|
44
45
|
waitForAllReady?: boolean;
|
|
46
|
+
fallbackToErrorDocumentOnShellError?: boolean;
|
|
45
47
|
}): Promise<AppSsrRenderResult>;
|
|
46
48
|
declare const _default: {
|
|
47
49
|
fetch(request: Request): Promise<Response>;
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import "./server-globals.js";
|
|
2
2
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
3
3
|
import { isOpenRedirectShaped } from "./request-pipeline.js";
|
|
4
|
+
import { isPprFallbackShellAbortError } from "../shims/ppr-fallback-shell.js";
|
|
4
5
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
6
|
import "./app-elements.js";
|
|
6
7
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
8
|
+
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
7
9
|
import { ServerInsertedHTMLContext, appRouterInstance, clearServerInsertedHTML, getBfcacheIdMapContext, renderServerInsertedHTML, setNavigationContext, useServerInsertedHTML } from "../shims/navigation.js";
|
|
8
10
|
import { runWithNavigationContext } from "../shims/navigation-state.js";
|
|
9
11
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
10
12
|
import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr, safeJsonStringify } from "./html.js";
|
|
11
13
|
import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
|
|
14
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
12
15
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
13
16
|
import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
|
|
14
17
|
import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform } from "./app-ssr-stream.js";
|
|
18
|
+
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
19
|
+
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
15
20
|
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-browser-state.js";
|
|
16
21
|
import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
|
|
17
22
|
import { createClientReferencePreloader } from "./app-client-reference-preloader.js";
|
|
18
23
|
import { deferUntilStreamConsumed } from "./app-page-stream.js";
|
|
19
|
-
import {
|
|
20
|
-
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
24
|
+
import { renderBeforeInteractiveInlineScripts } from "./before-interactive-head.js";
|
|
21
25
|
import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
|
|
22
26
|
import { Fragment, createElement, use } from "react";
|
|
23
27
|
import { renderToReadableStream, renderToStaticMarkup } from "react-dom/server.edge";
|
|
@@ -31,6 +35,50 @@ import clientReferences from "virtual:vite-rsc/client-references";
|
|
|
31
35
|
* the response-layer combine cap.
|
|
32
36
|
*/
|
|
33
37
|
const DEFAULT_REACT_MAX_HEADERS_LENGTH = 6e3;
|
|
38
|
+
function isReactDevelopmentRuntime() {
|
|
39
|
+
if (process.env.NODE_ENV === "production") return false;
|
|
40
|
+
if (process.env.NODE_ENV === "development") return true;
|
|
41
|
+
return Function.prototype.toString.call(createElement).includes("getOwner");
|
|
42
|
+
}
|
|
43
|
+
function isStaticPrerenderModule(value) {
|
|
44
|
+
return typeof value === "object" && value !== null && "prerender" in value && typeof value.prerender === "function";
|
|
45
|
+
}
|
|
46
|
+
async function loadStaticPrerender() {
|
|
47
|
+
const staticRenderer = await import("react-dom/static.edge");
|
|
48
|
+
if (isStaticPrerenderModule(staticRenderer)) return staticRenderer.prerender;
|
|
49
|
+
if (isReactDevelopmentRuntime()) try {
|
|
50
|
+
const [{ createRequire }, path] = await Promise.all([import("node:module"), import("node:path")]);
|
|
51
|
+
const reactDomPackageJson = createRequire(import.meta.url).resolve("react-dom/package.json");
|
|
52
|
+
const reactDomDir = path.dirname(reactDomPackageJson);
|
|
53
|
+
const devRenderer = await import(path.join(reactDomDir, "cjs/react-dom-server.edge.development.js"));
|
|
54
|
+
if (isStaticPrerenderModule(devRenderer)) return devRenderer.prerender;
|
|
55
|
+
const devRendererDefault = typeof devRenderer === "object" && devRenderer !== null && "default" in devRenderer && devRenderer.default;
|
|
56
|
+
if (isStaticPrerenderModule(devRendererDefault)) return devRendererDefault.prerender;
|
|
57
|
+
throw new Error("react-dom development renderer did not expose prerender().");
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new Error("[vinext] Failed to load React static development renderer.", { cause: error });
|
|
60
|
+
}
|
|
61
|
+
throw new Error("[vinext] react-dom/static.edge did not expose prerender().");
|
|
62
|
+
}
|
|
63
|
+
function createUtf8Stream(html) {
|
|
64
|
+
const encoder = new TextEncoder();
|
|
65
|
+
return new ReadableStream({ start(controller) {
|
|
66
|
+
controller.enqueue(encoder.encode(html));
|
|
67
|
+
controller.close();
|
|
68
|
+
} });
|
|
69
|
+
}
|
|
70
|
+
function buildBootstrapModuleScript(bootstrapModuleUrl, nonce) {
|
|
71
|
+
if (!bootstrapModuleUrl) return "";
|
|
72
|
+
return `<script type="module"${createNonceAttribute(nonce)} src="` + escapeHtmlAttr(bootstrapModuleUrl) + "\" id=\"_R_\" async=\"\"><\/script>";
|
|
73
|
+
}
|
|
74
|
+
function renderSsrErrorDocumentShell(bootstrapModuleUrl, nonce) {
|
|
75
|
+
const html = renderToStaticMarkup(createElement(DefaultGlobalError, { error: null })).replace("<style>", "<style data-vinext-error-shell-style=\"\">");
|
|
76
|
+
const bootstrapScript = buildBootstrapModuleScript(bootstrapModuleUrl, nonce);
|
|
77
|
+
if (!bootstrapScript) return createUtf8Stream(`<!DOCTYPE html>${html}`);
|
|
78
|
+
const documentClose = "</body></html>";
|
|
79
|
+
if (!html.endsWith(documentClose)) return createUtf8Stream(`<!DOCTYPE html>${html}${bootstrapScript}`);
|
|
80
|
+
return createUtf8Stream(`<!DOCTYPE html>${html.slice(0, -14)}${bootstrapScript}${documentClose}`);
|
|
81
|
+
}
|
|
34
82
|
const clientReferencePreloader = createClientReferencePreloader({
|
|
35
83
|
getReferences() {
|
|
36
84
|
return clientReferences;
|
|
@@ -60,42 +108,13 @@ function renderInsertedHtml(insertedElements) {
|
|
|
60
108
|
} catch {}
|
|
61
109
|
return insertedHTML;
|
|
62
110
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Render captured `<Script strategy="beforeInteractive">` inline scripts to
|
|
65
|
-
* HTML, ready to splice immediately after `<head ...>` opens. Each entry has
|
|
66
|
-
* already had its inline content escaped via `escapeInlineContent(..., "script")`
|
|
67
|
-
* inside the Script shim, so this function only quotes the attributes that
|
|
68
|
-
* actually go on the tag (id, nonce, plus the residual passthroughs).
|
|
69
|
-
*
|
|
70
|
-
* Keeping this function colocated with the rest of the head-injection
|
|
71
|
-
* helpers makes it obvious where the boundary is: anything passed through
|
|
72
|
-
* here is being concatenated directly into HTML; treat the inputs
|
|
73
|
-
* accordingly.
|
|
74
|
-
*/
|
|
75
|
-
const VALID_ATTR_NAME = /^[a-zA-Z][\w.-]*$/;
|
|
76
|
-
function renderBeforeInteractiveInlineScripts(scripts) {
|
|
77
|
-
if (scripts.length === 0) return "";
|
|
78
|
-
let html = "";
|
|
79
|
-
for (const script of scripts) {
|
|
80
|
-
let attrs = "";
|
|
81
|
-
if (script.id) attrs += ` id="${escapeHtmlAttr(script.id)}"`;
|
|
82
|
-
attrs += createNonceAttribute(script.nonce);
|
|
83
|
-
if (script.attributes) for (const [key, value] of Object.entries(script.attributes)) {
|
|
84
|
-
if (!VALID_ATTR_NAME.test(key)) continue;
|
|
85
|
-
if (value === true) attrs += ` ${key}`;
|
|
86
|
-
else if (typeof value === "string") attrs += ` ${key}="${escapeHtmlAttr(value)}"`;
|
|
87
|
-
}
|
|
88
|
-
html += `<script${attrs}>${script.innerHTML}<\/script>`;
|
|
89
|
-
}
|
|
90
|
-
return html;
|
|
91
|
-
}
|
|
92
111
|
function renderFontHtml(fontData, nonce, options = {}) {
|
|
93
112
|
if (!fontData) return "";
|
|
94
113
|
let fontHTML = "";
|
|
95
114
|
const nonceAttr = createNonceAttribute(nonce);
|
|
96
115
|
const includeStyles = options.includeStyles ?? true;
|
|
97
|
-
for (const url of fontData.links ?? []) fontHTML += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(url)}" />\n`;
|
|
98
|
-
for (const preload of fontData.preloads ?? []) fontHTML += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(preload.href)}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n`;
|
|
116
|
+
for (const url of fontData.links ?? []) fontHTML += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(url))}" />\n`;
|
|
117
|
+
for (const preload of fontData.preloads ?? []) fontHTML += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(preload.href))}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n`;
|
|
99
118
|
if (includeStyles && fontData.styles && fontData.styles.length > 0) fontHTML += `<style data-vinext-fonts${nonceAttr}>${fontData.styles.join("\n")}</style>\n`;
|
|
100
119
|
return fontHTML;
|
|
101
120
|
}
|
|
@@ -182,24 +201,50 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
182
201
|
const ssrRoot = withScriptNonce(createElement(BeforeInteractiveContext.Provider, { value: registerBeforeInteractiveInlineScript }, ssrTree), options?.scriptNonce);
|
|
183
202
|
const bootstrapModuleUrl = extractBootstrapModuleUrl(await import.meta.viteRsc.loadBootstrapScriptContent("index"));
|
|
184
203
|
const errorMetaRenderer = createSsrErrorMetaRenderer({ basePath: options?.basePath });
|
|
204
|
+
const pprFallbackShellSignal = options?.pprFallbackShellSignal;
|
|
185
205
|
let reactLinkHeader = "";
|
|
186
206
|
const maxHeadersLength = options?.reactMaxHeadersLength ?? DEFAULT_REACT_MAX_HEADERS_LENGTH;
|
|
187
207
|
const captureHeaders = maxHeadersLength > 0;
|
|
188
|
-
const
|
|
208
|
+
const renderOptions = {
|
|
209
|
+
bootstrapModules: bootstrapModuleUrl ? [bootstrapModuleUrl] : void 0,
|
|
210
|
+
formState: options?.formState ?? null,
|
|
211
|
+
nonce: options?.scriptNonce,
|
|
189
212
|
onHeaders: captureHeaders ? (headers) => {
|
|
190
213
|
const link = headers.get("Link");
|
|
191
214
|
if (link) reactLinkHeader = link;
|
|
192
215
|
} : void 0,
|
|
193
216
|
maxHeadersLength: captureHeaders ? maxHeadersLength : void 0,
|
|
194
|
-
bootstrapModules: bootstrapModuleUrl ? [bootstrapModuleUrl] : void 0,
|
|
195
|
-
formState: options?.formState ?? null,
|
|
196
|
-
nonce: options?.scriptNonce,
|
|
197
217
|
onError(error) {
|
|
218
|
+
if (pprFallbackShellSignal && isPprFallbackShellAbortError(error)) return;
|
|
198
219
|
errorMetaRenderer.capture(error);
|
|
199
220
|
if (error && typeof error === "object" && "digest" in error) return String(error.digest);
|
|
200
221
|
if (process.env.NODE_ENV === "production" && error) return ssrErrorDigest(getErrorMessage(error) + (error instanceof Error ? error.stack ?? "" : ""));
|
|
201
222
|
}
|
|
202
|
-
}
|
|
223
|
+
};
|
|
224
|
+
let htmlStream;
|
|
225
|
+
let shellErrorRecovered = false;
|
|
226
|
+
if (pprFallbackShellSignal) {
|
|
227
|
+
const prerender = await loadStaticPrerender();
|
|
228
|
+
const htmlAbortController = new AbortController();
|
|
229
|
+
const pendingHtml = prerender(ssrRoot, {
|
|
230
|
+
...renderOptions,
|
|
231
|
+
signal: htmlAbortController.signal
|
|
232
|
+
});
|
|
233
|
+
setTimeout(() => htmlAbortController.abort(), 0);
|
|
234
|
+
htmlStream = (await pendingHtml).prelude;
|
|
235
|
+
} else {
|
|
236
|
+
let streamingHtmlStream;
|
|
237
|
+
try {
|
|
238
|
+
streamingHtmlStream = await renderToReadableStream(ssrRoot, { ...renderOptions });
|
|
239
|
+
if (options?.waitForAllReady === true) await streamingHtmlStream.allReady;
|
|
240
|
+
htmlStream = streamingHtmlStream;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
streamingHtmlStream?.cancel().catch(() => {});
|
|
243
|
+
if (options?.fallbackToErrorDocumentOnShellError !== true || options?.waitForAllReady === true || typeof error?.digest === "string") throw error;
|
|
244
|
+
shellErrorRecovered = true;
|
|
245
|
+
htmlStream = renderSsrErrorDocumentShell(bootstrapModuleUrl, options?.scriptNonce);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
203
248
|
const inlineCssManifest = globalThis.__VINEXT_INLINE_CSS__;
|
|
204
249
|
const fontStyles = fontData?.styles ?? [];
|
|
205
250
|
const mergeFontStylesIntoInlineCss = fontStyles.length > 0 && hasInlineCssManifest(inlineCssManifest);
|
|
@@ -221,11 +266,11 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
221
266
|
return buildHeadInjectionHtml(ssrNavigationContext, bootstrapModuleUrl, options?.formState ?? null, insertedHTML + errorMetaHTML + getTraceMetaHTML() + initialDevServerErrorHTML, fontHTML, options?.scriptNonce);
|
|
222
267
|
};
|
|
223
268
|
const getBeforeInteractiveHeadHTML = () => renderBeforeInteractiveInlineScripts(beforeInteractiveInlineScripts);
|
|
224
|
-
if (options?.waitForAllReady === true) await htmlStream.allReady;
|
|
225
269
|
return {
|
|
226
270
|
htmlStream: deferUntilStreamConsumed(htmlStream.pipeThrough(createTickBufferedTransform(rscEmbed, getInsertedHTML, getBeforeInteractiveHeadHTML, inlineCssManifest, inlineCssFontStyles, inlineCssFontStyleFallbackHTML, options?.scriptNonce)), cleanup),
|
|
227
271
|
metadataReady: Promise.resolve(),
|
|
228
272
|
capturedRscData: options?.capturedRscDataRef?.value ?? null,
|
|
273
|
+
shellErrorRecovered,
|
|
229
274
|
linkHeader: reactLinkHeader
|
|
230
275
|
};
|
|
231
276
|
} catch (error) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BeforeInteractiveInlineScript } from "../shims/before-interactive-context.js";
|
|
2
|
+
|
|
3
|
+
//#region src/server/before-interactive-head.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Render captured `<Script strategy="beforeInteractive">` scripts to HTML,
|
|
6
|
+
* ready to splice immediately after `<head ...>` opens. Each entry has already
|
|
7
|
+
* had its inline content escaped via `escapeInlineContent(..., "script")`
|
|
8
|
+
* inside the Script shim, so this function only quotes the attributes that
|
|
9
|
+
* actually go on the tag (id, src, nonce, plus the residual passthroughs).
|
|
10
|
+
*
|
|
11
|
+
* Keeping this function in its own module makes the boundary obvious: anything
|
|
12
|
+
* passed through here is being concatenated directly into HTML; treat the
|
|
13
|
+
* inputs accordingly.
|
|
14
|
+
*/
|
|
15
|
+
declare function renderBeforeInteractiveInlineScripts(scripts: readonly BeforeInteractiveInlineScript[]): string;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { renderBeforeInteractiveInlineScripts };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createNonceAttribute, escapeHtmlAttr } from "./html.js";
|
|
2
|
+
//#region src/server/before-interactive-head.ts
|
|
3
|
+
const VALID_ATTR_NAME = /^[a-zA-Z][\w.-]*$/;
|
|
4
|
+
/**
|
|
5
|
+
* Render captured `<Script strategy="beforeInteractive">` scripts to HTML,
|
|
6
|
+
* ready to splice immediately after `<head ...>` opens. Each entry has already
|
|
7
|
+
* had its inline content escaped via `escapeInlineContent(..., "script")`
|
|
8
|
+
* inside the Script shim, so this function only quotes the attributes that
|
|
9
|
+
* actually go on the tag (id, src, nonce, plus the residual passthroughs).
|
|
10
|
+
*
|
|
11
|
+
* Keeping this function in its own module makes the boundary obvious: anything
|
|
12
|
+
* passed through here is being concatenated directly into HTML; treat the
|
|
13
|
+
* inputs accordingly.
|
|
14
|
+
*/
|
|
15
|
+
function renderBeforeInteractiveInlineScripts(scripts) {
|
|
16
|
+
if (scripts.length === 0) return "";
|
|
17
|
+
let html = "";
|
|
18
|
+
for (const script of scripts) {
|
|
19
|
+
let attrs = "";
|
|
20
|
+
if (script.id) attrs += ` id="${escapeHtmlAttr(script.id)}"`;
|
|
21
|
+
if (script.src) attrs += ` src="${escapeHtmlAttr(script.src)}"`;
|
|
22
|
+
attrs += createNonceAttribute(script.nonce);
|
|
23
|
+
if (script.attributes) for (const [key, value] of Object.entries(script.attributes)) {
|
|
24
|
+
if (!VALID_ATTR_NAME.test(key)) continue;
|
|
25
|
+
if (key === "data-nscript") continue;
|
|
26
|
+
if (value === true) attrs += ` ${key}`;
|
|
27
|
+
else if (typeof value === "string") attrs += ` ${key}="${escapeHtmlAttr(value)}"`;
|
|
28
|
+
}
|
|
29
|
+
attrs += ` data-nscript="beforeInteractive"`;
|
|
30
|
+
html += `<script${attrs}>${script.innerHTML ?? ""}<\/script>`;
|
|
31
|
+
}
|
|
32
|
+
return html;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { renderBeforeInteractiveInlineScripts };
|
|
@@ -19,6 +19,10 @@ function applyCdnResponseHeaders(headers, input) {
|
|
|
19
19
|
headers.delete("Cache-Control");
|
|
20
20
|
const map = getCdnCacheAdapter().buildResponseHeaders(input);
|
|
21
21
|
for (const [name, value] of Object.entries(map)) {
|
|
22
|
+
if (value === null) {
|
|
23
|
+
headers.delete(name);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
22
26
|
if (value === "") continue;
|
|
23
27
|
headers.set(name, value);
|
|
24
28
|
}
|
package/dist/server/csp.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
//#region src/server/csp.ts
|
|
2
2
|
const ESCAPE_REGEX = /[&><\u2028\u2029]/;
|
|
3
|
-
function matchesDirectiveName(directive, name) {
|
|
4
|
-
return directive === name || directive.startsWith(`${name} `);
|
|
5
|
-
}
|
|
6
3
|
function getNodeHeaderValue(headers, key) {
|
|
7
4
|
const value = headers?.[key];
|
|
8
5
|
if (Array.isArray(value)) return value.join(", ");
|
|
@@ -11,7 +8,7 @@ function getNodeHeaderValue(headers, key) {
|
|
|
11
8
|
}
|
|
12
9
|
function getScriptNonceFromHeader(cspHeaderValue) {
|
|
13
10
|
const directives = cspHeaderValue.split(";").map((directive) => directive.trim());
|
|
14
|
-
const directive = directives.find((value) =>
|
|
11
|
+
const directive = directives.find((value) => value.startsWith("script-src")) ?? directives.find((value) => value.startsWith("default-src"));
|
|
15
12
|
if (!directive) return;
|
|
16
13
|
const nonce = directive.split(" ").slice(1).map((source) => source.trim()).find((source) => source.startsWith("'nonce-") && source.length > 8 && source.endsWith("'"))?.slice(7, -1);
|
|
17
14
|
if (!nonce) return;
|
|
@@ -43,7 +43,7 @@ declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter,
|
|
|
43
43
|
* `next.config`. When undefined or empty, no meta tags are emitted.
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
|
-
clientTraceMetadata?: readonly string[]): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
|
|
46
|
+
clientTraceMetadata?: readonly string[], htmlLimitedBots?: string): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
|
|
47
47
|
|
|
48
48
|
statusCode?: number,
|
|
49
49
|
/**
|
|
@@ -53,6 +53,6 @@ statusCode?: number,
|
|
|
53
53
|
* client-side navigations in the Pages Router.
|
|
54
54
|
*/
|
|
55
55
|
|
|
56
|
-
isDataReq?: boolean) => Promise<void>;
|
|
56
|
+
isDataReq?: boolean, originalUrl?: string) => Promise<void>;
|
|
57
57
|
//#endregion
|
|
58
58
|
export { createSSRHandler, detectLocaleFromHeaders, extractLocaleFromUrl, parseCookieLocale };
|