vinext 1.0.0-beta.12 → 1.0.0-beta.13
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 +39 -12
- package/dist/build/action-owner-manifest.js +23 -5
- package/dist/build/lifecycle.d.ts +42 -0
- package/dist/build/lifecycle.js +246 -0
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +0 -3
- package/dist/build/pages-client-assets-module.js +1 -13
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.d.ts +1 -1
- package/dist/build/prerender-paths.js +6 -6
- package/dist/build/prerender-server-pool.js +1 -1
- package/dist/build/prerender.d.ts +1 -1
- package/dist/build/prerender.js +5 -5
- package/dist/build/preview-credentials.d.ts +1 -1
- package/dist/build/preview-credentials.js +2 -2
- package/dist/build/report.js +1 -1
- package/dist/build/run-prerender.d.ts +2 -2
- package/dist/build/run-prerender.js +5 -5
- package/dist/build/standalone.js +2 -2
- package/dist/cli-args.d.ts +5 -13
- package/dist/cli-args.js +2 -45
- package/dist/cli-dev-config.d.ts +6 -2
- package/dist/cli-dev-config.js +160 -3
- package/dist/cli.js +104 -439
- package/dist/config/config-matchers.js +1 -1
- package/dist/config/next-config.d.ts +2 -2
- package/dist/config/next-config.js +5 -5
- package/dist/config/prerender.d.ts +3 -0
- package/dist/config/prerender.js +8 -2
- package/dist/entries/app-browser-entry.js +1 -1
- package/dist/entries/app-rsc-entry.js +1 -1
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +17 -2
- package/dist/index.d.ts +6 -8
- package/dist/index.js +262 -101
- package/dist/init-cloudflare.d.ts +3 -2
- package/dist/init-cloudflare.js +117 -5
- package/dist/init-platform.d.ts +2 -0
- package/dist/init-platform.js +9 -3
- package/dist/init.d.ts +7 -5
- package/dist/init.js +41 -22
- package/dist/plugins/dynamic-preload-metadata.js +1 -1
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +1 -1
- package/dist/plugins/import-meta-url.js +1 -1
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/og-assets.js +32 -13
- package/dist/plugins/og-harfbuzz.d.ts +24 -0
- package/dist/plugins/og-harfbuzz.js +260 -0
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/require-condition-resolution.js +2 -2
- package/dist/plugins/require-context.js +2 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/plugins/use-cache-callable.d.ts +0 -2
- package/dist/plugins/use-cache-callable.js +8 -16
- package/dist/plugins/worker-image-imports.js +1 -1
- package/dist/routing/app-route-graph.js +1 -1
- package/dist/routing/app-router.js +1 -1
- package/dist/routing/pages-router.js +1 -1
- package/dist/server/app-action-forwarding.js +1 -1
- package/dist/server/app-browser-error.js +1 -1
- package/dist/server/app-elements-wire.js +2 -2
- package/dist/server/app-middleware.js +1 -1
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-dispatch.js +1 -1
- package/dist/server/app-page-element-builder.js +3 -2
- package/dist/server/app-page-probe.js +3 -3
- package/dist/server/app-request-stage-independent-entry.js +2 -2
- package/dist/server/app-route-handler-dispatch.js +1 -1
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-router-entry.js +2 -2
- package/dist/server/app-rsc-handler.d.ts +1 -1
- package/dist/server/app-rsc-handler.js +4 -4
- package/dist/server/app-rsc-response-stage.js +1 -1
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.js +4 -4
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/dev-lockfile.d.ts +1 -1
- package/dist/server/dev-lockfile.js +4 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +28 -6
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/metadata-route-response.js +8 -0
- package/dist/server/middleware-runtime.js +3 -3
- package/dist/server/pages-data-route.js +1 -1
- package/dist/server/pages-dev-hydration.d.ts +6 -0
- package/dist/server/pages-dev-hydration.js +19 -7
- package/dist/server/pages-page-data.js +2 -2
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.js +3 -3
- package/dist/server/pages-request-stage-entry.js +3 -3
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.js +7 -7
- package/dist/server/request-pipeline.js +2 -2
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/shims/cache-callable-runtime.d.ts +38 -0
- package/dist/shims/cache-callable-runtime.js +162 -11
- package/dist/shims/cache-runtime.d.ts +6 -8
- package/dist/shims/cache-runtime.js +82 -22
- package/dist/shims/font-local.js +1 -1
- package/dist/shims/form.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/internal/app-page-props-cache-key.d.ts +29 -0
- package/dist/shims/internal/app-page-props-cache-key.js +53 -1
- package/dist/shims/internal/format-url-object.d.ts +7 -0
- package/dist/shims/internal/format-url-object.js +53 -0
- package/dist/shims/internal/normalize-router-href.d.ts +15 -0
- package/dist/shims/internal/normalize-router-href.js +41 -0
- package/dist/shims/internal/pages-data-target.d.ts +4 -1
- package/dist/shims/internal/pages-data-target.js +28 -35
- package/dist/shims/internal/route-pattern-for-warning.d.ts +2 -2
- package/dist/shims/internal/route-pattern-for-warning.js +3 -3
- package/dist/shims/link.js +31 -92
- package/dist/shims/metadata.js +5 -4
- package/dist/shims/navigation.js +2 -2
- package/dist/shims/router-state.js +1 -1
- package/dist/shims/router.d.ts +8 -7
- package/dist/shims/router.js +312 -148
- package/dist/shims/server.js +3 -3
- package/dist/utils/built-asset-url.js +1 -1
- package/dist/utils/project.d.ts +1 -11
- package/dist/utils/project.js +19 -28
- package/dist/utils/react-version.d.ts +3 -1
- package/dist/utils/react-version.js +19 -1
- package/dist/utils/vite-cli-invocation.d.ts +21 -0
- package/dist/utils/vite-cli-invocation.js +144 -0
- package/package.json +10 -2
package/dist/shims/router.js
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
1
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
3
2
|
import { parseCookieHeader } from "../utils/parse-cookie.js";
|
|
4
|
-
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
5
3
|
import { isExternalUrl } from "../utils/external-url.js";
|
|
4
|
+
import { sortRoutes, splitPathSegments } from "../routing/utils.js";
|
|
5
|
+
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
6
|
+
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
6
7
|
import { addLocalePrefix, getDomainLocaleUrl, getLocalePathPrefix } from "../utils/domain-locale.js";
|
|
7
|
-
import { isUnknownRecord } from "../utils/record.js";
|
|
8
8
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
9
9
|
import { RouterContext } from "./internal/router-context.js";
|
|
10
10
|
import { applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDataJson } from "../client/vinext-next-data.js";
|
|
11
11
|
import { isValidModulePath } from "../client/validate-module-path.js";
|
|
12
|
-
import {
|
|
12
|
+
import { matchRoutePattern, routePattern, routePatternParts } from "../routing/route-pattern.js";
|
|
13
13
|
import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../utils/deployment-id.js";
|
|
14
14
|
import { dedupedPagesDataFetch, evictPagesDataCache, fetchCachedPagesData, fetchStaticPagesData, getPagesStaticDataCache } from "./internal/pages-data-fetch-dedup.js";
|
|
15
|
-
import { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
15
|
+
import { getPagesMiddlewareDataHref, matchesPagesMiddlewarePath, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
16
16
|
import { getPagesRouterComponentsMap } from "./internal/pages-router-components.js";
|
|
17
17
|
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
18
18
|
import { resolveDirectHybridClientRouteOwner } from "./internal/hybrid-client-route-owner-direct.js";
|
|
19
19
|
import { installWindowNext } from "../client/window-next.js";
|
|
20
|
-
import { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
21
|
-
import { addQueryParam,
|
|
20
|
+
import { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isAbsoluteUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, toSameOriginPath, withBasePath } from "./url-utils.js";
|
|
21
|
+
import { addQueryParam, mergeRewriteQuery, mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
|
22
22
|
import { scrollToHashTarget } from "./hash-scroll.js";
|
|
23
23
|
import { installPagesRouterRuntime, setPagesRouterPopStateHandler, setStampInitialHistoryState } from "./pages-router-runtime.js";
|
|
24
|
-
import { interpolateDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
24
|
+
import { interpolateDynamicRouteHref, resolveDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
25
|
+
import { formatUrlObject, formatUrlObjectWithValidation } from "./internal/format-url-object.js";
|
|
26
|
+
import { normalizeRouterHref, resolvePagesRouterHref } from "./internal/normalize-router-href.js";
|
|
27
|
+
import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
|
|
25
28
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
26
29
|
import { Component, Fragment, StrictMode, createElement, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
|
|
27
30
|
//#region src/shims/router.ts
|
|
@@ -217,36 +220,69 @@ function getPagesRouterRuntimeComponents() {
|
|
|
217
220
|
routerRuntimeState.components = components;
|
|
218
221
|
return components;
|
|
219
222
|
}
|
|
220
|
-
function
|
|
223
|
+
function resolvePagesUrlPath(formatted) {
|
|
224
|
+
if (typeof window === "undefined") return formatted;
|
|
225
|
+
const routePathname = window.__NEXT_DATA__?.page ?? stripBasePath(window.location.pathname, __basePath);
|
|
226
|
+
const visibleAsPath = stripBasePath(window.location.pathname, __basePath) + window.location.search;
|
|
227
|
+
return resolvePagesRouterHref(formatted, {
|
|
228
|
+
pathname: routePathname,
|
|
229
|
+
asPath: formatted.startsWith("#") ? visibleAsPath : routePathname
|
|
230
|
+
}, __basePath);
|
|
231
|
+
}
|
|
232
|
+
function hasUrlObjectAuthority(url) {
|
|
233
|
+
return Boolean(url.host || url.hostname || url.slashes);
|
|
234
|
+
}
|
|
235
|
+
function resolveUrl(url, resolveQueryFromRoute = false) {
|
|
221
236
|
if (typeof url === "string") return url;
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
237
|
+
const formatted = formatUrlObject(url);
|
|
238
|
+
if (url.protocol || hasUrlObjectAuthority(url) || url.pathname) return resolvePagesUrlPath(formatted);
|
|
239
|
+
const visiblePathname = typeof window === "undefined" ? "/" : stripBasePath(window.location.pathname, __basePath);
|
|
240
|
+
const routePathname = typeof window === "undefined" ? void 0 : window.__NEXT_DATA__?.page;
|
|
241
|
+
const matchingDynamicRoute = resolveQueryFromRoute && formatted.startsWith("?") && routePathname && extractRouteParamNames(routePathname).length > 0 && extractRouteParamsFromPath(routePathname, removeNavigationLocalePrefix(visiblePathname)) !== null ? routePathname : void 0;
|
|
242
|
+
return resolvePagesUrlPath((typeof window === "undefined" ? "/" : matchingDynamicRoute ?? (formatted ? visiblePathname : routePathname ?? visiblePathname)) + (formatted.startsWith("#") && typeof window !== "undefined" ? window.location.search : "") + formatted);
|
|
243
|
+
}
|
|
244
|
+
function toPreparedSameOriginPath(url) {
|
|
245
|
+
const appPath = toSameOriginAppPath(url, __basePath);
|
|
246
|
+
if (appPath !== null) return appPath;
|
|
247
|
+
if (!isAbsoluteUrl(url)) return null;
|
|
248
|
+
const localPath = toSameOriginPath(url);
|
|
249
|
+
if (localPath === null) return null;
|
|
250
|
+
const parsed = new URL(url);
|
|
251
|
+
return parsed.username || parsed.password ? null : localPath;
|
|
252
|
+
}
|
|
253
|
+
/** Next.js only strips a same-origin URL when the origin is a literal prefix. */
|
|
254
|
+
function credentialedSameOriginHref(url) {
|
|
255
|
+
if (!url) return void 0;
|
|
256
|
+
const href = resolveUrl(url);
|
|
257
|
+
try {
|
|
258
|
+
const parsed = new URL(href, window.location.href);
|
|
259
|
+
if (!parsed.username && !parsed.password) return void 0;
|
|
260
|
+
} catch {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
return toSameOriginPath(href) !== null ? href : void 0;
|
|
238
264
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
265
|
+
function hasUrlObjectQuery(url) {
|
|
266
|
+
return typeof url.query === "string" ? url.query.length > 0 : url.query !== null && typeof url.query === "object" && Object.keys(url.query).length > 0;
|
|
267
|
+
}
|
|
268
|
+
function inheritsVisiblePath(url) {
|
|
269
|
+
return !url.pathname && (hasUrlObjectQuery(url) || typeof url.search === "string" && url.search.length > 0 || typeof url.hash === "string" && url.hash.length > 0);
|
|
270
|
+
}
|
|
271
|
+
function prepareUrl(url) {
|
|
272
|
+
const routePathname = getCurrentRoutePathnameForWarning();
|
|
273
|
+
if (typeof url === "string") {
|
|
274
|
+
const normalized = normalizeRouterHref(url, routePathname);
|
|
275
|
+
return normalized === url ? url : resolvePagesUrlPath(normalized);
|
|
276
|
+
}
|
|
277
|
+
const formatted = formatUrlObjectWithValidation(url);
|
|
278
|
+
const normalized = normalizeRouterHref(formatted, routePathname);
|
|
279
|
+
if (normalized === formatted) return url;
|
|
280
|
+
if (!hasUrlObjectAuthority(url) && (url.protocol || url.pathname)) return resolvePagesUrlPath(normalized);
|
|
281
|
+
if (!url.pathname && normalized.startsWith("#")) return {
|
|
282
|
+
...url,
|
|
283
|
+
hash: normalized
|
|
284
|
+
};
|
|
285
|
+
return normalized;
|
|
250
286
|
}
|
|
251
287
|
/**
|
|
252
288
|
* Next.js's internal `_h` replacement receives browser-visible URLs, which may
|
|
@@ -266,35 +302,43 @@ function normalizeHydrationNavigationUrl(url) {
|
|
|
266
302
|
}
|
|
267
303
|
}
|
|
268
304
|
var HrefInterpolationError = class extends Error {};
|
|
269
|
-
function
|
|
270
|
-
|
|
305
|
+
function getHrefInterpolationError(href, routePattern, query) {
|
|
306
|
+
const missingParams = routePatternParts(routePattern).filter((part) => part.startsWith(":") && !part.endsWith("*")).map((part) => part.slice(1, part.endsWith("+") ? -1 : void 0)).filter((paramName) => {
|
|
307
|
+
const value = query[paramName];
|
|
308
|
+
return value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
309
|
+
});
|
|
310
|
+
return missingParams.length > 0 ? new HrefInterpolationError(`The provided \`href\` (${href}) value is missing query values (${missingParams.join(", ")}) to be interpolated properly. Read more: https://nextjs.org/docs/messages/href-interpolation-failed`) : null;
|
|
311
|
+
}
|
|
312
|
+
function resolveCurrentDynamicRoute(resolved, displayHref) {
|
|
313
|
+
if (typeof window === "undefined") return null;
|
|
271
314
|
const routePattern = window.__NEXT_DATA__?.page;
|
|
272
|
-
if (!routePattern || extractRouteParamNames(routePattern).length === 0) return
|
|
315
|
+
if (!routePattern || extractRouteParamNames(routePattern).length === 0) return null;
|
|
273
316
|
try {
|
|
274
317
|
const target = new URL(resolved, "http://vinext.local");
|
|
275
318
|
const currentOrigin = getWindowOrigin();
|
|
276
|
-
if (currentOrigin && target.origin !== "http://vinext.local" && target.origin !== currentOrigin) return
|
|
319
|
+
if (currentOrigin && target.origin !== "http://vinext.local" && target.origin !== currentOrigin) return null;
|
|
277
320
|
const visiblePath = stripBasePath(window.location.pathname, __basePath);
|
|
278
321
|
const visibleLocale = getLocalePathPrefix(visiblePath, window.__VINEXT_LOCALES__);
|
|
279
|
-
if (extractRouteParamsFromPath(routePattern, visibleLocale ? visiblePath.slice(visibleLocale.length + 1) || "/" : visiblePath) === null) return
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
322
|
+
if (extractRouteParamsFromPath(routePattern, visibleLocale ? visiblePath.slice(visibleLocale.length + 1) || "/" : visiblePath) === null) return null;
|
|
323
|
+
const href = routePattern + target.search + target.hash;
|
|
324
|
+
if (displayHref !== void 0) return {
|
|
325
|
+
href,
|
|
326
|
+
as: interpolateDynamicRouteHref(href, displayHref)?.href || null
|
|
327
|
+
};
|
|
328
|
+
const dynamicRoute = resolveDynamicRouteHref(href);
|
|
329
|
+
if (!dynamicRoute) {
|
|
330
|
+
const error = getHrefInterpolationError(href, routePattern, parseQueryString(target.search));
|
|
331
|
+
if (error) throw error;
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
291
334
|
const targetLocale = getLocalePathPrefix(target.pathname, window.__VINEXT_LOCALES__);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
335
|
+
return {
|
|
336
|
+
href,
|
|
337
|
+
as: targetLocale ? `/${targetLocale}${dynamicRoute.as}` : dynamicRoute.as
|
|
338
|
+
};
|
|
295
339
|
} catch (error) {
|
|
296
340
|
if (error instanceof HrefInterpolationError) throw error;
|
|
297
|
-
return
|
|
341
|
+
return null;
|
|
298
342
|
}
|
|
299
343
|
}
|
|
300
344
|
function getCurrentUrlLocale() {
|
|
@@ -363,7 +407,11 @@ function getDomainLocalePath(url, locale) {
|
|
|
363
407
|
*/
|
|
364
408
|
function applyNavigationLocale(url, locale, replaceExistingLocale = false) {
|
|
365
409
|
if (!locale || typeof window === "undefined") return url;
|
|
366
|
-
if (isAbsoluteOrProtocolRelativeUrl(url))
|
|
410
|
+
if (isAbsoluteOrProtocolRelativeUrl(url)) {
|
|
411
|
+
const localPath = window.location ? toSameOriginAppPath(url, __basePath) : null;
|
|
412
|
+
if (localPath == null) return url;
|
|
413
|
+
url = localPath;
|
|
414
|
+
}
|
|
367
415
|
if (!replaceExistingLocale && getLocalePathPrefix(url, window.__VINEXT_LOCALES__)) return url;
|
|
368
416
|
const normalizedUrl = replaceExistingLocale ? removeNavigationLocalePrefix(url) : url;
|
|
369
417
|
const domainLocalePath = getDomainLocalePath(normalizedUrl, locale);
|
|
@@ -416,6 +464,15 @@ function isHashOnlyChange(href) {
|
|
|
416
464
|
if (typeof window === "undefined") return false;
|
|
417
465
|
return isHashOnlyBrowserUrlChange(href, window.location.href, __basePath);
|
|
418
466
|
}
|
|
467
|
+
function toHistoryAppPath(url) {
|
|
468
|
+
const localUrl = isAbsoluteUrl(url) ? toSameOriginPath(url) ?? url : url;
|
|
469
|
+
if (!localUrl.startsWith("/") || localUrl.startsWith("//")) return url;
|
|
470
|
+
if (!__basePath) return localUrl;
|
|
471
|
+
const suffixIndex = localUrl.search(/[?#]/);
|
|
472
|
+
const pathname = suffixIndex === -1 ? localUrl : localUrl.slice(0, suffixIndex);
|
|
473
|
+
if (!hasBasePath(pathname, __basePath)) return localUrl;
|
|
474
|
+
return stripBasePath(pathname, __basePath) + (suffixIndex === -1 ? "" : localUrl.slice(suffixIndex));
|
|
475
|
+
}
|
|
419
476
|
/**
|
|
420
477
|
* Build router-shaped state for the initial document entry. Captures the
|
|
421
478
|
* active locale (from `window.__VINEXT_LOCALE__`) so a back-navigation
|
|
@@ -424,12 +481,18 @@ function isHashOnlyChange(href) {
|
|
|
424
481
|
* navigates back.
|
|
425
482
|
*/
|
|
426
483
|
function buildInitialRouterState() {
|
|
427
|
-
const
|
|
484
|
+
const browserPath = window.location.pathname + window.location.search;
|
|
485
|
+
const nextData = window.__NEXT_DATA__;
|
|
486
|
+
const middlewareMatches = nextData?.__vinext?.hasMiddleware && matchesPagesMiddlewarePath(stripBasePath(window.location.pathname, __basePath));
|
|
487
|
+
const routeUrl = normalizePathTrailingSlash(nextData?.page && !middlewareMatches ? withBasePath(formatUrlObject({
|
|
488
|
+
pathname: nextData.page,
|
|
489
|
+
query: mergeRouteParamsIntoQuery(parseQueryString(browserPath), nextData.query ?? {})
|
|
490
|
+
}), __basePath) : browserPath, __trailingSlash);
|
|
428
491
|
const options = {};
|
|
429
492
|
if (window.__VINEXT_LOCALE__ !== void 0) options.locale = window.__VINEXT_LOCALE__;
|
|
430
493
|
return {
|
|
431
|
-
url:
|
|
432
|
-
as:
|
|
494
|
+
url: routeUrl,
|
|
495
|
+
as: browserPath,
|
|
433
496
|
options,
|
|
434
497
|
__N: true,
|
|
435
498
|
key: createHistoryKey()
|
|
@@ -437,8 +500,8 @@ function buildInitialRouterState() {
|
|
|
437
500
|
}
|
|
438
501
|
/**
|
|
439
502
|
* Stamp the initial document entry with router-shaped state (only if no
|
|
440
|
-
* state is present).
|
|
441
|
-
*
|
|
503
|
+
* state is present). An early next/router import may precede the generated
|
|
504
|
+
* entry's __NEXT_DATA__ and matcher setup, so the ready transition retries it.
|
|
442
505
|
*/
|
|
443
506
|
function stampInitialHistoryState() {
|
|
444
507
|
installManualScrollRestoration();
|
|
@@ -448,6 +511,8 @@ function stampInitialHistoryState() {
|
|
|
448
511
|
routerRuntimeState.currentHistoryKey = getRouterStateKey(existingState) ?? routerRuntimeState.currentHistoryKey;
|
|
449
512
|
return;
|
|
450
513
|
}
|
|
514
|
+
const nextData = window.__NEXT_DATA__;
|
|
515
|
+
if (!nextData || nextData.__vinext?.hasMiddleware && !Object.hasOwn(window, "__VINEXT_MIDDLEWARE_MATCHER__")) return;
|
|
451
516
|
const initialState = buildInitialRouterState();
|
|
452
517
|
routerRuntimeState.currentHistoryKey = initialState.key;
|
|
453
518
|
window.history.replaceState(initialState, "");
|
|
@@ -742,12 +807,13 @@ function getCurrentHistoryAsPath() {
|
|
|
742
807
|
try {
|
|
743
808
|
const browserUrl = new URL(window.location.href);
|
|
744
809
|
const stateLocale = state.options.locale === false ? void 0 : state.options.locale;
|
|
745
|
-
const
|
|
810
|
+
const stateAs = toHistoryAppPath(state.as);
|
|
811
|
+
const localizedStateAs = applyNavigationLocale(stateAs, stateLocale);
|
|
746
812
|
const stateUrl = new URL(toBrowserNavigationHref(localizedStateAs, window.location.href, __basePath), window.location.href);
|
|
747
813
|
if (stateUrl.pathname !== browserUrl.pathname || stateUrl.search !== browserUrl.search) return null;
|
|
748
|
-
const
|
|
814
|
+
const appAs = removeNavigationLocalePrefix(stripHash(stateAs));
|
|
749
815
|
const visibleAs = `${removeNavigationLocalePrefix(stripBasePath(window.location.pathname, __basePath))}${window.location.search}`;
|
|
750
|
-
return `${
|
|
816
|
+
return `${appAs || visibleAs}${window.location.hash}`;
|
|
751
817
|
} catch {
|
|
752
818
|
return null;
|
|
753
819
|
}
|
|
@@ -783,6 +849,7 @@ function markPagesRouterReady() {
|
|
|
783
849
|
}
|
|
784
850
|
function initializePagesRouterReadyFromNextData(nextData, forceReady = false) {
|
|
785
851
|
if (typeof window === "undefined") return;
|
|
852
|
+
stampInitialHistoryState();
|
|
786
853
|
routerRuntimeState.pagesRouterReady = forceReady || getPagesNavigationIsReadyFromSerializedState(nextData.page, window.location.search, nextData);
|
|
787
854
|
}
|
|
788
855
|
function markPagesRouterHydrated() {
|
|
@@ -1098,8 +1165,8 @@ async function resolveClientConfigRewrite(href) {
|
|
|
1098
1165
|
kind: "rewrite"
|
|
1099
1166
|
} : null;
|
|
1100
1167
|
}
|
|
1101
|
-
function getMiddlewarePagesDataFetchUrl(browserUrl, dataTarget) {
|
|
1102
|
-
const middlewareDataHref = getPagesMiddlewareDataHref(browserUrl, __basePath, dataTarget?.prefetchLocale ? { locale: dataTarget.prefetchLocale } : void 0);
|
|
1168
|
+
function getMiddlewarePagesDataFetchUrl(browserUrl, dataTarget, routeUrl = browserUrl) {
|
|
1169
|
+
const middlewareDataHref = getPagesMiddlewareDataHref(browserUrl, __basePath, dataTarget?.prefetchLocale ? { locale: dataTarget.prefetchLocale } : void 0, routeUrl);
|
|
1103
1170
|
if (!middlewareDataHref) return null;
|
|
1104
1171
|
if (dataTarget?.dataKind === "static" && dataTarget.middlewareDataHref === middlewareDataHref && dataTarget.prefetchDataHref) return dataTarget.prefetchDataHref;
|
|
1105
1172
|
return middlewareDataHref;
|
|
@@ -1114,8 +1181,8 @@ function getPagesDataCacheHref(dataHref) {
|
|
|
1114
1181
|
function shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget) {
|
|
1115
1182
|
return middlewareEffect?.redirectLocation != null || dataTarget?.dataKind !== "static";
|
|
1116
1183
|
}
|
|
1117
|
-
async function resolveMiddlewareDataEffect(browserUrl, signal, dataTarget) {
|
|
1118
|
-
const dataUrl = getMiddlewarePagesDataFetchUrl(browserUrl, dataTarget);
|
|
1184
|
+
async function resolveMiddlewareDataEffect(browserUrl, signal, dataTarget, routeUrl = browserUrl) {
|
|
1185
|
+
const dataUrl = getMiddlewarePagesDataFetchUrl(browserUrl, dataTarget, routeUrl);
|
|
1119
1186
|
if (!dataUrl) return null;
|
|
1120
1187
|
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
1121
1188
|
try {
|
|
@@ -1413,6 +1480,7 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
|
|
|
1413
1480
|
scheduleHardNavigationAndThrow(url, "Navigation failed: missing __NEXT_DATA__ in response");
|
|
1414
1481
|
}
|
|
1415
1482
|
const nextData = parseVinextNextDataJson(nextDataJson);
|
|
1483
|
+
if (options.routePattern && nextData.page !== options.routePattern) scheduleHardNavigationAndThrow(browserUrl, "Navigation fallback resolved a different page");
|
|
1416
1484
|
let nextDataRouteState = options.nextDataRouteState;
|
|
1417
1485
|
let isDevelopmentNotFound = false;
|
|
1418
1486
|
if (res.status === 404 && options.allowNotFoundResponse !== true && (nextData.page === "/404" || nextData.page === "/_error") && typeof nextData.notFoundSrcPage === "string") {
|
|
@@ -1459,6 +1527,19 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
|
|
|
1459
1527
|
assertStillCurrent();
|
|
1460
1528
|
const PageComponent = pageModule.default;
|
|
1461
1529
|
if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(browserUrl, "Navigation failed: page module default export is not a component");
|
|
1530
|
+
const pageLoaders = window.__VINEXT_PAGE_LOADERS__ ??= {};
|
|
1531
|
+
pageLoaders[nextData.page] ??= () => Promise.resolve(pageModule);
|
|
1532
|
+
const pagePatterns = window.__VINEXT_PAGE_PATTERNS__ ??= [];
|
|
1533
|
+
if (!pagePatterns.includes(nextData.page)) {
|
|
1534
|
+
pagePatterns.push(nextData.page);
|
|
1535
|
+
const sortedPatterns = sortRoutes(pagePatterns.map((pagePattern) => ({
|
|
1536
|
+
pagePattern,
|
|
1537
|
+
pattern: routePattern(pagePattern)
|
|
1538
|
+
})));
|
|
1539
|
+
pagePatterns.splice(0, pagePatterns.length, ...sortedPatterns.map(({ pagePattern }) => pagePattern));
|
|
1540
|
+
_cachedPagesRoutePatternKey = null;
|
|
1541
|
+
_cachedPagesRoutePattern = void 0;
|
|
1542
|
+
}
|
|
1462
1543
|
const React = (await import("react")).default;
|
|
1463
1544
|
assertStillCurrent();
|
|
1464
1545
|
let AppComponent = window.__VINEXT_APP__;
|
|
@@ -1524,6 +1605,7 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1524
1605
|
else {
|
|
1525
1606
|
let browserUrl = url;
|
|
1526
1607
|
let htmlFetchUrl = fetchUrl;
|
|
1608
|
+
const routeMasked = options.routeMasked ?? routeUrl !== url;
|
|
1527
1609
|
const configRedirect = hasClientRedirectRules() && clientConfigRedirectCouldMatch(browserUrl) ? await resolveClientConfigRedirect(browserUrl) : null;
|
|
1528
1610
|
if (configRedirect) {
|
|
1529
1611
|
const redirectedUrl = resolveLocalRedirectUrl(configRedirect);
|
|
@@ -1531,30 +1613,37 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1531
1613
|
throw new InternalNavigationRedirect(redirectedUrl);
|
|
1532
1614
|
}
|
|
1533
1615
|
let routeLookupUrl = routeUrl;
|
|
1534
|
-
|
|
1616
|
+
let routePattern = options.routePattern;
|
|
1617
|
+
if (!routeMasked && hasClientRewriteRules()) {
|
|
1535
1618
|
const syncConfigRewrite = hasClientAppRouteManifest() ? void 0 : resolveClientConfigRewriteSync(browserUrl);
|
|
1536
1619
|
const configRewrite = syncConfigRewrite === void 0 ? await resolveClientConfigRewrite(browserUrl) : syncConfigRewrite;
|
|
1537
1620
|
if (configRewrite?.kind === "document") scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a document route");
|
|
1538
1621
|
else if (configRewrite?.kind === "rewrite") {
|
|
1539
1622
|
routeLookupUrl = configRewrite.href;
|
|
1540
1623
|
htmlFetchUrl = configRewrite.href;
|
|
1624
|
+
routePattern = void 0;
|
|
1541
1625
|
}
|
|
1542
1626
|
}
|
|
1543
|
-
const pagesDataTargetOptions = {
|
|
1627
|
+
const pagesDataTargetOptions = {
|
|
1628
|
+
locale: options.locale,
|
|
1629
|
+
routePattern
|
|
1630
|
+
};
|
|
1631
|
+
const middlewareTargetOptions = { locale: options.locale };
|
|
1544
1632
|
let dataTarget = resolvePagesDataNavigationTarget(routeLookupUrl, __basePath, pagesDataTargetOptions);
|
|
1545
1633
|
let middlewareDataResponse;
|
|
1546
1634
|
let middlewareEffect = null;
|
|
1547
1635
|
let middlewareRewrittenTarget;
|
|
1548
|
-
const
|
|
1636
|
+
const middlewareUrl = routeMasked ? browserUrl : routeUrl;
|
|
1637
|
+
const middlewareProbeDataHref = getMiddlewarePagesDataFetchUrl(middlewareUrl, dataTarget, routeUrl);
|
|
1549
1638
|
if (middlewareProbeDataHref !== null) {
|
|
1550
1639
|
middlewareDataCacheEvictHref = getPagesDataCacheHref(middlewareProbeDataHref);
|
|
1551
1640
|
try {
|
|
1552
|
-
middlewareEffect = await resolveMiddlewareDataEffect(
|
|
1641
|
+
middlewareEffect = await resolveMiddlewareDataEffect(middlewareUrl, controller.signal, dataTarget, routeUrl);
|
|
1553
1642
|
} catch (err) {
|
|
1554
1643
|
if (err instanceof DOMException && err.name === "AbortError") throw new NavigationCancelledError(browserUrl);
|
|
1555
1644
|
throw err;
|
|
1556
1645
|
}
|
|
1557
|
-
if (middlewareEffect?.rewriteTarget) middlewareRewrittenTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath,
|
|
1646
|
+
if (middlewareEffect?.rewriteTarget) middlewareRewrittenTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath, middlewareTargetOptions);
|
|
1558
1647
|
if (middlewareEffect) {
|
|
1559
1648
|
if (shouldEvictMiddlewareDataCache(middlewareEffect, middlewareRewrittenTarget !== void 0 ? middlewareRewrittenTarget : dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
|
|
1560
1649
|
else middlewareDataCacheEvictHref = null;
|
|
@@ -1567,14 +1656,14 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1567
1656
|
if (!redirectedUrl) scheduleHardNavigationAndThrow(redirectLocation, "Navigation redirected externally");
|
|
1568
1657
|
throw new InternalNavigationRedirect(redirectedUrl);
|
|
1569
1658
|
} else if (middlewareEffect) {
|
|
1570
|
-
if (middlewareEffect.rewriteTarget ||
|
|
1659
|
+
if (middlewareEffect.rewriteTarget || !routeMasked) middlewareDataResponse = middlewareEffect.response;
|
|
1571
1660
|
if (middlewareEffect.rewriteTarget) {
|
|
1572
1661
|
const rewrittenOwner = resolveDirectHybridClientRouteOwner(middlewareEffect.rewriteTarget, __basePath);
|
|
1573
1662
|
if (rewrittenOwner === "app" || rewrittenOwner === "document") {
|
|
1574
1663
|
options.beforeHistoryChange?.();
|
|
1575
1664
|
scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a non-Pages route");
|
|
1576
1665
|
}
|
|
1577
|
-
const rewrittenTarget = middlewareRewrittenTarget ?? resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath,
|
|
1666
|
+
const rewrittenTarget = middlewareRewrittenTarget ?? resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath, middlewareTargetOptions);
|
|
1578
1667
|
if (!rewrittenTarget) {
|
|
1579
1668
|
options.beforeHistoryChange?.();
|
|
1580
1669
|
scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a non-Pages route");
|
|
@@ -1584,9 +1673,13 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1584
1673
|
}
|
|
1585
1674
|
if (middlewareEffect && shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
|
|
1586
1675
|
else if (middlewareEffect) middlewareDataCacheEvictHref = null;
|
|
1676
|
+
if (middlewareEffect?.rewriteTarget) routePattern = void 0;
|
|
1587
1677
|
if (dataTarget?.dataKind === "static" || dataTarget?.dataKind === "server") await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options, middlewareDataResponse);
|
|
1588
1678
|
else if (dataTarget) await navigateClientNoData(browserUrl, dataTarget, controller, assertStillCurrent, options);
|
|
1589
|
-
else await navigateClientHtml(browserUrl, htmlFetchUrl, controller, navId, assertStillCurrent,
|
|
1679
|
+
else await navigateClientHtml(browserUrl, htmlFetchUrl, controller, navId, assertStillCurrent, {
|
|
1680
|
+
...options,
|
|
1681
|
+
routePattern
|
|
1682
|
+
});
|
|
1590
1683
|
}
|
|
1591
1684
|
} finally {
|
|
1592
1685
|
if (navId === routerRuntimeState.navigationId) routerRuntimeState.activeAbortController = null;
|
|
@@ -1677,7 +1770,7 @@ function dispatchNavigateEvent() {
|
|
|
1677
1770
|
* @param fullUrl absolute URL committed to the browser (with basePath)
|
|
1678
1771
|
* @param navState router-level metadata (`url`, `as`, `options`) the popstate
|
|
1679
1772
|
* handler needs to honour stickiness — most importantly the active
|
|
1680
|
-
* locale and the
|
|
1773
|
+
* locale and the Next-compatible basePath-prefixed `as` path.
|
|
1681
1774
|
*/
|
|
1682
1775
|
function updateHistory(mode, fullUrl, navState) {
|
|
1683
1776
|
const previousKey = getRouterStateKey(window.history.state);
|
|
@@ -1719,9 +1812,8 @@ function throwNoRouterInstance() {
|
|
|
1719
1812
|
/**
|
|
1720
1813
|
* Shared client-side navigation flow used by both `useRouter()` and the
|
|
1721
1814
|
* `Router` singleton. The only differences between push/replace are the
|
|
1722
|
-
* history method (`pushState` vs `replaceState`)
|
|
1723
|
-
*
|
|
1724
|
-
* back/forward restoration while replace does not.
|
|
1815
|
+
* history method (`pushState` vs `replaceState`) and the fact that push saves
|
|
1816
|
+
* scroll position for back/forward restoration while replace does not.
|
|
1725
1817
|
*
|
|
1726
1818
|
* `onStateUpdate` lets the hook trigger a `setState` re-render at the same
|
|
1727
1819
|
* point that hashChangeComplete/routeChangeComplete fires; the singleton
|
|
@@ -1729,36 +1821,69 @@ function throwNoRouterInstance() {
|
|
|
1729
1821
|
*/
|
|
1730
1822
|
async function performNavigation(url, as, options, mode, onStateUpdate, redirectBrowserHref) {
|
|
1731
1823
|
if (typeof window === "undefined") throwNoRouterInstance();
|
|
1824
|
+
const inputHref = resolveUrl(url);
|
|
1825
|
+
const sameOriginPath = isAbsoluteUrl(inputHref) ? toSameOriginPath(inputHref) : null;
|
|
1826
|
+
const origin = getWindowOrigin();
|
|
1827
|
+
const absoluteHistoryUrl = sameOriginPath === null ? void 0 : origin && inputHref.startsWith(origin) ? inputHref.slice(origin.length) : sameOriginPath;
|
|
1828
|
+
const currentRoute = window.__NEXT_DATA__?.page ?? stripBasePath(window.location.pathname, __basePath);
|
|
1829
|
+
const currentAs = stripBasePath(window.location.pathname, __basePath) + window.location.search;
|
|
1830
|
+
const preparedHistoryHref = (isAbsoluteUrl(inputHref) ? toSameOriginAppPath(inputHref, __basePath) : null) ?? absoluteHistoryUrl ?? resolvePagesRouterHref(inputHref, {
|
|
1831
|
+
pathname: currentRoute,
|
|
1832
|
+
asPath: currentAs
|
|
1833
|
+
}, __basePath);
|
|
1834
|
+
const isQueryOnlyString = typeof url === "string" && url.startsWith("?");
|
|
1835
|
+
const urlInheritsCurrentPath = typeof url === "string" && (isQueryOnlyString || options?._vinextInterpolateDynamicRoute === true) || typeof url !== "string" && !url.pathname && (hasUrlObjectQuery(url) || typeof url.search === "string" && url.search.length > 0);
|
|
1836
|
+
const replaceInheritedLocale = options?.locale !== void 0 && (!as ? urlInheritsCurrentPath || typeof url !== "string" && inheritsVisiblePath(url) : typeof as !== "string" && inheritsVisiblePath(as));
|
|
1837
|
+
const credentialedHistoryHref = credentialedSameOriginHref(url);
|
|
1838
|
+
const credentialedDisplayHref = credentialedSameOriginHref(as) ?? (!as ? credentialedHistoryHref : void 0);
|
|
1839
|
+
as = as ? resolveUrl(as, true) : void 0;
|
|
1732
1840
|
assertSafeNavigationUrl(resolveUrl(url));
|
|
1733
|
-
if (as !== void 0) assertSafeNavigationUrl(
|
|
1841
|
+
if (as !== void 0) assertSafeNavigationUrl(as);
|
|
1734
1842
|
const isHydrationQueryUpdate = options?._h === 1;
|
|
1735
1843
|
const navigationLocale = resolveTransitionLocale(options?.locale);
|
|
1736
|
-
const
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1844
|
+
const unlocalizedRouteHref = resolveUrl(isQueryOnlyString ? `${stripBasePath(window.location.pathname, __basePath)}${url}` : url);
|
|
1845
|
+
const localRouteHref = isExternalUrl(unlocalizedRouteHref) ? toSameOriginAppPath(unlocalizedRouteHref, __basePath) : unlocalizedRouteHref;
|
|
1846
|
+
const implicitDynamicRoute = !isHydrationQueryUpdate && as === void 0 && localRouteHref !== null ? resolveDynamicRouteHref(localRouteHref) : null;
|
|
1847
|
+
const routeForNavigation = implicitDynamicRoute?.as ?? unlocalizedRouteHref;
|
|
1848
|
+
let resolved = isHydrationQueryUpdate ? normalizeHydrationNavigationUrl(as ?? resolveUrl(url)) : applyNavigationLocale(as ?? resolveUrl(routeForNavigation), navigationLocale, replaceInheritedLocale);
|
|
1849
|
+
let resolvedRoute = isHydrationQueryUpdate ? normalizeHydrationNavigationUrl(resolveUrl(url)) : applyNavigationLocale(routeForNavigation, navigationLocale, replaceInheritedLocale);
|
|
1850
|
+
let routeIdentityHref = implicitDynamicRoute ? removeNavigationLocalePrefix(implicitDynamicRoute.href) : void 0;
|
|
1851
|
+
if (urlInheritsCurrentPath) {
|
|
1852
|
+
const internalDynamicRoute = resolveCurrentDynamicRoute(unlocalizedRouteHref, as);
|
|
1853
|
+
if (internalDynamicRoute) {
|
|
1854
|
+
if (internalDynamicRoute.as) {
|
|
1855
|
+
const localizedRoute = applyNavigationLocale(internalDynamicRoute.as, navigationLocale, replaceInheritedLocale);
|
|
1856
|
+
if (as === void 0) resolved = localizedRoute;
|
|
1857
|
+
resolvedRoute = localizedRoute;
|
|
1858
|
+
} else resolvedRoute = internalDynamicRoute.href;
|
|
1859
|
+
routeIdentityHref = internalDynamicRoute.href;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
if (isExternalUrl(resolvedRoute)) {
|
|
1863
|
+
const localPath = toPreparedSameOriginPath(resolvedRoute);
|
|
1864
|
+
if (localPath == null) {
|
|
1865
|
+
window.location.href = resolvedRoute;
|
|
1866
|
+
return false;
|
|
1867
|
+
}
|
|
1868
|
+
resolvedRoute = localPath;
|
|
1742
1869
|
}
|
|
1743
1870
|
if (isExternalUrl(resolved)) {
|
|
1744
|
-
const localPath =
|
|
1871
|
+
const localPath = toPreparedSameOriginPath(resolved);
|
|
1745
1872
|
if (localPath == null) {
|
|
1746
|
-
if (
|
|
1747
|
-
|
|
1748
|
-
|
|
1873
|
+
if (process.env.NODE_ENV !== "production") throw new Error(`Invalid href: "${toBrowserNavigationHref(resolvedRoute, window.location.href, __basePath)}" and as: "${resolved}", received relative href and external as
|
|
1874
|
+
See more info: https://nextjs.org/docs/messages/invalid-relative-url-external-as`);
|
|
1875
|
+
window.location.href = resolved;
|
|
1876
|
+
return false;
|
|
1749
1877
|
}
|
|
1750
1878
|
resolved = localPath;
|
|
1751
1879
|
}
|
|
1752
|
-
if (isExternalUrl(resolvedRoute)) {
|
|
1753
|
-
const localPath = toSameOriginAppPath(resolvedRoute, __basePath);
|
|
1754
|
-
if (localPath != null) resolvedRoute = localPath;
|
|
1755
|
-
}
|
|
1756
1880
|
resolved = normalizePathTrailingSlash(resolved, __trailingSlash);
|
|
1757
1881
|
resolvedRoute = normalizePathTrailingSlash(resolvedRoute, __trailingSlash);
|
|
1758
1882
|
let interpolatedRoute = resolvedRoute;
|
|
1759
1883
|
if (resolvedRoute.includes("[")) {
|
|
1760
|
-
const projection = interpolateDynamicRouteHref(resolvedRoute, resolved, typeof url === "string" || !url.query || typeof url.query === "string" ? void 0 : url.query);
|
|
1884
|
+
const projection = interpolateDynamicRouteHref(resolvedRoute, resolved, typeof url === "string" || url.search || !url.query || typeof url.query === "string" ? void 0 : url.query);
|
|
1761
1885
|
if (projection?.href) {
|
|
1886
|
+
routeIdentityHref ??= removeNavigationLocalePrefix(resolvedRoute);
|
|
1762
1887
|
interpolatedRoute = projection.href;
|
|
1763
1888
|
if (as === void 0 && stripHash(resolved).split("?", 1)[0] === projection.routePathname) {
|
|
1764
1889
|
const remaining = new URLSearchParams();
|
|
@@ -1774,16 +1899,14 @@ async function performNavigation(url, as, options, mode, onStateUpdate, redirect
|
|
|
1774
1899
|
resolved = normalizePathTrailingSlash(`${projection.href.split(/[?#]/, 1)[0]}${searchStr ? `?${searchStr}` : ""}${hashStr}`, __trailingSlash);
|
|
1775
1900
|
}
|
|
1776
1901
|
} else {
|
|
1777
|
-
const
|
|
1778
|
-
|
|
1779
|
-
return value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
1780
|
-
}) : [];
|
|
1781
|
-
const hasExplicitHrefPathname = typeof url === "string" || url.pathname !== void 0;
|
|
1902
|
+
const hrefInterpolationError = projection ? getHrefInterpolationError(resolvedRoute, projection.routePathname, projection.query) : null;
|
|
1903
|
+
const hasExplicitHrefPathname = typeof url === "string" || !urlInheritsCurrentPath;
|
|
1782
1904
|
const isMiddlewareMatch = options?.shallow !== true && getPagesMiddlewareDataHref(resolved, __basePath, { locale: navigationLocale }) !== null;
|
|
1783
|
-
if (
|
|
1905
|
+
if (hrefInterpolationError && hasExplicitHrefPathname && !isMiddlewareMatch) {
|
|
1784
1906
|
const asPathname = stripHash(resolved).split("?", 1)[0];
|
|
1785
1907
|
const routePathname = projection?.routePathname ?? stripHash(resolvedRoute).split("?", 1)[0];
|
|
1786
|
-
|
|
1908
|
+
if (asPathname === routePathname) throw hrefInterpolationError;
|
|
1909
|
+
throw new HrefInterpolationError(`The provided \`as\` value (${asPathname}) is incompatible with the \`href\` value (${routePathname}). Read more: https://nextjs.org/docs/messages/incompatible-href-as`);
|
|
1787
1910
|
}
|
|
1788
1911
|
interpolatedRoute = resolved;
|
|
1789
1912
|
}
|
|
@@ -1795,50 +1918,59 @@ async function performNavigation(url, as, options, mode, onStateUpdate, redirect
|
|
|
1795
1918
|
if (parsed.origin === getWindowOrigin()) browserEventUrl = parsed.pathname + parsed.search + parsed.hash;
|
|
1796
1919
|
} catch {}
|
|
1797
1920
|
const fullRouteUrl = interpolatedRoute !== resolved ? normalizePathTrailingSlash(toBrowserNavigationHref(interpolatedRoute, window.location.href, __basePath), __trailingSlash) : full;
|
|
1921
|
+
if (routeIdentityHref && !routeIdentityHref.startsWith("/") && !isAbsoluteUrl(routeIdentityHref)) routeIdentityHref = resolvePagesRouterHref(routeIdentityHref, {
|
|
1922
|
+
pathname: currentRoute,
|
|
1923
|
+
asPath: currentAs
|
|
1924
|
+
}, __basePath);
|
|
1925
|
+
const routeFetchUrl = routeIdentityHref ? replaceUrlPathname(routeIdentityHref, new URL(fullRouteUrl, window.location.href).pathname) : void 0;
|
|
1798
1926
|
const errorRouteHtmlFetchUrl = resolvePagesErrorHtmlFetchUrl(url, navigationLocale);
|
|
1799
|
-
const htmlFetchUrl = errorRouteHtmlFetchUrl ?? getPagesHtmlFetchUrl(fullRouteUrl, navigationLocale);
|
|
1927
|
+
const htmlFetchUrl = errorRouteHtmlFetchUrl ?? getPagesHtmlFetchUrl(routeFetchUrl ?? fullRouteUrl, navigationLocale);
|
|
1800
1928
|
const shallow = options?.shallow ?? false;
|
|
1801
1929
|
const doScroll = options?.scroll !== false;
|
|
1802
1930
|
const hash = extractHash(resolved);
|
|
1803
|
-
const
|
|
1804
|
-
|
|
1805
|
-
y: 0
|
|
1806
|
-
} : null;
|
|
1807
|
-
const navigateOptions = errorRouteHtmlFetchUrl ? {
|
|
1808
|
-
allowNotFoundResponse: true,
|
|
1809
|
-
locale: navigationLocale,
|
|
1810
|
-
mode,
|
|
1811
|
-
scroll: scrollTarget,
|
|
1812
|
-
isHydrationQueryUpdate: options?._h === 1
|
|
1813
|
-
} : {
|
|
1931
|
+
const navigateOptions = {
|
|
1932
|
+
allowNotFoundResponse: errorRouteHtmlFetchUrl !== null,
|
|
1814
1933
|
locale: navigationLocale,
|
|
1815
1934
|
mode,
|
|
1816
|
-
scroll:
|
|
1935
|
+
scroll: doScroll ? {
|
|
1936
|
+
x: 0,
|
|
1937
|
+
y: 0
|
|
1938
|
+
} : null,
|
|
1817
1939
|
isHydrationQueryUpdate: options?._h === 1
|
|
1818
1940
|
};
|
|
1819
1941
|
if (redirectBrowserHref !== void 0) navigateOptions.redirectBrowserHref = redirectBrowserHref;
|
|
1820
|
-
|
|
1821
|
-
if (
|
|
1942
|
+
navigateOptions.routeMasked = as !== void 0 && stripHash(interpolatedRoute).split("?", 1)[0] !== stripHash(resolved).split("?", 1)[0];
|
|
1943
|
+
if (routeIdentityHref) navigateOptions.routePattern = removeTrailingSlash(stripHash(routeIdentityHref).split("?", 1)[0]);
|
|
1944
|
+
const isHashOnlyNavigation = options?._h !== 1 && isHashOnlyChange(full);
|
|
1822
1945
|
const navStateOptions = { shallow };
|
|
1823
1946
|
if (navigationLocale !== void 0) navStateOptions.locale = navigationLocale;
|
|
1824
|
-
const
|
|
1947
|
+
const currentAppUrl = stripBasePath(window.location.pathname, __basePath) + window.location.search;
|
|
1948
|
+
const historyRouteUrl = routeIdentityHref ?? (redirectBrowserHref === void 0 ? preparedHistoryHref : interpolatedRoute);
|
|
1949
|
+
const absoluteInputHistoryUrl = redirectBrowserHref === void 0 && absoluteHistoryUrl !== void 0 && (__basePath === "" || !hasBasePath(new URL(absoluteHistoryUrl, window.location.href).pathname, __basePath)) ? absoluteHistoryUrl : void 0;
|
|
1950
|
+
const historyUrl = historyRouteUrl.startsWith("#") ? currentAppUrl + historyRouteUrl : historyRouteUrl;
|
|
1951
|
+
const preparedHistoryAs = resolved.startsWith("#") ? currentAppUrl + resolved : redirectBrowserHref !== void 0 || resolved.startsWith("//") ? resolved : resolvePagesRouterHref(resolved, {
|
|
1952
|
+
pathname: currentRoute,
|
|
1953
|
+
asPath: currentAs
|
|
1954
|
+
}, __basePath);
|
|
1825
1955
|
const navState = {
|
|
1826
|
-
url:
|
|
1827
|
-
as:
|
|
1956
|
+
url: credentialedHistoryHref ?? normalizePathTrailingSlash(absoluteInputHistoryUrl === void 0 ? withBasePath(historyUrl, __basePath) : historyUrl, __trailingSlash),
|
|
1957
|
+
as: credentialedDisplayHref ?? normalizePathTrailingSlash(withBasePath(preparedHistoryAs, __basePath), __trailingSlash),
|
|
1828
1958
|
options: navStateOptions
|
|
1829
1959
|
};
|
|
1830
1960
|
if (options?._h !== 1) cancelActiveNavigationEvent({ shallow });
|
|
1831
|
-
if (
|
|
1961
|
+
if (isHashOnlyNavigation) {
|
|
1832
1962
|
if (mode === "push") saveScrollPosition();
|
|
1833
1963
|
const eventUrl = resolveHashUrl(browserEventUrl);
|
|
1834
1964
|
routerEvents.emit("hashChangeStart", eventUrl, { shallow });
|
|
1835
|
-
updateHistory(mode, resolved.startsWith("#") ? resolved : redirectBrowserHref ?? full, navState);
|
|
1965
|
+
updateHistory(mode, resolved.startsWith("#") ? resolved : redirectBrowserHref ?? credentialedDisplayHref ?? full, navState);
|
|
1836
1966
|
if (doScroll) scrollToHashTarget(extractHash(resolved));
|
|
1837
1967
|
onStateUpdate?.();
|
|
1838
1968
|
routerEvents.emit("hashChangeComplete", eventUrl, { shallow });
|
|
1839
1969
|
dispatchNavigateEvent();
|
|
1840
1970
|
return true;
|
|
1841
1971
|
}
|
|
1972
|
+
const currentLocale = getCurrentUrlLocale();
|
|
1973
|
+
if (mode === "push" && interpolatedRoute !== resolved && stripHash(full) === routerRuntimeState.lastPathnameAndSearch && navigationLocale === currentLocale) mode = "replace";
|
|
1842
1974
|
const appPath = getLocalPathname(resolved);
|
|
1843
1975
|
const appPathNorm = appPath !== null ? removeTrailingSlash(appPath) : null;
|
|
1844
1976
|
const appPathEntry = appPathNorm !== null ? getPagesRouterComponentsMap()[appPathNorm] : void 0;
|
|
@@ -1867,12 +1999,12 @@ async function performNavigation(url, as, options, mode, onStateUpdate, redirect
|
|
|
1867
1999
|
if (beforeHistoryChangeEmitted) return;
|
|
1868
2000
|
beforeHistoryChangeEmitted = true;
|
|
1869
2001
|
routerEvents.emit("beforeHistoryChange", browserEventUrl, { shallow });
|
|
1870
|
-
updateHistory(mode, redirectBrowserHref ?? full, navState);
|
|
2002
|
+
updateHistory(mode, redirectBrowserHref ?? credentialedDisplayHref ?? full, navState);
|
|
1871
2003
|
};
|
|
1872
2004
|
if (!shallow) {
|
|
1873
2005
|
if (reusesMountedConfigRewritePage(full)) emitBeforeHistoryChange();
|
|
1874
2006
|
navigateOptions.beforeHistoryChange = emitBeforeHistoryChange;
|
|
1875
|
-
const result = await runNavigateClient(full, browserEventUrl, redirectBrowserHref ?? htmlFetchUrl, navigateOptions, fullRouteUrl, eventContext);
|
|
2007
|
+
const result = await runNavigateClient(full, browserEventUrl, redirectBrowserHref ?? htmlFetchUrl, navigateOptions, routeFetchUrl ?? fullRouteUrl, eventContext);
|
|
1876
2008
|
if (typeof result === "object") {
|
|
1877
2009
|
if (eventContext) clearActiveNavigationEvent(eventContext);
|
|
1878
2010
|
return performNavigation(result.redirectDestination, void 0, {
|
|
@@ -1921,7 +2053,7 @@ async function prefetchUrl(url, as) {
|
|
|
1921
2053
|
const displayUrl = as ?? url;
|
|
1922
2054
|
const dataTarget = resolvePagesDataNavigationTarget(url, __basePath);
|
|
1923
2055
|
if (dataTarget) {
|
|
1924
|
-
const middlewareDataHref = displayUrl === url ? dataTarget.middlewareDataHref : getPagesMiddlewareDataHref(displayUrl, __basePath) ?? void 0;
|
|
2056
|
+
const middlewareDataHref = displayUrl === url ? dataTarget.middlewareDataHref : getPagesMiddlewareDataHref(displayUrl, __basePath, {}, url) ?? void 0;
|
|
1925
2057
|
prefetchPagesData({
|
|
1926
2058
|
...dataTarget,
|
|
1927
2059
|
middlewareDataHref
|
|
@@ -2027,7 +2159,8 @@ function handlePagesRouterPopState(e) {
|
|
|
2027
2159
|
if (state !== null && state !== void 0 && !isNextRouterState(state)) return;
|
|
2028
2160
|
if (wasFirst && !routerRuntimeState.routerDidNavigate && isNextRouterState(state)) {
|
|
2029
2161
|
const currentLocale = window.__VINEXT_LOCALE__;
|
|
2030
|
-
|
|
2162
|
+
const stateAs = typeof state.as === "string" ? removeNavigationLocalePrefix(stripHash(toHistoryAppPath(state.as))) : void 0;
|
|
2163
|
+
if (state.options?.locale === currentLocale && stateAs === getTrackedPagesRouterAsPath()) return;
|
|
2031
2164
|
}
|
|
2032
2165
|
const currentHash = window.location.hash;
|
|
2033
2166
|
const isHashOnly = browserUrl === routerRuntimeState.lastPathnameAndSearch && (currentHash !== routerRuntimeState.lastHash || currentHash !== "");
|
|
@@ -2085,14 +2218,28 @@ function handlePagesRouterPopState(e) {
|
|
|
2085
2218
|
x: 0,
|
|
2086
2219
|
y: 0
|
|
2087
2220
|
} : readScrollPosition(state);
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2221
|
+
let stateFetchUrl = browserUrl;
|
|
2222
|
+
let routePattern;
|
|
2223
|
+
let routeMasked = false;
|
|
2224
|
+
if (isNextRouterState(state) && typeof state.url === "string" && typeof state.as === "string" && stripHash(state.url) !== stripHash(state.as)) {
|
|
2225
|
+
const stateUrl = toHistoryAppPath(state.url);
|
|
2226
|
+
const stateAs = toHistoryAppPath(state.as);
|
|
2227
|
+
const dynamicRoute = interpolateDynamicRouteHref(stateUrl, removeNavigationLocalePrefix(stateAs));
|
|
2228
|
+
const concreteRouteUrl = dynamicRoute?.href || stateUrl;
|
|
2229
|
+
const fetchRouteUrl = applyNavigationLocale(concreteRouteUrl, effectiveLocale);
|
|
2230
|
+
stateFetchUrl = normalizePathTrailingSlash(withBasePath(fetchRouteUrl, __basePath), __trailingSlash);
|
|
2231
|
+
if (dynamicRoute?.href) routePattern = removeTrailingSlash(stripHash(removeNavigationLocalePrefix(stateUrl)).split("?", 1)[0]);
|
|
2232
|
+
const routePathname = getLocalPathname(concreteRouteUrl);
|
|
2233
|
+
const displayPathname = getLocalPathname(stateAs);
|
|
2234
|
+
routeMasked = routePathname === null || displayPathname === null || removeNavigationLocalePrefix(routePathname) !== removeNavigationLocalePrefix(displayPathname);
|
|
2235
|
+
}
|
|
2236
|
+
const result = await runNavigateClient(browserUrl, fullEventUrl, getPagesHtmlFetchUrl(stateFetchUrl, effectiveLocale), {
|
|
2237
|
+
locale: effectiveLocale,
|
|
2238
|
+
routePattern,
|
|
2239
|
+
routeMasked,
|
|
2093
2240
|
scroll: scrollTarget,
|
|
2094
2241
|
beforeHistoryChange: emitBeforeHistoryChange
|
|
2095
|
-
},
|
|
2242
|
+
}, stateFetchUrl, eventContext);
|
|
2096
2243
|
if (typeof result === "object") {
|
|
2097
2244
|
clearActiveNavigationEvent(eventContext);
|
|
2098
2245
|
await performNavigation(result.redirectDestination, void 0, { locale: false }, "replace", void 0, isAbsoluteOrProtocolRelativeUrl(result.redirectDestination) ? result.redirectDestination : void 0);
|
|
@@ -2165,6 +2312,33 @@ function withRouter(ComposedComponent) {
|
|
|
2165
2312
|
if (process.env.NODE_ENV !== "production") WithRouterWrapper.displayName = `withRouter(${composed.displayName || composed.name || "Unknown"})`;
|
|
2166
2313
|
return WithRouterWrapper;
|
|
2167
2314
|
}
|
|
2315
|
+
/**
|
|
2316
|
+
* Pages Router `components` map exposed on the singleton.
|
|
2317
|
+
*
|
|
2318
|
+
* In Next.js, `Router.components` doubles as (a) the cached `PrivateRouteInfo`
|
|
2319
|
+
* keyed by route pattern after a real page render, and (b) a marker store
|
|
2320
|
+
* (`{ __appRouter: true }`) for App Router routes detected via prefetch (see
|
|
2321
|
+
* `packages/next/src/shared/lib/router/router.ts:2525`). The Next.js deploy
|
|
2322
|
+
* test suite asserts the latter through `window.next.router.components`.
|
|
2323
|
+
*
|
|
2324
|
+
* vinext only writes the marker variant — the cached-page-info side is handled
|
|
2325
|
+
* by Vite's module graph + our own loader manifest — but the property must be
|
|
2326
|
+
* present and mutable so the deploy assertion can find it. The map lives
|
|
2327
|
+
* behind a `Symbol.for` global so the Link shim's Pages-mode prefetch branch
|
|
2328
|
+
* writes to the same instance even when Vite resolves the router shim and
|
|
2329
|
+
* the link shim through different module IDs.
|
|
2330
|
+
*
|
|
2331
|
+
* Issue: https://github.com/cloudflare/vinext/issues/1526
|
|
2332
|
+
*/
|
|
2333
|
+
const _components = getPagesRouterComponentsMap();
|
|
2334
|
+
function navigatePagesRouter(url, as, options, mode) {
|
|
2335
|
+
if (typeof window === "undefined") throwNoRouterInstance();
|
|
2336
|
+
const preparedUrl = prepareUrl(url);
|
|
2337
|
+
const preparedAs = as ? prepareUrl(as) : void 0;
|
|
2338
|
+
assertSafeNavigationUrl(resolveUrl(preparedUrl));
|
|
2339
|
+
if (preparedAs) assertSafeNavigationUrl(resolveUrl(preparedAs));
|
|
2340
|
+
return performNavigation(preparedUrl, preparedAs, options, mode);
|
|
2341
|
+
}
|
|
2168
2342
|
const RouterMethods = {
|
|
2169
2343
|
router: null,
|
|
2170
2344
|
readyCallbacks: [],
|
|
@@ -2172,20 +2346,10 @@ const RouterMethods = {
|
|
|
2172
2346
|
callback();
|
|
2173
2347
|
},
|
|
2174
2348
|
/** See `_components` comment above for the dual role this map plays. */
|
|
2175
|
-
components:
|
|
2349
|
+
components: _components,
|
|
2176
2350
|
sdc: getPagesStaticDataCache(),
|
|
2177
|
-
push: (url, as, options) =>
|
|
2178
|
-
|
|
2179
|
-
assertSafeNavigationUrl(resolveUrl(url));
|
|
2180
|
-
if (as !== void 0) assertSafeNavigationUrl(String(as));
|
|
2181
|
-
return performNavigation(url, as, options, "push");
|
|
2182
|
-
},
|
|
2183
|
-
replace: (url, as, options) => {
|
|
2184
|
-
if (typeof window === "undefined") throwNoRouterInstance();
|
|
2185
|
-
assertSafeNavigationUrl(resolveUrl(url));
|
|
2186
|
-
if (as !== void 0) assertSafeNavigationUrl(String(as));
|
|
2187
|
-
return performNavigation(url, as, options, "replace");
|
|
2188
|
-
},
|
|
2351
|
+
push: (url, as, options) => navigatePagesRouter(url, as, options, "push"),
|
|
2352
|
+
replace: (url, as, options) => navigatePagesRouter(url, as, options, "replace"),
|
|
2189
2353
|
back: () => {
|
|
2190
2354
|
if (typeof window === "undefined") throwNoRouterInstance();
|
|
2191
2355
|
window.history.back();
|