vinext 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/prerender.d.ts +9 -1
  4. package/dist/build/prerender.js +42 -12
  5. package/dist/build/run-prerender.d.ts +10 -2
  6. package/dist/build/run-prerender.js +15 -1
  7. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  8. package/dist/client/app-nav-failure-handler.js +44 -0
  9. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  10. package/dist/client/pages-router-link-navigation.js +32 -2
  11. package/dist/client/vinext-next-data.d.ts +18 -1
  12. package/dist/client/vinext-next-data.js +2 -0
  13. package/dist/client/window-next.d.ts +2 -1
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -1
  17. package/dist/config/config-matchers.js +87 -16
  18. package/dist/config/next-config.d.ts +46 -4
  19. package/dist/config/next-config.js +147 -48
  20. package/dist/config/tsconfig-paths.js +14 -1
  21. package/dist/deploy.d.ts +30 -11
  22. package/dist/deploy.js +200 -112
  23. package/dist/entries/app-browser-entry.d.ts +9 -3
  24. package/dist/entries/app-browser-entry.js +21 -3
  25. package/dist/entries/app-rsc-entry.d.ts +2 -0
  26. package/dist/entries/app-rsc-entry.js +65 -5
  27. package/dist/entries/app-rsc-manifest.js +2 -0
  28. package/dist/entries/app-ssr-entry.js +1 -1
  29. package/dist/entries/pages-client-entry.js +66 -20
  30. package/dist/entries/pages-server-entry.js +47 -31
  31. package/dist/index.js +417 -102
  32. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  33. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  34. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  35. package/dist/plugins/fonts.js +5 -4
  36. package/dist/plugins/optimize-imports.d.ts +2 -1
  37. package/dist/plugins/optimize-imports.js +11 -9
  38. package/dist/plugins/postcss.js +7 -7
  39. package/dist/plugins/strip-server-exports.d.ts +9 -7
  40. package/dist/plugins/strip-server-exports.js +493 -46
  41. package/dist/plugins/typeof-window.d.ts +14 -0
  42. package/dist/plugins/typeof-window.js +150 -0
  43. package/dist/routing/app-route-graph.d.ts +2 -1
  44. package/dist/routing/app-route-graph.js +46 -16
  45. package/dist/routing/file-matcher.d.ts +10 -1
  46. package/dist/routing/file-matcher.js +22 -1
  47. package/dist/routing/pages-router.js +3 -3
  48. package/dist/routing/utils.d.ts +35 -6
  49. package/dist/routing/utils.js +59 -7
  50. package/dist/server/api-handler.d.ts +6 -1
  51. package/dist/server/api-handler.js +21 -15
  52. package/dist/server/app-browser-action-result.d.ts +19 -6
  53. package/dist/server/app-browser-action-result.js +20 -11
  54. package/dist/server/app-browser-entry.js +175 -91
  55. package/dist/server/app-browser-error.d.ts +10 -6
  56. package/dist/server/app-browser-error.js +43 -8
  57. package/dist/server/app-browser-hydration.d.ts +2 -0
  58. package/dist/server/app-browser-hydration.js +1 -0
  59. package/dist/server/app-browser-navigation-controller.d.ts +5 -3
  60. package/dist/server/app-browser-navigation-controller.js +23 -2
  61. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  62. package/dist/server/app-browser-server-action-navigation.js +9 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js +19 -11
  65. package/dist/server/app-browser-stream.js +86 -43
  66. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  67. package/dist/server/app-elements-wire.d.ts +6 -1
  68. package/dist/server/app-elements-wire.js +14 -4
  69. package/dist/server/app-elements.d.ts +2 -2
  70. package/dist/server/app-elements.js +2 -2
  71. package/dist/server/app-fallback-renderer.d.ts +1 -0
  72. package/dist/server/app-fallback-renderer.js +3 -1
  73. package/dist/server/app-optimistic-routing.js +2 -2
  74. package/dist/server/app-page-boundary-render.d.ts +1 -0
  75. package/dist/server/app-page-boundary-render.js +27 -14
  76. package/dist/server/app-page-cache-render.d.ts +53 -0
  77. package/dist/server/app-page-cache-render.js +91 -0
  78. package/dist/server/app-page-cache.d.ts +16 -2
  79. package/dist/server/app-page-cache.js +62 -1
  80. package/dist/server/app-page-dispatch.d.ts +26 -0
  81. package/dist/server/app-page-dispatch.js +149 -92
  82. package/dist/server/app-page-element-builder.d.ts +1 -0
  83. package/dist/server/app-page-element-builder.js +5 -2
  84. package/dist/server/app-page-execution.d.ts +6 -1
  85. package/dist/server/app-page-execution.js +21 -1
  86. package/dist/server/app-page-probe.d.ts +1 -0
  87. package/dist/server/app-page-probe.js +4 -0
  88. package/dist/server/app-page-render-observation.d.ts +3 -1
  89. package/dist/server/app-page-render-observation.js +17 -1
  90. package/dist/server/app-page-render.d.ts +12 -1
  91. package/dist/server/app-page-render.js +42 -4
  92. package/dist/server/app-page-request.d.ts +2 -0
  93. package/dist/server/app-page-request.js +2 -1
  94. package/dist/server/app-page-route-wiring.d.ts +3 -1
  95. package/dist/server/app-page-route-wiring.js +14 -5
  96. package/dist/server/app-page-stream.d.ts +15 -3
  97. package/dist/server/app-page-stream.js +11 -5
  98. package/dist/server/app-pages-bridge.d.ts +23 -1
  99. package/dist/server/app-pages-bridge.js +26 -17
  100. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  101. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  102. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  103. package/dist/server/app-ppr-fallback-shell.js +8 -1
  104. package/dist/server/app-route-handler-dispatch.js +9 -2
  105. package/dist/server/app-route-handler-policy.d.ts +1 -0
  106. package/dist/server/app-router-entry.js +5 -0
  107. package/dist/server/app-rsc-cache-busting.js +2 -0
  108. package/dist/server/app-rsc-handler.d.ts +28 -0
  109. package/dist/server/app-rsc-handler.js +195 -59
  110. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  111. package/dist/server/app-rsc-route-matching.js +8 -2
  112. package/dist/server/app-segment-config.d.ts +9 -1
  113. package/dist/server/app-segment-config.js +12 -3
  114. package/dist/server/app-server-action-execution.d.ts +1 -0
  115. package/dist/server/app-server-action-execution.js +47 -15
  116. package/dist/server/app-ssr-entry.d.ts +2 -0
  117. package/dist/server/app-ssr-entry.js +84 -39
  118. package/dist/server/before-interactive-head.d.ts +17 -0
  119. package/dist/server/before-interactive-head.js +35 -0
  120. package/dist/server/cache-control.js +4 -0
  121. package/dist/server/csp.js +1 -4
  122. package/dist/server/dev-server.d.ts +2 -2
  123. package/dist/server/dev-server.js +321 -83
  124. package/dist/server/hybrid-route-priority.d.ts +22 -0
  125. package/dist/server/hybrid-route-priority.js +33 -0
  126. package/dist/server/image-optimization.d.ts +18 -9
  127. package/dist/server/image-optimization.js +37 -23
  128. package/dist/server/implicit-tags.d.ts +2 -1
  129. package/dist/server/implicit-tags.js +4 -1
  130. package/dist/server/middleware-matcher.js +12 -3
  131. package/dist/server/middleware-runtime.d.ts +3 -4
  132. package/dist/server/middleware-runtime.js +2 -0
  133. package/dist/server/navigation-planner.d.ts +135 -41
  134. package/dist/server/navigation-planner.js +138 -0
  135. package/dist/server/navigation-trace.d.ts +9 -1
  136. package/dist/server/navigation-trace.js +9 -1
  137. package/dist/server/operation-token.d.ts +40 -0
  138. package/dist/server/operation-token.js +85 -0
  139. package/dist/server/pages-api-route.d.ts +6 -0
  140. package/dist/server/pages-api-route.js +13 -2
  141. package/dist/server/pages-asset-tags.d.ts +2 -1
  142. package/dist/server/pages-asset-tags.js +6 -2
  143. package/dist/server/pages-data-route.d.ts +9 -2
  144. package/dist/server/pages-data-route.js +18 -6
  145. package/dist/server/pages-dev-module-url.d.ts +4 -0
  146. package/dist/server/pages-dev-module-url.js +15 -0
  147. package/dist/server/pages-document-initial-props.d.ts +4 -15
  148. package/dist/server/pages-document-initial-props.js +27 -56
  149. package/dist/server/pages-get-initial-props.d.ts +54 -4
  150. package/dist/server/pages-get-initial-props.js +43 -1
  151. package/dist/server/pages-i18n.js +2 -2
  152. package/dist/server/pages-node-compat.js +2 -2
  153. package/dist/server/pages-page-data.d.ts +11 -2
  154. package/dist/server/pages-page-data.js +207 -34
  155. package/dist/server/pages-page-handler.d.ts +4 -2
  156. package/dist/server/pages-page-handler.js +62 -23
  157. package/dist/server/pages-page-response.d.ts +4 -1
  158. package/dist/server/pages-page-response.js +11 -8
  159. package/dist/server/pages-readiness.js +1 -1
  160. package/dist/server/pages-request-pipeline.d.ts +8 -7
  161. package/dist/server/pages-request-pipeline.js +126 -47
  162. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  163. package/dist/server/pregenerated-concrete-paths.js +2 -19
  164. package/dist/server/prerender-manifest.d.ts +33 -0
  165. package/dist/server/prerender-manifest.js +54 -0
  166. package/dist/server/prerender-route-params.d.ts +1 -2
  167. package/dist/server/prod-server.d.ts +3 -1
  168. package/dist/server/prod-server.js +50 -13
  169. package/dist/server/request-pipeline.d.ts +3 -15
  170. package/dist/server/request-pipeline.js +58 -47
  171. package/dist/server/rsc-stream-hints.d.ts +5 -1
  172. package/dist/server/rsc-stream-hints.js +6 -1
  173. package/dist/server/seed-cache.js +10 -18
  174. package/dist/server/static-file-cache.js +16 -4
  175. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  176. package/dist/shims/app-router-scroll-state.js +14 -2
  177. package/dist/shims/app-router-scroll.d.ts +3 -0
  178. package/dist/shims/app-router-scroll.js +28 -18
  179. package/dist/shims/before-interactive-context.d.ts +14 -3
  180. package/dist/shims/cache-runtime.js +3 -2
  181. package/dist/shims/cache.d.ts +1 -0
  182. package/dist/shims/cache.js +1 -1
  183. package/dist/shims/cdn-cache.d.ts +5 -5
  184. package/dist/shims/document.d.ts +15 -20
  185. package/dist/shims/document.js +5 -8
  186. package/dist/shims/dynamic-preload-chunks.js +6 -4
  187. package/dist/shims/error-boundary.d.ts +2 -0
  188. package/dist/shims/error-boundary.js +7 -0
  189. package/dist/shims/error.js +3 -2
  190. package/dist/shims/error.react-server.d.ts +9 -0
  191. package/dist/shims/error.react-server.js +6 -0
  192. package/dist/shims/fetch-cache.d.ts +3 -1
  193. package/dist/shims/fetch-cache.js +45 -20
  194. package/dist/shims/hash-scroll.js +6 -1
  195. package/dist/shims/headers.js +29 -4
  196. package/dist/shims/image.js +9 -2
  197. package/dist/shims/internal/als-registry.js +28 -1
  198. package/dist/shims/internal/app-route-detection.js +8 -17
  199. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  201. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  202. package/dist/shims/internal/navigation-untracked.js +55 -0
  203. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  204. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  205. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  206. package/dist/shims/internal/pages-data-target.js +17 -8
  207. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  208. package/dist/shims/internal/pages-router-accessor.js +13 -0
  209. package/dist/shims/internal/router-context.d.ts +2 -1
  210. package/dist/shims/internal/router-context.js +3 -1
  211. package/dist/shims/link.js +47 -19
  212. package/dist/shims/metadata.js +4 -4
  213. package/dist/shims/navigation.d.ts +8 -2
  214. package/dist/shims/navigation.js +63 -31
  215. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  216. package/dist/shims/ppr-fallback-shell.js +28 -7
  217. package/dist/shims/router.d.ts +18 -3
  218. package/dist/shims/router.js +512 -142
  219. package/dist/shims/script.js +8 -4
  220. package/dist/shims/server.d.ts +16 -1
  221. package/dist/shims/server.js +44 -12
  222. package/dist/shims/unified-request-context.js +1 -0
  223. package/dist/utils/built-asset-url.d.ts +4 -0
  224. package/dist/utils/built-asset-url.js +11 -0
  225. package/dist/utils/commonjs-loader.d.ts +16 -0
  226. package/dist/utils/commonjs-loader.js +100 -0
  227. package/dist/utils/deployment-id.d.ts +8 -0
  228. package/dist/utils/deployment-id.js +22 -0
  229. package/dist/utils/has-trailing-comma.d.ts +24 -0
  230. package/dist/utils/has-trailing-comma.js +62 -0
  231. package/dist/utils/html-limited-bots.d.ts +18 -1
  232. package/dist/utils/html-limited-bots.js +23 -1
  233. package/dist/utils/parse-cookie.d.ts +13 -0
  234. package/dist/utils/parse-cookie.js +52 -0
  235. package/dist/utils/path.d.ts +7 -1
  236. package/dist/utils/path.js +9 -1
  237. package/dist/utils/text-stream.d.ts +1 -1
  238. package/dist/utils/text-stream.js +2 -2
  239. package/dist/utils/vite-version.d.ts +12 -1
  240. package/dist/utils/vite-version.js +9 -1
  241. package/package.json +2 -2
  242. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  243. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -1,7 +1,7 @@
1
1
  import { splitPathSegments } from "../routing/utils.js";
2
2
  import { removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
3
3
  import { assertSafeNavigationUrl } from "./url-safety.js";
4
- import { matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
4
+ import { fillRoutePatternSegments, matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
5
5
  import { isUnknownRecord } from "../utils/record.js";
6
6
  import { AppRouterContext } from "./internal/app-router-context.js";
7
7
  import { RouterContext } from "./internal/router-context.js";
@@ -9,16 +9,18 @@ import { applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDat
9
9
  import { isValidModulePath } from "../client/validate-module-path.js";
10
10
  import { addLocalePrefix, getDomainLocaleUrl, getLocalePathPrefix } from "../utils/domain-locale.js";
11
11
  import { buildPagesDataHref } from "./internal/pages-data-url.js";
12
+ import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../utils/deployment-id.js";
13
+ import { dedupedPagesDataFetch } from "./internal/pages-data-fetch-dedup.js";
12
14
  import { prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
15
+ import { addQueryParam, appendSearchParamsToUrl, mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
16
+ import { resolveHybridClientRouteOwner } from "./internal/hybrid-client-route-owner.js";
13
17
  import { getPagesRouterComponentsMap, markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
14
- import { dedupedPagesDataFetch } from "./internal/pages-data-fetch-dedup.js";
15
18
  import { installWindowNext } from "../client/window-next.js";
16
19
  import { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
17
- import { addQueryParam, appendSearchParamsToUrl, mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
18
20
  import { scrollToHashTarget } from "./hash-scroll.js";
19
- import { setPagesRouterPopStateHandler, setStampInitialHistoryState } from "./pages-router-runtime.js";
21
+ import { installPagesRouterRuntime, setPagesRouterPopStateHandler, setStampInitialHistoryState } from "./pages-router-runtime.js";
20
22
  import { getCurrentBrowserLocale } from "./client-locale.js";
21
- import { createElement, useContext, useEffect, useMemo, useState } from "react";
23
+ import { Component, Fragment, createElement, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
22
24
  //#region src/shims/router.ts
23
25
  /**
24
26
  * next/router shim
@@ -31,6 +33,134 @@ import { createElement, useContext, useEffect, useMemo, useState } from "react";
31
33
  const __basePath = process.env.__NEXT_ROUTER_BASEPATH ?? "";
32
34
  /** trailingSlash from next.config.js, injected by the plugin at build time */
33
35
  const __trailingSlash = process.env.__VINEXT_TRAILING_SLASH === "true";
36
+ /** experimental.scrollRestoration from next.config.js, injected by the plugin at build time */
37
+ const __scrollRestoration = process.env.__NEXT_SCROLL_RESTORATION === "true";
38
+ const noopCommit = () => {};
39
+ const SCROLL_RESTORE_MAX_FRAMES = 60;
40
+ const SCROLL_RESTORE_TOLERANCE_PX = 1;
41
+ /**
42
+ * A version of useLayoutEffect that doesn't warn during SSR.
43
+ * `wrapWithRouterContext` is shared with the server-side Pages Router render
44
+ * path, where a raw useLayoutEffect would log React's "useLayoutEffect does
45
+ * nothing on the server" warning on every render. Same pattern as
46
+ * `shims/image.tsx`; Next.js only runs the commit callback on the client.
47
+ */
48
+ const useNonWarningLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
49
+ var PagesRouterCommitBoundary = class extends Component {
50
+ componentDidCatch(error) {
51
+ this.props.onError(error);
52
+ }
53
+ render() {
54
+ return createElement(PagesRouterCommitBoundaryHelper, { onCommit: this.props.onCommit }, this.props.children);
55
+ }
56
+ };
57
+ function PagesRouterCommitBoundaryHelper({ children, onCommit }) {
58
+ useNonWarningLayoutEffect(() => {
59
+ onCommit();
60
+ }, [onCommit]);
61
+ return createElement(Fragment, null, children);
62
+ }
63
+ function renderPagesRouterElement(element, scroll) {
64
+ const root = window.__VINEXT_ROOT__;
65
+ if (!root) return Promise.resolve();
66
+ cancelPreviousRenderCommit();
67
+ return new Promise((resolve, reject) => {
68
+ const cancel = () => {
69
+ if (routerRuntimeState.cancelPendingRenderCommit === cancel) routerRuntimeState.cancelPendingRenderCommit = null;
70
+ reject(new NavigationCancelledError("superseded"));
71
+ };
72
+ routerRuntimeState.cancelPendingRenderCommit = cancel;
73
+ const clearIfCurrent = () => {
74
+ if (routerRuntimeState.cancelPendingRenderCommit === cancel) routerRuntimeState.cancelPendingRenderCommit = null;
75
+ };
76
+ const isCurrent = () => routerRuntimeState.cancelPendingRenderCommit === cancel;
77
+ const scrollHandler = async () => {
78
+ if (scroll) await restorePagesRouterScrollPosition(scroll, isCurrent);
79
+ };
80
+ root.render(wrapWithRouterContext(element, () => {
81
+ (async () => {
82
+ if (!isCurrent()) return;
83
+ try {
84
+ await scrollHandler();
85
+ if (!isCurrent()) return;
86
+ clearIfCurrent();
87
+ resolve();
88
+ } catch (err) {
89
+ clearIfCurrent();
90
+ reject(err);
91
+ }
92
+ })();
93
+ }, (error) => {
94
+ clearIfCurrent();
95
+ reject(error);
96
+ }));
97
+ if (!hasBrowserDocument()) {
98
+ clearIfCurrent();
99
+ resolve();
100
+ }
101
+ });
102
+ }
103
+ function hasBrowserDocument() {
104
+ return typeof document !== "undefined" && document.documentElement !== void 0;
105
+ }
106
+ async function restorePagesRouterScrollPosition(scroll, shouldContinue) {
107
+ if (!shouldContinue()) return;
108
+ scrollToPagesRouterPosition(scroll);
109
+ if (isAtScrollPosition(scroll)) return;
110
+ let previousScrollPosition = getWindowScrollPosition();
111
+ for (let frame = 0; frame < SCROLL_RESTORE_MAX_FRAMES; frame += 1) {
112
+ await waitForNextAnimationFrame();
113
+ if (!shouldContinue()) return;
114
+ scrollToPagesRouterPosition(scroll);
115
+ if (isAtScrollPosition(scroll)) return;
116
+ const currentScrollPosition = getWindowScrollPosition();
117
+ if (currentScrollPosition.x === previousScrollPosition.x && currentScrollPosition.y === previousScrollPosition.y) break;
118
+ previousScrollPosition = currentScrollPosition;
119
+ }
120
+ }
121
+ function scrollToPagesRouterPosition({ x, y }) {
122
+ if (!hasBrowserDocument()) {
123
+ window.scrollTo(x, y);
124
+ return;
125
+ }
126
+ const htmlElement = document.documentElement;
127
+ if (!(htmlElement.dataset.scrollBehavior === "smooth")) {
128
+ window.scrollTo(x, y);
129
+ return;
130
+ }
131
+ const previousScrollBehavior = htmlElement.style.scrollBehavior;
132
+ htmlElement.style.scrollBehavior = "auto";
133
+ htmlElement.getClientRects();
134
+ window.scrollTo(x, y);
135
+ htmlElement.style.scrollBehavior = previousScrollBehavior;
136
+ }
137
+ function isAtScrollPosition({ x, y }) {
138
+ return Math.abs(window.scrollX - x) <= SCROLL_RESTORE_TOLERANCE_PX && Math.abs(window.scrollY - y) <= SCROLL_RESTORE_TOLERANCE_PX;
139
+ }
140
+ function waitForNextAnimationFrame() {
141
+ return new Promise((resolve) => {
142
+ if (typeof requestAnimationFrame === "function") {
143
+ requestAnimationFrame(() => resolve());
144
+ return;
145
+ }
146
+ setTimeout(resolve, 16);
147
+ });
148
+ }
149
+ function canUseSessionStorageForScrollRestoration() {
150
+ if (typeof window === "undefined") return false;
151
+ try {
152
+ const key = "__next";
153
+ window.sessionStorage.setItem(key, key);
154
+ window.sessionStorage.removeItem(key);
155
+ return true;
156
+ } catch {
157
+ return false;
158
+ }
159
+ }
160
+ const manualScrollRestoration = __scrollRestoration && typeof window !== "undefined" && window.next?.appDir !== true && "scrollRestoration" in window.history && canUseSessionStorageForScrollRestoration();
161
+ function installManualScrollRestoration() {
162
+ if (manualScrollRestoration) window.history.scrollRestoration = "manual";
163
+ }
34
164
  function createRouterEvents() {
35
165
  const listeners = /* @__PURE__ */ new Map();
36
166
  return {
@@ -46,14 +176,58 @@ function createRouterEvents() {
46
176
  }
47
177
  };
48
178
  }
49
- const routerEvents = createRouterEvents();
179
+ const PAGES_ROUTER_RUNTIME_STATE_KEY = Symbol.for("vinext.pagesRouter.runtimeState");
180
+ function createPagesRouterRuntimeState() {
181
+ return {
182
+ events: createRouterEvents(),
183
+ historyKeyCounter: 0,
184
+ navigationId: 0,
185
+ activeAbortController: null,
186
+ cancelPendingRenderCommit: null,
187
+ lastPathnameAndSearch: typeof window !== "undefined" ? window.location.pathname + window.location.search : "",
188
+ isFirstPopStateEvent: true,
189
+ routerDidNavigate: false,
190
+ deprecatedEventBridgeInstalled: false,
191
+ pagesRouterReady: typeof window === "undefined" || !shouldDeferInitialPagesRouterReady()
192
+ };
193
+ }
194
+ function getPagesRouterRuntimeState() {
195
+ if (typeof window === "undefined") return createPagesRouterRuntimeState();
196
+ const globalObject = window;
197
+ const existing = globalObject[PAGES_ROUTER_RUNTIME_STATE_KEY];
198
+ if (existing) return existing;
199
+ const state = createPagesRouterRuntimeState();
200
+ globalObject[PAGES_ROUTER_RUNTIME_STATE_KEY] = state;
201
+ return state;
202
+ }
203
+ const routerRuntimeState = getPagesRouterRuntimeState();
204
+ const routerEvents = routerRuntimeState.events;
205
+ function getPagesRouterRuntimeComponents() {
206
+ const existing = routerRuntimeState.components;
207
+ if (existing) return existing;
208
+ const components = {
209
+ CommitBoundary: PagesRouterCommitBoundary,
210
+ Provider: PagesRouterProvider
211
+ };
212
+ routerRuntimeState.components = components;
213
+ return components;
214
+ }
50
215
  function resolveUrl(url) {
51
216
  if (typeof url === "string") return url;
52
- let result = url.pathname ?? "/";
53
- if (url.query) {
217
+ const hasQuery = url.query !== void 0 && Object.keys(url.query).length > 0;
218
+ const hasSearch = typeof url.search === "string" && url.search.length > 0;
219
+ const hasHash = typeof url.hash === "string" && url.hash.length > 0;
220
+ const inheritsVisiblePath = url.pathname === void 0 && (hasQuery || hasSearch || hasHash);
221
+ let result = url.pathname ?? (typeof window !== "undefined" ? inheritsVisiblePath ? stripBasePath(window.location.pathname, __basePath) : window.__NEXT_DATA__?.page ?? stripBasePath(window.location.pathname, __basePath) : "/");
222
+ if (hasSearch) {
223
+ const search = url.search.startsWith("?") ? url.search : `?${url.search}`;
224
+ const hashIndex = search.indexOf("#");
225
+ result += hashIndex === -1 ? search : `${search.slice(0, hashIndex)}%23${search.slice(hashIndex + 1)}`;
226
+ } else if (hasQuery) {
54
227
  const params = urlQueryToSearchParams(url.query);
55
228
  result = appendSearchParamsToUrl(result, params);
56
- }
229
+ } else if (hasHash && typeof window !== "undefined") result += window.location.search;
230
+ if (hasHash) result += url.hash.startsWith("#") ? url.hash : `#${url.hash}`;
57
231
  return result;
58
232
  }
59
233
  /**
@@ -65,8 +239,39 @@ function resolveUrl(url) {
65
239
  * Pages error routes are handled as a narrow exception below because Next.js
66
240
  * treats their href as the component route while preserving `as` in history.
67
241
  */
68
- function resolveNavigationTarget(url, as, locale) {
69
- return applyNavigationLocale(as ?? resolveUrl(url), locale);
242
+ function resolveNavigationTarget(url, as, locale, replaceExistingLocale = false) {
243
+ return applyNavigationLocale(as ?? resolveUrl(url), locale, replaceExistingLocale);
244
+ }
245
+ var HrefInterpolationError = class extends Error {};
246
+ function interpolateCurrentDynamicRoute(resolved) {
247
+ if (typeof window === "undefined") return resolved;
248
+ const routePattern = window.__NEXT_DATA__?.page;
249
+ if (!routePattern || extractRouteParamNames(routePattern).length === 0) return resolved;
250
+ try {
251
+ const target = new URL(resolved, "http://vinext.local");
252
+ const currentOrigin = getWindowOrigin();
253
+ if (currentOrigin && target.origin !== "http://vinext.local" && target.origin !== currentOrigin) return resolved;
254
+ const visiblePath = stripBasePath(window.location.pathname, __basePath);
255
+ const visibleLocale = getLocalePathPrefix(visiblePath, window.__VINEXT_LOCALES__);
256
+ if (extractRouteParamsFromPath(routePattern, visibleLocale ? visiblePath.slice(visibleLocale.length + 1) || "/" : visiblePath) === null) return resolved;
257
+ const query = parseQueryString(target.search);
258
+ const missingParams = routePatternParts(routePattern).filter((part) => part.startsWith(":") && !part.endsWith("*")).map((part) => part.slice(1, part.endsWith("+") ? -1 : void 0)).filter((paramName) => {
259
+ const value = query[paramName];
260
+ return value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
261
+ });
262
+ if (missingParams.length > 0) throw new HrefInterpolationError(`The provided \`href\` (${`${routePattern}${target.search}${target.hash}`}) value is missing query values (${missingParams.join(", ")}) to be interpolated properly. Read more: https://nextjs.org/docs/messages/href-interpolation-failed`);
263
+ const routeParams = getRouteParamsFromQuery(routePattern, query);
264
+ if (!routeParams) return resolved;
265
+ const pathname = fillRoutePatternSegments(routePattern, Object.fromEntries(Object.entries(routeParams).map(([key, value]) => [key, Array.isArray(value) ? value.map(encodeURIComponent) : encodeURIComponent(value)])));
266
+ if (!pathname) return resolved;
267
+ const targetLocale = getLocalePathPrefix(target.pathname, window.__VINEXT_LOCALES__);
268
+ target.pathname = targetLocale ? `/${targetLocale}${pathname}` : pathname;
269
+ for (const paramName of extractRouteParamNames(routePattern)) target.searchParams.delete(paramName);
270
+ return target.href.slice(target.origin.length);
271
+ } catch (error) {
272
+ if (error instanceof HrefInterpolationError) throw error;
273
+ return resolved;
274
+ }
70
275
  }
71
276
  function getCurrentUrlLocale() {
72
277
  return getCurrentBrowserLocale({
@@ -131,13 +336,26 @@ function getDomainLocalePath(url, locale) {
131
336
  * Apply locale prefix to a URL for client-side navigation.
132
337
  * Same logic as Link's applyLocaleToHref but reads from window globals.
133
338
  */
134
- function applyNavigationLocale(url, locale) {
339
+ function applyNavigationLocale(url, locale, replaceExistingLocale = false) {
135
340
  if (!locale || typeof window === "undefined") return url;
136
341
  if (isAbsoluteOrProtocolRelativeUrl(url)) return url;
137
- if (getLocalePathPrefix(url, window.__VINEXT_LOCALES__)) return url;
138
- const domainLocalePath = getDomainLocalePath(url, locale);
342
+ if (!replaceExistingLocale && getLocalePathPrefix(url, window.__VINEXT_LOCALES__)) return url;
343
+ const normalizedUrl = replaceExistingLocale ? removeNavigationLocalePrefix(url) : url;
344
+ const domainLocalePath = getDomainLocalePath(normalizedUrl, locale);
139
345
  if (domainLocalePath) return domainLocalePath;
140
- return addLocalePrefix(url, locale, window.__VINEXT_DEFAULT_LOCALE__ ?? "");
346
+ return addLocalePrefix(normalizedUrl, locale, window.__VINEXT_DEFAULT_LOCALE__ ?? "");
347
+ }
348
+ function removeNavigationLocalePrefix(url) {
349
+ const locales = window.__VINEXT_LOCALES__;
350
+ if (!locales?.length) return url;
351
+ try {
352
+ const parsed = new URL(url, "http://vinext.local");
353
+ const locale = getLocalePathPrefix(parsed.pathname, locales);
354
+ if (!locale) return url;
355
+ return `${parsed.pathname.slice(locale.length + 1) || "/"}${parsed.search}${parsed.hash}`;
356
+ } catch {
357
+ return url;
358
+ }
141
359
  }
142
360
  function isDefaultLocaleRootNavigation(url, locale) {
143
361
  if (typeof window === "undefined") return false;
@@ -201,8 +419,16 @@ function buildInitialRouterState() {
201
419
  * locale stamped before any push could overwrite the active locale global.
202
420
  */
203
421
  function stampInitialHistoryState() {
204
- if (window.history.state !== null && window.history.state !== void 0) return;
205
- window.history.replaceState(buildInitialRouterState(), "");
422
+ installManualScrollRestoration();
423
+ if (!window.history) return;
424
+ const existingState = window.history.state;
425
+ if (existingState !== null && existingState !== void 0) {
426
+ routerRuntimeState.currentHistoryKey = getRouterStateKey(existingState) ?? routerRuntimeState.currentHistoryKey;
427
+ return;
428
+ }
429
+ const initialState = buildInitialRouterState();
430
+ routerRuntimeState.currentHistoryKey = initialState.key;
431
+ window.history.replaceState(initialState, "");
206
432
  }
207
433
  setStampInitialHistoryState(stampInitialHistoryState);
208
434
  /** Save current scroll position into history state for back/forward restoration.
@@ -213,22 +439,62 @@ setStampInitialHistoryState(stampInitialHistoryState);
213
439
  * minting the same shape here so the entry isn't treated as foreign.
214
440
  */
215
441
  function saveScrollPosition() {
216
- const existing = typeof window.history.state === "object" && window.history.state !== null ? window.history.state : null;
442
+ const position = getWindowScrollPosition();
443
+ const existing = isUnknownRecord(window.history.state) ? window.history.state : null;
217
444
  const scroll = {
218
- __vinext_scrollX: window.scrollX,
219
- __vinext_scrollY: window.scrollY
445
+ __vinext_scrollX: position.x,
446
+ __vinext_scrollY: position.y
220
447
  };
221
448
  const base = existing ?? buildInitialRouterState();
449
+ const key = getRouterStateKey(base);
450
+ if (key !== void 0) {
451
+ routerRuntimeState.currentHistoryKey = key;
452
+ saveScrollPositionToSessionStorage(key, position);
453
+ }
222
454
  window.history.replaceState({
223
455
  ...base,
224
456
  ...scroll
225
457
  }, "");
226
458
  }
227
- /** Restore scroll position from history state */
228
- function restoreScrollPosition(state) {
229
- if (state && typeof state === "object" && "__vinext_scrollY" in state) {
230
- const { __vinext_scrollX: x, __vinext_scrollY: y } = state;
231
- requestAnimationFrame(() => window.scrollTo(x, y));
459
+ function getWindowScrollPosition() {
460
+ return {
461
+ x: window.scrollX,
462
+ y: window.scrollY
463
+ };
464
+ }
465
+ function getScrollStorageKey(historyKey) {
466
+ return `__next_scroll_${historyKey}`;
467
+ }
468
+ function readScrollPosition(value) {
469
+ if (!isUnknownRecord(value)) return null;
470
+ const nextX = value.x;
471
+ const nextY = value.y;
472
+ if (typeof nextX === "number" && typeof nextY === "number") return {
473
+ x: nextX,
474
+ y: nextY
475
+ };
476
+ const vinextX = value.__vinext_scrollX;
477
+ const vinextY = value.__vinext_scrollY;
478
+ if (typeof vinextX === "number" && typeof vinextY === "number") return {
479
+ x: vinextX,
480
+ y: vinextY
481
+ };
482
+ return null;
483
+ }
484
+ function saveScrollPositionToSessionStorage(key, position) {
485
+ if (!manualScrollRestoration) return;
486
+ try {
487
+ window.sessionStorage.setItem(getScrollStorageKey(key), JSON.stringify(position));
488
+ } catch {}
489
+ }
490
+ function readScrollPositionFromSessionStorage(key) {
491
+ if (!manualScrollRestoration) return null;
492
+ try {
493
+ const value = window.sessionStorage.getItem(getScrollStorageKey(key));
494
+ if (value === null) return null;
495
+ return readScrollPosition(JSON.parse(value));
496
+ } catch {
497
+ return null;
232
498
  }
233
499
  }
234
500
  let _ssrContext = null;
@@ -380,6 +646,11 @@ function getRouteParamsFromQuery(pattern, query) {
380
646
  function getRouteQueryFromNextData(nextData, resolvedPath) {
381
647
  const routeQuery = {};
382
648
  if (!nextData?.query || !nextData.page) return routeQuery;
649
+ if (extractRouteParamsFromPath(nextData.page, resolvedPath) === null) {
650
+ for (const [key, value] of Object.entries(nextData.query)) if (typeof value === "string") routeQuery[key] = value;
651
+ else if (Array.isArray(value)) routeQuery[key] = [...value];
652
+ return routeQuery;
653
+ }
383
654
  const routeParamNames = extractRouteParamNames(nextData.page);
384
655
  if (routeParamNames.length === 0) return routeQuery;
385
656
  const currentRouteParams = extractRouteParamsFromPath(nextData.page, resolvedPath);
@@ -422,9 +693,23 @@ function getPathnameAndQuery() {
422
693
  ...searchQuery,
423
694
  ...routeQuery
424
695
  },
425
- asPath: resolvedPath + window.location.search + window.location.hash
696
+ asPath: getCurrentHistoryAsPath() ?? resolvedPath + window.location.search + window.location.hash
426
697
  };
427
698
  }
699
+ function getCurrentHistoryAsPath() {
700
+ const state = window.history?.state;
701
+ if (!isNextRouterState(state) || typeof state.as !== "string") return null;
702
+ try {
703
+ const browserUrl = new URL(window.location.href);
704
+ const stateUrl = new URL(toBrowserNavigationHref(state.as, window.location.href, __basePath), window.location.href);
705
+ if (stateUrl.pathname !== browserUrl.pathname || stateUrl.search !== browserUrl.search) return null;
706
+ const stateAs = stripHash(state.as);
707
+ const visibleAs = `${stripBasePath(window.location.pathname, __basePath)}${window.location.search}`;
708
+ return `${stateAs || visibleAs}${window.location.hash}`;
709
+ } catch {
710
+ return null;
711
+ }
712
+ }
428
713
  function getPagesNavigationIsReadyFromSerializedState(routePattern, searchString, nextData) {
429
714
  if (!routePattern) return true;
430
715
  if (nextData?.gssp === true || nextData?.gip === true || nextData?.isExperimentalCompile === true || nextData?.appGip === true && nextData.gsp !== true) return true;
@@ -439,9 +724,8 @@ function shouldDeferInitialPagesRouterReady() {
439
724
  if (!nextData) return false;
440
725
  return !getPagesNavigationIsReadyFromSerializedState(nextData.page, window.location.search, nextData);
441
726
  }
442
- let _pagesRouterReady = typeof window === "undefined" ? true : !shouldDeferInitialPagesRouterReady();
443
727
  function isPagesRouterReady() {
444
- return _pagesRouterReady;
728
+ return routerRuntimeState.pagesRouterReady;
445
729
  }
446
730
  function isPagesRouterDocumentActive() {
447
731
  if (typeof window === "undefined") return true;
@@ -451,10 +735,28 @@ function isPagesRouterDocumentActive() {
451
735
  return Boolean(window.__VINEXT_APP__ || window.__VINEXT_APP_LOADER__);
452
736
  }
453
737
  function markPagesRouterReady() {
454
- if (typeof window === "undefined" || _pagesRouterReady) return false;
455
- _pagesRouterReady = true;
738
+ if (typeof window === "undefined" || routerRuntimeState.pagesRouterReady) return false;
739
+ routerRuntimeState.pagesRouterReady = true;
456
740
  return true;
457
741
  }
742
+ function initializePagesRouterReadyFromNextData(nextData) {
743
+ if (typeof window === "undefined") return;
744
+ routerRuntimeState.pagesRouterReady = getPagesNavigationIsReadyFromSerializedState(nextData.page, window.location.search, nextData);
745
+ }
746
+ function markPagesRouterHydrated() {
747
+ if (typeof window === "undefined" || window.__NEXT_HYDRATED === true) return;
748
+ const hydratedAt = performance.now();
749
+ window.__VINEXT_HYDRATED_AT = hydratedAt;
750
+ window.__NEXT_HYDRATED = true;
751
+ window.__NEXT_HYDRATED_AT = hydratedAt;
752
+ window.__NEXT_HYDRATED_CB?.();
753
+ }
754
+ function PagesRouterHydrationMarker() {
755
+ useEffect(() => {
756
+ markPagesRouterHydrated();
757
+ }, []);
758
+ return null;
759
+ }
458
760
  function getRouterSnapshot() {
459
761
  const isReady = typeof window === "undefined" ? _getSSRContext()?.navigationIsReady ?? true : isPagesRouterReady();
460
762
  return {
@@ -488,20 +790,10 @@ var HardNavigationScheduledError = class extends Error {
488
790
  this.name = "HardNavigationScheduledError";
489
791
  }
490
792
  };
491
- /**
492
- * Monotonically increasing ID for tracking the current navigation.
493
- * Each call to navigateClient() increments this and captures the value.
494
- * After each async boundary, the navigation checks whether it is still
495
- * the active one. If a newer navigation has started, the stale one
496
- * throws NavigationCancelledError so the caller can emit routeChangeError
497
- * and skip routeChangeComplete.
498
- *
499
- * Replaces the old boolean `_navInProgress` guard which silently dropped
500
- * the second navigation, causing URL/content mismatch.
501
- */
502
- let _navigationId = 0;
503
- /** AbortController for the in-flight fetch, so superseded navigations abort network I/O. */
504
- let _activeAbortController = null;
793
+ function cancelPreviousRenderCommit() {
794
+ routerRuntimeState.cancelPendingRenderCommit?.();
795
+ routerRuntimeState.cancelPendingRenderCommit = null;
796
+ }
505
797
  function scheduleHardNavigationAndThrow(url, message) {
506
798
  if (typeof window === "undefined") throw new HardNavigationScheduledError(message);
507
799
  window.location.href = url;
@@ -566,15 +858,23 @@ function getMiddlewarePagesDataFetchUrl(browserUrl) {
566
858
  if (parsed.origin !== getWindowOrigin()) return null;
567
859
  return buildPagesDataHref(__basePath, buildId, stripBasePath(parsed.pathname, __basePath), parsed.search);
568
860
  }
569
- async function resolveMiddlewareDataRedirect(browserUrl, signal) {
861
+ async function resolveMiddlewareDataEffect(browserUrl, signal) {
570
862
  const dataUrl = getMiddlewarePagesDataFetchUrl(browserUrl);
571
863
  if (!dataUrl) return null;
572
864
  if (signal.aborted) throw new DOMException("Aborted", "AbortError");
573
865
  try {
574
- return (await dedupedPagesDataFetch(dataUrl, { headers: {
575
- Accept: "application/json",
576
- "x-nextjs-data": "1"
577
- } })).headers.get("x-nextjs-redirect");
866
+ const res = await dedupedPagesDataFetch(dataUrl, {
867
+ headers: {
868
+ Accept: "application/json",
869
+ "x-nextjs-data": "1"
870
+ },
871
+ signal
872
+ });
873
+ return {
874
+ redirectLocation: res.headers.get("x-nextjs-redirect"),
875
+ rewriteTarget: res.headers.get("x-nextjs-rewrite"),
876
+ response: res
877
+ };
578
878
  } catch {
579
879
  return null;
580
880
  }
@@ -611,19 +911,24 @@ function handleDataRedirect(destination, redirectBasePath, mode = "push") {
611
911
  * data endpoint returns 404 and the client lands on the new build via a
612
912
  * full document load.
613
913
  */
614
- async function navigateClientData(url, target, controller, navId, assertStillCurrent, options = {}) {
615
- const root = window.__VINEXT_ROOT__;
616
- if (!root) {
914
+ async function navigateClientData(url, initialTarget, controller, navId, assertStillCurrent, options = {}, prefetchedResponse) {
915
+ if (!window.__VINEXT_ROOT__) {
617
916
  window.location.href = url;
618
917
  return;
619
918
  }
620
919
  if (controller.signal.aborted) throw new NavigationCancelledError(url);
621
- let res;
622
- try {
623
- res = await dedupedPagesDataFetch(target.dataHref, { headers: {
920
+ let res = prefetchedResponse;
921
+ if (!res) try {
922
+ const headers = {
624
923
  Accept: "application/json",
625
924
  "x-nextjs-data": "1"
626
- } });
925
+ };
926
+ const deploymentId = getDeploymentId();
927
+ if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
928
+ res = await dedupedPagesDataFetch(initialTarget.dataHref, {
929
+ headers,
930
+ signal: controller.signal
931
+ });
627
932
  } catch (err) {
628
933
  if (err instanceof DOMException && err.name === "AbortError") throw new NavigationCancelledError(url);
629
934
  throw err;
@@ -634,11 +939,14 @@ async function navigateClientData(url, target, controller, navId, assertStillCur
634
939
  const redirectedUrl = resolveLocalRedirectUrl(softRedirect);
635
940
  if (!redirectedUrl) scheduleHardNavigationAndThrow(softRedirect, "Navigation redirected externally");
636
941
  window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
637
- _lastPathnameAndSearch = window.location.pathname + window.location.search;
942
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
638
943
  await navigateClientHtml(redirectedUrl, redirectedUrl, controller, navId, assertStillCurrent);
639
944
  return;
640
945
  }
641
946
  if (!res.ok) scheduleHardNavigationAndThrow(url, `Data navigation failed: ${res.status} ${res.statusText}`);
947
+ const rewriteTarget = res.headers.get("x-nextjs-rewrite");
948
+ const target = rewriteTarget ? resolvePagesDataNavigationTarget(rewriteTarget, __basePath) : initialTarget;
949
+ if (!target) scheduleHardNavigationAndThrow(url, "Data navigation failed: rewrite target has no page loader");
642
950
  let body;
643
951
  try {
644
952
  body = await res.json();
@@ -646,7 +954,9 @@ async function navigateClientData(url, target, controller, navId, assertStillCur
646
954
  scheduleHardNavigationAndThrow(url, "Data navigation failed: invalid JSON response");
647
955
  }
648
956
  assertStillCurrent();
649
- const pageProps = body.pageProps && typeof body.pageProps === "object" ? body.pageProps : {};
957
+ const props = isUnknownRecord(body) ? body : {};
958
+ const rawPageProps = props.pageProps;
959
+ const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
650
960
  const redirectDestination = pageProps.__N_REDIRECT;
651
961
  if (typeof redirectDestination === "string") {
652
962
  handleDataRedirect(redirectDestination, pageProps.__N_REDIRECT_BASE_PATH, options.mode);
@@ -673,17 +983,18 @@ async function navigateClientData(url, target, controller, navId, assertStillCur
673
983
  assertStillCurrent();
674
984
  let element;
675
985
  if (AppComponent) element = React.createElement(AppComponent, {
986
+ ...props,
676
987
  Component: PageComponent,
677
- pageProps
988
+ pageProps: rawPageProps,
989
+ router: Router
678
990
  });
679
991
  else element = React.createElement(PageComponent, pageProps);
680
- element = wrapWithRouterContext(element);
681
992
  const mergedQuery = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
682
993
  const prev = window.__NEXT_DATA__;
683
994
  const nextLocale = (window.__VINEXT_LOCALES__?.length ?? 0) > 0 ? target.locale ?? window.__VINEXT_DEFAULT_LOCALE__ : prev?.locale;
684
995
  const nextData = {
685
996
  ...prev,
686
- props: { pageProps },
997
+ props,
687
998
  page: target.pattern,
688
999
  query: mergedQuery,
689
1000
  buildId: target.buildId,
@@ -692,7 +1003,8 @@ async function navigateClientData(url, target, controller, navId, assertStillCur
692
1003
  };
693
1004
  window.__NEXT_DATA__ = nextData;
694
1005
  applyVinextLocaleGlobals(window, nextData);
695
- root.render(element);
1006
+ await renderPagesRouterElement(element, options.scroll);
1007
+ assertStillCurrent();
696
1008
  }
697
1009
  /**
698
1010
  * Perform client-side navigation by fetching the page's full HTML and
@@ -707,8 +1019,7 @@ async function navigateClientData(url, target, controller, navId, assertStillCur
707
1019
  async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillCurrent, options = {}) {
708
1020
  let browserUrl = url;
709
1021
  let pendingRedirectHistoryUrl = fetchUrl === url ? null : url;
710
- const root = window.__VINEXT_ROOT__;
711
- if (!root) {
1022
+ if (!window.__VINEXT_ROOT__) {
712
1023
  window.location.href = browserUrl;
713
1024
  return;
714
1025
  }
@@ -736,7 +1047,9 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
736
1047
  const nextDataJson = extractVinextNextDataJson(html);
737
1048
  if (!nextDataJson) scheduleHardNavigationAndThrow(url, "Navigation failed: missing __NEXT_DATA__ in response");
738
1049
  const nextData = parseVinextNextDataJson(nextDataJson);
739
- const { pageProps } = nextData.props;
1050
+ const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
1051
+ const rawPageProps = props.pageProps;
1052
+ const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
740
1053
  let pageModuleUrl = nextData.__vinext?.pageModuleUrl;
741
1054
  if (!pageModuleUrl) {
742
1055
  const moduleMatch = html.match(/import\("([^"]+)"\);\s*\n\s*const PageComponent/);
@@ -744,11 +1057,10 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
744
1057
  pageModuleUrl = moduleMatch?.[1] ?? altMatch?.[1] ?? void 0;
745
1058
  }
746
1059
  let pageModule;
747
- if (!pageModuleUrl) {
748
- const loader = window.__VINEXT_PAGE_LOADERS__?.[nextData.page];
749
- if (!loader) scheduleHardNavigationAndThrow(browserUrl, "Navigation failed: no page module URL found");
750
- pageModule = await loader();
751
- } else {
1060
+ const loader = window.__VINEXT_PAGE_LOADERS__?.[nextData.page];
1061
+ if (loader) pageModule = await loader();
1062
+ else if (!pageModuleUrl) scheduleHardNavigationAndThrow(browserUrl, "Navigation failed: no page module URL found");
1063
+ else {
752
1064
  if (!isValidModulePath(pageModuleUrl)) {
753
1065
  console.error("[vinext] Blocked import of invalid page module path:", pageModuleUrl);
754
1066
  scheduleHardNavigationAndThrow(browserUrl, "Navigation failed: invalid page module path");
@@ -777,18 +1089,20 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
777
1089
  assertStillCurrent();
778
1090
  let element;
779
1091
  if (AppComponent) element = React.createElement(AppComponent, {
1092
+ ...props,
780
1093
  Component: PageComponent,
781
- pageProps
1094
+ pageProps: rawPageProps,
1095
+ router: Router
782
1096
  });
783
1097
  else element = React.createElement(PageComponent, pageProps);
784
- element = wrapWithRouterContext(element);
785
1098
  if (pendingRedirectHistoryUrl) {
786
1099
  window.history.replaceState(window.history.state ?? {}, "", pendingRedirectHistoryUrl);
787
- _lastPathnameAndSearch = window.location.pathname + window.location.search;
1100
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
788
1101
  }
789
1102
  window.__NEXT_DATA__ = nextData;
790
1103
  applyVinextLocaleGlobals(window, nextData);
791
- root.render(element);
1104
+ await renderPagesRouterElement(element, options.scroll);
1105
+ assertStillCurrent();
792
1106
  }
793
1107
  /**
794
1108
  * Perform client-side navigation. Prefers the JSON data endpoint when the
@@ -806,43 +1120,50 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
806
1120
  */
807
1121
  async function navigateClient(url, fetchUrl = url, options = {}) {
808
1122
  if (typeof window === "undefined") return;
809
- _activeAbortController?.abort();
1123
+ const previousAbortController = routerRuntimeState.activeAbortController;
1124
+ if (previousAbortController) queueMicrotask(() => previousAbortController.abort());
1125
+ cancelPreviousRenderCommit();
810
1126
  const controller = new AbortController();
811
- _activeAbortController = controller;
812
- const navId = ++_navigationId;
1127
+ routerRuntimeState.activeAbortController = controller;
1128
+ const navId = ++routerRuntimeState.navigationId;
813
1129
  /** Check if this navigation is still the active one. If not, throw. */
814
1130
  function assertStillCurrent() {
815
- if (navId !== _navigationId) throw new NavigationCancelledError(url);
1131
+ if (navId !== routerRuntimeState.navigationId) throw new NavigationCancelledError(url);
816
1132
  }
817
1133
  try {
818
1134
  if (options.allowNotFoundResponse === true) await navigateClientHtml(url, fetchUrl, controller, navId, assertStillCurrent, options);
819
1135
  else {
820
1136
  let browserUrl = url;
821
1137
  let htmlFetchUrl = fetchUrl;
822
- const dataTarget = resolvePagesDataNavigationTarget(browserUrl, __basePath);
1138
+ let dataTarget = resolvePagesDataNavigationTarget(browserUrl, __basePath);
1139
+ let middlewareDataResponse;
823
1140
  if (!dataTarget) {
824
- let redirectLocation;
1141
+ let middlewareEffect;
825
1142
  try {
826
- redirectLocation = await resolveMiddlewareDataRedirect(browserUrl, controller.signal);
1143
+ middlewareEffect = await resolveMiddlewareDataEffect(browserUrl, controller.signal);
827
1144
  } catch (err) {
828
1145
  if (err instanceof DOMException && err.name === "AbortError") throw new NavigationCancelledError(browserUrl);
829
1146
  throw err;
830
1147
  }
831
1148
  assertStillCurrent();
1149
+ const redirectLocation = middlewareEffect?.redirectLocation ?? null;
832
1150
  if (redirectLocation) {
833
1151
  const redirectedUrl = resolveLocalRedirectUrl(redirectLocation);
834
1152
  if (!redirectedUrl) scheduleHardNavigationAndThrow(redirectLocation, "Navigation redirected externally");
835
1153
  window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
836
- _lastPathnameAndSearch = window.location.pathname + window.location.search;
1154
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
837
1155
  browserUrl = redirectedUrl;
838
1156
  htmlFetchUrl = redirectedUrl;
1157
+ } else if (middlewareEffect?.rewriteTarget) {
1158
+ dataTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
1159
+ if (dataTarget) middlewareDataResponse = middlewareEffect.response;
839
1160
  }
840
1161
  }
841
- if (dataTarget) await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options);
1162
+ if (dataTarget) await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options, middlewareDataResponse);
842
1163
  else await navigateClientHtml(browserUrl, htmlFetchUrl, controller, navId, assertStillCurrent, options);
843
1164
  }
844
1165
  } finally {
845
- if (navId === _navigationId) _activeAbortController = null;
1166
+ if (navId === routerRuntimeState.navigationId) routerRuntimeState.activeAbortController = null;
846
1167
  }
847
1168
  }
848
1169
  /**
@@ -928,8 +1249,8 @@ function dispatchNavigateEvent() {
928
1249
  * locale and the canonical app-relative `as` path.
929
1250
  */
930
1251
  function updateHistory(mode, fullUrl, navState) {
931
- const previousState = typeof window.history.state === "object" && window.history.state !== null ? window.history.state : null;
932
- const key = mode === "push" ? createHistoryKey() : previousState?.key ?? createHistoryKey();
1252
+ const previousKey = getRouterStateKey(window.history.state);
1253
+ const key = mode === "push" ? createHistoryKey() : previousKey ?? routerRuntimeState.currentHistoryKey ?? createHistoryKey();
933
1254
  const state = {
934
1255
  url: navState?.url ?? fullUrl,
935
1256
  as: navState?.as ?? fullUrl,
@@ -939,13 +1260,13 @@ function updateHistory(mode, fullUrl, navState) {
939
1260
  };
940
1261
  if (mode === "push") window.history.pushState(state, "", fullUrl);
941
1262
  else window.history.replaceState(state, "", fullUrl);
942
- _lastPathnameAndSearch = window.location.pathname + window.location.search;
943
- _routerDidNavigate = true;
1263
+ routerRuntimeState.currentHistoryKey = key;
1264
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1265
+ routerRuntimeState.routerDidNavigate = true;
944
1266
  }
945
- let _historyKeyCounter = 0;
946
1267
  function createHistoryKey() {
947
- _historyKeyCounter += 1;
948
- return `vinext_${_historyKeyCounter.toString(36)}_${Math.random().toString(36).slice(2, 9)}`;
1268
+ routerRuntimeState.historyKeyCounter += 1;
1269
+ return `vinext_${routerRuntimeState.historyKeyCounter.toString(36)}_${Math.random().toString(36).slice(2, 9)}`;
949
1270
  }
950
1271
  /**
951
1272
  * Throw the canonical "no router instance" error used when a Pages Router
@@ -979,7 +1300,8 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
979
1300
  assertSafeNavigationUrl(resolveUrl(url));
980
1301
  if (as !== void 0) assertSafeNavigationUrl(String(as));
981
1302
  const navigationLocale = resolveTransitionLocale(options?.locale);
982
- let resolved = resolveNavigationTarget(url, as, navigationLocale);
1303
+ let resolved = resolveNavigationTarget(url, as, navigationLocale, as === void 0 && options?.locale !== void 0 && typeof url !== "string" && url.pathname === void 0 && (url.query !== void 0 && Object.keys(url.query).length > 0 || typeof url.search === "string" && url.search.length > 0 || typeof url.hash === "string" && url.hash.length > 0));
1304
+ if (as === void 0 && (typeof url === "string" && options?._vinextInterpolateDynamicRoute === true || typeof url !== "string" && url.pathname === void 0 && (url.query !== void 0 && Object.keys(url.query).length > 0 || typeof url.search === "string" && url.search.length > 0))) resolved = interpolateCurrentDynamicRoute(resolved);
983
1305
  if (isExternalUrl(resolved)) {
984
1306
  const localPath = toSameOriginAppPath(resolved, __basePath);
985
1307
  if (localPath == null) {
@@ -993,12 +1315,21 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
993
1315
  const full = normalizePathTrailingSlash(toBrowserNavigationHref(resolved, window.location.href, __basePath), __trailingSlash);
994
1316
  const errorRouteHtmlFetchUrl = resolvePagesErrorHtmlFetchUrl(url, navigationLocale);
995
1317
  const htmlFetchUrl = errorRouteHtmlFetchUrl ?? getPagesHtmlFetchUrl(full, navigationLocale);
996
- const navigateOptions = errorRouteHtmlFetchUrl ? {
997
- allowNotFoundResponse: true,
998
- mode
999
- } : { mode };
1000
1318
  const shallow = options?.shallow ?? false;
1001
1319
  const doScroll = options?.scroll !== false;
1320
+ const hash = extractHash(resolved);
1321
+ const scrollTarget = doScroll ? {
1322
+ x: 0,
1323
+ y: 0
1324
+ } : null;
1325
+ const navigateOptions = errorRouteHtmlFetchUrl ? {
1326
+ allowNotFoundResponse: true,
1327
+ mode,
1328
+ scroll: scrollTarget
1329
+ } : {
1330
+ mode,
1331
+ scroll: scrollTarget
1332
+ };
1002
1333
  const navStateOptions = { shallow };
1003
1334
  if (navigationLocale !== void 0) navStateOptions.locale = navigationLocale;
1004
1335
  const resolvedNoHash = stripHash(resolved);
@@ -1007,7 +1338,8 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1007
1338
  as: resolvedNoHash,
1008
1339
  options: navStateOptions
1009
1340
  };
1010
- if (isHashOnlyChange(full)) {
1341
+ if (options?._h !== 1 && isHashOnlyChange(full)) {
1342
+ if (mode === "push") saveScrollPosition();
1011
1343
  const eventUrl = resolveHashUrl(full);
1012
1344
  routerEvents.emit("hashChangeStart", eventUrl, { shallow });
1013
1345
  updateHistory(mode, resolved.startsWith("#") ? resolved : full, navState);
@@ -1020,25 +1352,25 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1020
1352
  const appPath = getLocalPathname(resolved);
1021
1353
  const appPathNorm = appPath !== null ? removeTrailingSlash(appPath) : null;
1022
1354
  const appPathEntry = appPathNorm !== null ? getPagesRouterComponentsMap()[appPathNorm] : void 0;
1023
- if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter) {
1355
+ if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter || ["app", "document"].includes(resolveHybridClientRouteOwner(resolved, __basePath) ?? "")) {
1024
1356
  if (mode === "push") window.location.assign(full);
1025
1357
  else window.location.replace(full);
1026
1358
  return new Promise(() => {});
1027
1359
  }
1028
1360
  if (mode === "push") saveScrollPosition();
1029
- routerEvents.emit("routeChangeStart", resolved, { shallow });
1361
+ const isQueryUpdating = options?._h === 1;
1362
+ if (!isQueryUpdating) routerEvents.emit("routeChangeStart", resolved, { shallow });
1030
1363
  routerEvents.emit("beforeHistoryChange", resolved, { shallow });
1031
1364
  updateHistory(mode, full, navState);
1032
1365
  if (!shallow) {
1033
1366
  const result = await runNavigateClient(full, resolved, htmlFetchUrl, navigateOptions);
1034
1367
  if (result === "cancelled") return true;
1035
1368
  if (result === "failed") return false;
1036
- }
1037
- onStateUpdate?.();
1038
- routerEvents.emit("routeChangeComplete", resolved, { shallow });
1039
- const hash = extractHash(resolved);
1040
- if (doScroll) if (hash) scrollToHashTarget(hash);
1369
+ } else if (doScroll) if (hash) scrollToHashTarget(hash);
1041
1370
  else window.scrollTo(0, 0);
1371
+ onStateUpdate?.();
1372
+ if (!isQueryUpdating) routerEvents.emit("routeChangeComplete", resolved, { shallow });
1373
+ if (doScroll && hash && !shallow) scrollToHashTarget(hash);
1042
1374
  dispatchNavigateEvent();
1043
1375
  return true;
1044
1376
  }
@@ -1083,8 +1415,9 @@ async function prefetchUrl(url) {
1083
1415
  */
1084
1416
  function useRouter() {
1085
1417
  const router = useContext(RouterContext);
1086
- if (!router) throw new Error("NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted");
1087
- return router;
1418
+ if (router) return router;
1419
+ if (typeof window !== "undefined" && window.__VINEXT_PAGE_LOADERS__ !== void 0) return Router;
1420
+ throw new Error("NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted");
1088
1421
  }
1089
1422
  function PagesRouterProvider({ children }) {
1090
1423
  const [{ pathname, query, asPath, isReady }, setState] = useState(getRouterSnapshot);
@@ -1095,9 +1428,11 @@ function PagesRouterProvider({ children }) {
1095
1428
  window.addEventListener("vinext:navigate", onNavigate);
1096
1429
  let cancelled = false;
1097
1430
  const readyTimer = window.setTimeout(() => {
1098
- if (cancelled || !markPagesRouterReady()) return;
1099
- setState(getRouterSnapshot());
1100
- notifyNextNavigationPagesContext();
1431
+ if (cancelled) return;
1432
+ if (markPagesRouterReady()) {
1433
+ setState(getRouterSnapshot());
1434
+ notifyNextNavigationPagesContext();
1435
+ }
1101
1436
  }, 0);
1102
1437
  return () => {
1103
1438
  cancelled = true;
@@ -1140,36 +1475,47 @@ function PagesRouterProvider({ children }) {
1140
1475
  Router.prefetch(href);
1141
1476
  }
1142
1477
  }), []);
1143
- const content = createElement(RouterContext.Provider, { value: router }, children);
1478
+ const content = createElement(RouterContext.Provider, { value: router }, createElement(Fragment, null, children, createElement(PagesRouterHydrationMarker)));
1144
1479
  return AppRouterContext ? createElement(AppRouterContext.Provider, { value: appRouter }, content) : content;
1145
1480
  }
1146
- let _beforePopStateCb;
1147
- let _lastPathnameAndSearch = typeof window !== "undefined" ? window.location.pathname + window.location.search : "";
1148
- let _isFirstPopStateEvent = true;
1149
- let _routerDidNavigate = false;
1150
1481
  function isNextRouterState(state) {
1151
1482
  return typeof state === "object" && state !== null && "__N" in state && state.__N === true;
1152
1483
  }
1484
+ function getRouterStateKey(state) {
1485
+ if (!isNextRouterState(state)) return void 0;
1486
+ return typeof state.key === "string" ? state.key : void 0;
1487
+ }
1153
1488
  function handlePagesRouterPopState(e) {
1154
1489
  const browserUrl = window.location.pathname + window.location.search;
1155
1490
  const appUrl = stripBasePath(window.location.pathname, __basePath) + window.location.search;
1156
1491
  const state = e.state;
1157
- const wasFirst = _isFirstPopStateEvent;
1158
- _isFirstPopStateEvent = false;
1492
+ const wasFirst = routerRuntimeState.isFirstPopStateEvent;
1493
+ routerRuntimeState.isFirstPopStateEvent = false;
1159
1494
  if (state !== null && state !== void 0 && !isNextRouterState(state)) return;
1160
- if (wasFirst && !_routerDidNavigate && isNextRouterState(state)) {
1495
+ if (wasFirst && !routerRuntimeState.routerDidNavigate && isNextRouterState(state)) {
1161
1496
  const currentLocale = window.__VINEXT_LOCALE__;
1162
- if (state.options?.locale === currentLocale && typeof state.as === "string" && withBasePath(state.as, __basePath) === _lastPathnameAndSearch) return;
1497
+ if (state.options?.locale === currentLocale && typeof state.as === "string" && withBasePath(state.as, __basePath) === routerRuntimeState.lastPathnameAndSearch) return;
1498
+ }
1499
+ const isHashOnly = browserUrl === routerRuntimeState.lastPathnameAndSearch;
1500
+ const targetKey = getRouterStateKey(state);
1501
+ let forcedScroll;
1502
+ if (manualScrollRestoration) {
1503
+ const currentKey = routerRuntimeState.currentHistoryKey;
1504
+ if (currentKey !== void 0 && currentKey !== targetKey) saveScrollPositionToSessionStorage(currentKey, getWindowScrollPosition());
1505
+ if (targetKey !== void 0 && currentKey !== targetKey) forcedScroll = readScrollPositionFromSessionStorage(targetKey) ?? {
1506
+ x: 0,
1507
+ y: 0
1508
+ };
1163
1509
  }
1164
- const isHashOnly = browserUrl === _lastPathnameAndSearch;
1165
- if (_beforePopStateCb !== void 0) {
1166
- if (!_beforePopStateCb({
1510
+ if (routerRuntimeState.beforePopStateCb !== void 0) {
1511
+ if (!routerRuntimeState.beforePopStateCb({
1167
1512
  url: appUrl,
1168
1513
  as: appUrl,
1169
1514
  options: { shallow: false }
1170
1515
  })) return;
1171
1516
  }
1172
- _lastPathnameAndSearch = browserUrl;
1517
+ if (targetKey !== void 0) routerRuntimeState.currentHistoryKey = targetKey;
1518
+ routerRuntimeState.lastPathnameAndSearch = browserUrl;
1173
1519
  if (isHashOnly) {
1174
1520
  const hashUrl = appUrl + window.location.hash;
1175
1521
  routerEvents.emit("hashChangeStart", hashUrl, { shallow: false });
@@ -1183,9 +1529,12 @@ function handlePagesRouterPopState(e) {
1183
1529
  routerEvents.emit("routeChangeStart", fullAppUrl, { shallow: false });
1184
1530
  routerEvents.emit("beforeHistoryChange", fullAppUrl, { shallow: false });
1185
1531
  (async () => {
1186
- if (await runNavigateClient(browserUrl, fullAppUrl, getPagesHtmlFetchUrl(browserUrl, effectiveLocale)) === "completed") {
1532
+ const scrollTarget = manualScrollRestoration ? forcedScroll ?? readScrollPosition(state) ?? {
1533
+ x: 0,
1534
+ y: 0
1535
+ } : readScrollPosition(state);
1536
+ if (await runNavigateClient(browserUrl, fullAppUrl, getPagesHtmlFetchUrl(browserUrl, effectiveLocale), { scroll: scrollTarget }) === "completed") {
1187
1537
  routerEvents.emit("routeChangeComplete", fullAppUrl, { shallow: false });
1188
- restoreScrollPosition(e.state);
1189
1538
  dispatchNavigateEvent();
1190
1539
  }
1191
1540
  })();
@@ -1198,9 +1547,22 @@ setPagesRouterPopStateHandler(handlePagesRouterPopState);
1198
1547
  * The provider owns the reactive Pages Router snapshot so next/router and
1199
1548
  * next/compat/router consumers share one context value instead of each hook
1200
1549
  * installing its own global URL-change listener.
1550
+ *
1551
+ * The PagesRouterCommitBoundary exists for client navigations: its layout
1552
+ * callback runs scroll restoration at commit time and resolves the navigation
1553
+ * at the same root-commit boundary Next.js awaits before routeChangeComplete.
1554
+ * Its onError rejection drives the hard-navigation fallback in runNavigateClient.
1555
+ * The same boundary intentionally also wraps SSR and initial hydration, where
1556
+ * callbacks default to noopCommit: a hydration-time render error is caught
1557
+ * here (React still console.error's it) instead of propagating, matching the
1558
+ * navigation-path containment.
1201
1559
  */
1202
- function wrapWithRouterContext(element) {
1203
- return createElement(PagesRouterProvider, null, element);
1560
+ function wrapWithRouterContext(element, onCommit = noopCommit, onError = noopCommit) {
1561
+ const { CommitBoundary, Provider } = getPagesRouterRuntimeComponents();
1562
+ return createElement(CommitBoundary, {
1563
+ onCommit,
1564
+ onError
1565
+ }, createElement(Provider, null, element));
1204
1566
  }
1205
1567
  /**
1206
1568
  * Higher-order component that injects the Pages Router `router` instance as
@@ -1263,7 +1625,7 @@ const RouterMethods = {
1263
1625
  },
1264
1626
  beforePopState: (cb) => {
1265
1627
  if (typeof window === "undefined") throwNoRouterInstance();
1266
- _beforePopStateCb = cb;
1628
+ routerRuntimeState.beforePopStateCb = cb;
1267
1629
  },
1268
1630
  events: routerEvents
1269
1631
  };
@@ -1330,7 +1692,7 @@ const Router = Object.defineProperties(RouterMethods, {
1330
1692
  isReady: {
1331
1693
  enumerable: true,
1332
1694
  get() {
1333
- return isPagesRouterReady();
1695
+ return isPagesRouterReady() && (typeof window === "undefined" || window.__NEXT_HYDRATED === true);
1334
1696
  }
1335
1697
  },
1336
1698
  isPreview: {
@@ -1346,27 +1708,35 @@ const Router = Object.defineProperties(RouterMethods, {
1346
1708
  }
1347
1709
  }
1348
1710
  });
1349
- for (const event of [
1711
+ routerRuntimeState.publicRouter = Router;
1712
+ const deprecatedRouterEvents = [
1350
1713
  "routeChangeStart",
1351
1714
  "beforeHistoryChange",
1352
1715
  "routeChangeComplete",
1353
1716
  "routeChangeError",
1354
1717
  "hashChangeStart",
1355
1718
  "hashChangeComplete"
1356
- ]) {
1357
- const eventField = `on${event.charAt(0).toUpperCase()}${event.substring(1)}`;
1358
- routerEvents.on(event, (...args) => {
1359
- const handler = Router[eventField];
1360
- if (typeof handler === "function") try {
1361
- handler(...args);
1362
- } catch (err) {
1363
- console.error(`Error when running the Router event: ${eventField}`);
1364
- console.error(err instanceof Error ? `${err.message}\n${err.stack}` : String(err));
1365
- }
1366
- });
1719
+ ];
1720
+ if (!routerRuntimeState.deprecatedEventBridgeInstalled) {
1721
+ routerRuntimeState.deprecatedEventBridgeInstalled = true;
1722
+ for (const event of deprecatedRouterEvents) {
1723
+ const eventField = `on${event.charAt(0).toUpperCase()}${event.substring(1)}`;
1724
+ routerEvents.on(event, (...args) => {
1725
+ const handler = (routerRuntimeState.publicRouter ?? Router)[eventField];
1726
+ if (typeof handler === "function") try {
1727
+ handler(...args);
1728
+ } catch (err) {
1729
+ console.error(`Error when running the Router event: ${eventField}`);
1730
+ console.error(err instanceof Error ? `${err.message}\n${err.stack}` : String(err));
1731
+ }
1732
+ });
1733
+ }
1734
+ }
1735
+ if (typeof window !== "undefined") {
1736
+ installPagesRouterRuntime();
1737
+ installWindowNext({ router: Router });
1367
1738
  }
1368
- if (typeof window !== "undefined") installWindowNext({ router: Router });
1369
1739
  const _PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
1370
1740
  globalThis[_PAGES_NAVIGATION_ACCESSOR_KEY] = getPagesNavigationContext;
1371
1741
  //#endregion
1372
- export { _registerRouterStateAccessors, applyNavigationLocale, Router as default, getPagesNavigationContext, getPagesNavigationIsReadyFromSerializedState, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
1742
+ export { initializePagesRouterReadyFromNextData as _initializePagesRouterReadyFromNextData, markPagesRouterReady as _markPagesRouterReady, _registerRouterStateAccessors, applyNavigationLocale, Router as default, getPagesNavigationContext, getPagesNavigationIsReadyFromSerializedState, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };