vinext 0.1.7 → 0.2.0

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 (279) hide show
  1. package/README.md +51 -30
  2. package/dist/build/inject-pregenerated-paths.d.ts +4 -0
  3. package/dist/build/inject-pregenerated-paths.js +18 -0
  4. package/dist/build/layout-classification.js +1 -1
  5. package/dist/build/nitro-route-rules.js +1 -1
  6. package/dist/build/pages-client-assets-module.d.ts +11 -0
  7. package/dist/build/pages-client-assets-module.js +27 -0
  8. package/dist/build/prerender.d.ts +2 -1
  9. package/dist/build/prerender.js +13 -6
  10. package/dist/build/report.d.ts +13 -2
  11. package/dist/build/report.js +99 -2
  12. package/dist/build/run-prerender.d.ts +7 -0
  13. package/dist/build/run-prerender.js +10 -1
  14. package/dist/build/standalone.js +2 -0
  15. package/dist/cache/cache-adapters-virtual.js +3 -3
  16. package/dist/check.d.ts +18 -0
  17. package/dist/check.js +77 -19
  18. package/dist/cli-args.d.ts +1 -2
  19. package/dist/cli-args.js +1 -1
  20. package/dist/cli-dev-config.d.ts +12 -0
  21. package/dist/cli-dev-config.js +23 -0
  22. package/dist/cli.js +113 -97
  23. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  24. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  25. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  26. package/dist/{server → client}/dev-error-overlay.js +2 -2
  27. package/dist/client/navigation-runtime.d.ts +2 -0
  28. package/dist/client/navigation-runtime.js +3 -1
  29. package/dist/client/window-next.d.ts +2 -1
  30. package/dist/cloudflare/index.d.ts +2 -2
  31. package/dist/cloudflare/index.js +2 -2
  32. package/dist/config/config-matchers.js +14 -10
  33. package/dist/config/next-config.d.ts +6 -3
  34. package/dist/config/next-config.js +47 -1
  35. package/dist/config/prerender.d.ts +34 -0
  36. package/dist/config/prerender.js +55 -0
  37. package/dist/config/server-external-packages.d.ts +4 -0
  38. package/dist/config/server-external-packages.js +91 -0
  39. package/dist/entries/app-rsc-entry.d.ts +2 -1
  40. package/dist/entries/app-rsc-entry.js +89 -15
  41. package/dist/entries/app-rsc-manifest.js +10 -0
  42. package/dist/entries/pages-client-entry.d.ts +3 -0
  43. package/dist/entries/pages-client-entry.js +16 -1
  44. package/dist/entries/pages-server-entry.js +6 -2
  45. package/dist/image/image-adapters-virtual.d.ts +59 -0
  46. package/dist/image/image-adapters-virtual.js +59 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.js +211 -118
  49. package/dist/init-cloudflare.d.ts +43 -0
  50. package/dist/init-cloudflare.js +839 -0
  51. package/dist/init-platform.d.ts +40 -0
  52. package/dist/init-platform.js +195 -0
  53. package/dist/init.d.ts +16 -38
  54. package/dist/init.js +208 -97
  55. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  56. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  57. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  58. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  59. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  60. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  61. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  62. package/dist/packages/cloudflare/src/deploy.js +276 -0
  63. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  64. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
  65. package/dist/plugins/ast-scope.d.ts +16 -0
  66. package/dist/plugins/ast-scope.js +62 -0
  67. package/dist/plugins/ast-utils.d.ts +27 -1
  68. package/dist/plugins/ast-utils.js +32 -1
  69. package/dist/plugins/css-module-imports.d.ts +14 -0
  70. package/dist/plugins/css-module-imports.js +59 -0
  71. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  72. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  73. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  74. package/dist/plugins/middleware-server-only.d.ts +8 -6
  75. package/dist/plugins/middleware-server-only.js +8 -7
  76. package/dist/plugins/optimize-imports.js +1 -1
  77. package/dist/plugins/typeof-window.d.ts +1 -1
  78. package/dist/plugins/typeof-window.js +28 -56
  79. package/dist/routing/app-route-graph.d.ts +29 -4
  80. package/dist/routing/app-route-graph.js +182 -40
  81. package/dist/routing/app-router.d.ts +5 -0
  82. package/dist/routing/app-router.js +5 -0
  83. package/dist/routing/file-matcher.d.ts +8 -0
  84. package/dist/routing/file-matcher.js +10 -1
  85. package/dist/routing/pages-router.js +2 -2
  86. package/dist/server/api-handler.js +9 -14
  87. package/dist/server/app-browser-action-result.d.ts +4 -1
  88. package/dist/server/app-browser-action-result.js +8 -1
  89. package/dist/server/app-browser-entry.js +194 -190
  90. package/dist/server/app-browser-history-controller.d.ts +2 -1
  91. package/dist/server/app-browser-history-controller.js +6 -2
  92. package/dist/server/app-browser-interception-context.d.ts +1 -0
  93. package/dist/server/app-browser-interception-context.js +4 -2
  94. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  95. package/dist/server/app-browser-navigation-controller.js +60 -31
  96. package/dist/server/app-browser-server-action-client.d.ts +32 -0
  97. package/dist/server/app-browser-server-action-client.js +127 -0
  98. package/dist/server/app-browser-state.d.ts +11 -1
  99. package/dist/server/app-browser-state.js +25 -8
  100. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  101. package/dist/server/app-browser-visible-commit.js +43 -25
  102. package/dist/server/app-elements-wire.d.ts +9 -2
  103. package/dist/server/app-elements-wire.js +8 -1
  104. package/dist/server/app-elements.d.ts +2 -2
  105. package/dist/server/app-elements.js +4 -3
  106. package/dist/server/app-fallback-renderer.d.ts +5 -2
  107. package/dist/server/app-fallback-renderer.js +15 -7
  108. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  109. package/dist/server/app-hydration-cache-publication.js +43 -0
  110. package/dist/server/app-middleware.d.ts +4 -3
  111. package/dist/server/app-middleware.js +8 -3
  112. package/dist/server/app-optimistic-routing.js +11 -4
  113. package/dist/server/app-page-boundary-render.d.ts +3 -0
  114. package/dist/server/app-page-boundary-render.js +14 -3
  115. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  116. package/dist/server/app-page-cache-finalizer.js +10 -3
  117. package/dist/server/app-page-cache-render.d.ts +1 -0
  118. package/dist/server/app-page-cache-render.js +8 -4
  119. package/dist/server/app-page-cache.d.ts +1 -0
  120. package/dist/server/app-page-cache.js +5 -2
  121. package/dist/server/app-page-dispatch.d.ts +33 -4
  122. package/dist/server/app-page-dispatch.js +63 -90
  123. package/dist/server/app-page-element-builder.d.ts +9 -2
  124. package/dist/server/app-page-element-builder.js +114 -23
  125. package/dist/server/app-page-head.d.ts +16 -1
  126. package/dist/server/app-page-head.js +44 -22
  127. package/dist/server/app-page-params.d.ts +2 -1
  128. package/dist/server/app-page-params.js +8 -1
  129. package/dist/server/app-page-ppr-runtime.d.ts +7 -0
  130. package/dist/server/app-page-ppr-runtime.js +70 -0
  131. package/dist/server/app-page-probe.d.ts +1 -0
  132. package/dist/server/app-page-probe.js +6 -1
  133. package/dist/server/app-page-render-identity.d.ts +1 -0
  134. package/dist/server/app-page-render-identity.js +1 -1
  135. package/dist/server/app-page-render.d.ts +4 -1
  136. package/dist/server/app-page-render.js +26 -3
  137. package/dist/server/app-page-request.d.ts +22 -1
  138. package/dist/server/app-page-request.js +92 -15
  139. package/dist/server/app-page-route-wiring.d.ts +14 -2
  140. package/dist/server/app-page-route-wiring.js +61 -25
  141. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  142. package/dist/server/app-page-search-params-observation.js +11 -7
  143. package/dist/server/app-page-segment-state.d.ts +2 -1
  144. package/dist/server/app-page-segment-state.js +3 -1
  145. package/dist/server/app-page-stream.d.ts +5 -0
  146. package/dist/server/app-page-stream.js +3 -1
  147. package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
  148. package/dist/server/app-route-handler-dispatch.js +1 -0
  149. package/dist/server/app-route-handler-execution.js +7 -2
  150. package/dist/server/app-route-handler-response.js +1 -0
  151. package/dist/server/app-route-handler-runtime.js +1 -1
  152. package/dist/server/app-route-module-loader.d.ts +2 -0
  153. package/dist/server/app-route-module-loader.js +1 -0
  154. package/dist/server/app-router-entry.js +16 -8
  155. package/dist/server/app-rsc-errors.js +7 -1
  156. package/dist/server/app-rsc-handler.d.ts +3 -1
  157. package/dist/server/app-rsc-handler.js +67 -39
  158. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  159. package/dist/server/app-rsc-request-normalization.js +6 -3
  160. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  161. package/dist/server/app-rsc-route-matching.js +36 -3
  162. package/dist/server/app-segment-config.d.ts +12 -0
  163. package/dist/server/app-segment-config.js +91 -5
  164. package/dist/server/app-server-action-execution.d.ts +5 -0
  165. package/dist/server/app-server-action-execution.js +94 -33
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +19 -8
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-static-generation.d.ts +1 -0
  171. package/dist/server/app-static-generation.js +1 -0
  172. package/dist/server/app-visited-response-cache.d.ts +6 -0
  173. package/dist/server/app-visited-response-cache.js +3 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.js +19 -18
  179. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  180. package/dist/server/dev-stack-sourcemap.js +1 -1
  181. package/dist/server/fetch-handler.d.ts +2 -0
  182. package/dist/server/fetch-handler.js +18 -0
  183. package/dist/server/headers.d.ts +5 -15
  184. package/dist/server/headers.js +4 -15
  185. package/dist/server/image-optimization.d.ts +51 -1
  186. package/dist/server/image-optimization.js +52 -2
  187. package/dist/server/implicit-tags.js +1 -1
  188. package/dist/server/isr-cache.d.ts +1 -1
  189. package/dist/server/isr-cache.js +2 -2
  190. package/dist/server/metadata-routes.d.ts +3 -1
  191. package/dist/server/metadata-routes.js +12 -2
  192. package/dist/server/middleware-runtime.js +6 -1
  193. package/dist/server/navigation-planner.d.ts +1 -0
  194. package/dist/server/navigation-planner.js +14 -3
  195. package/dist/server/pages-api-route.js +2 -2
  196. package/dist/server/pages-asset-tags.d.ts +4 -6
  197. package/dist/server/pages-asset-tags.js +12 -12
  198. package/dist/server/pages-client-assets.d.ts +12 -0
  199. package/dist/server/pages-client-assets.js +10 -0
  200. package/dist/server/pages-node-compat.d.ts +8 -1
  201. package/dist/server/pages-node-compat.js +32 -4
  202. package/dist/server/pages-page-data.d.ts +24 -1
  203. package/dist/server/pages-page-data.js +45 -24
  204. package/dist/server/pages-page-handler.d.ts +2 -1
  205. package/dist/server/pages-page-handler.js +19 -12
  206. package/dist/server/pages-page-response.d.ts +7 -0
  207. package/dist/server/pages-page-response.js +4 -1
  208. package/dist/server/pages-request-pipeline.d.ts +2 -0
  209. package/dist/server/pages-request-pipeline.js +25 -1
  210. package/dist/server/pages-router-entry.d.ts +30 -0
  211. package/dist/server/pages-router-entry.js +108 -0
  212. package/dist/server/prerender-manifest.d.ts +3 -1
  213. package/dist/server/prerender-route-params.js +1 -1
  214. package/dist/server/prod-server.d.ts +1 -1
  215. package/dist/server/prod-server.js +48 -26
  216. package/dist/server/request-pipeline.js +1 -0
  217. package/dist/server/seed-cache.js +4 -4
  218. package/dist/server/worker-utils.d.ts +2 -1
  219. package/dist/server/worker-utils.js +7 -1
  220. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  221. package/dist/shims/app-router-scroll-state.js +1 -0
  222. package/dist/shims/app-router-scroll.js +2 -1
  223. package/dist/shims/cache.js +19 -15
  224. package/dist/shims/cdn-cache.js +1 -1
  225. package/dist/shims/dynamic-preload-chunks.js +2 -1
  226. package/dist/shims/error-boundary.d.ts +19 -1
  227. package/dist/shims/error-boundary.js +11 -1
  228. package/dist/shims/form.d.ts +3 -1
  229. package/dist/shims/form.js +37 -43
  230. package/dist/shims/headers.d.ts +9 -1
  231. package/dist/shims/headers.js +31 -6
  232. package/dist/shims/image.js +75 -14
  233. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  234. package/dist/shims/internal/app-route-detection.js +4 -17
  235. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  236. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  237. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
  238. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  239. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
  240. package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
  241. package/dist/shims/internal/pages-data-target.d.ts +10 -9
  242. package/dist/shims/internal/pages-data-target.js +91 -12
  243. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  244. package/dist/shims/internal/pages-router-components.js +13 -0
  245. package/dist/shims/layout-segment-context.d.ts +4 -1
  246. package/dist/shims/layout-segment-context.js +18 -4
  247. package/dist/shims/link.js +70 -37
  248. package/dist/shims/metadata.d.ts +3 -2
  249. package/dist/shims/metadata.js +8 -4
  250. package/dist/shims/navigation.d.ts +5 -1
  251. package/dist/shims/navigation.js +45 -10
  252. package/dist/shims/navigation.react-server.js +1 -1
  253. package/dist/shims/root-params.d.ts +15 -1
  254. package/dist/shims/root-params.js +21 -1
  255. package/dist/shims/router.d.ts +5 -7
  256. package/dist/shims/router.js +374 -94
  257. package/dist/shims/server.js +3 -2
  258. package/dist/shims/slot.js +3 -6
  259. package/dist/typegen.js +6 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  261. package/dist/utils/client-runtime-metadata.js +31 -22
  262. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  263. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  264. package/dist/utils/domain-locale.d.ts +6 -3
  265. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  266. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  267. package/dist/utils/path.d.ts +2 -1
  268. package/dist/utils/path.js +1 -1
  269. package/dist/utils/project.d.ts +52 -2
  270. package/dist/utils/project.js +230 -5
  271. package/dist/utils/protocol-headers.d.ts +17 -0
  272. package/dist/utils/protocol-headers.js +17 -0
  273. package/dist/utils/react-version.d.ts +4 -0
  274. package/dist/utils/react-version.js +44 -0
  275. package/package.json +53 -4
  276. package/dist/deploy.d.ts +0 -190
  277. package/dist/deploy.js +0 -1033
  278. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  279. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -1,22 +1,23 @@
1
1
  import { splitPathSegments } from "../routing/utils.js";
2
- import { removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
2
+ import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
3
+ import { parseCookieHeader } from "../utils/parse-cookie.js";
3
4
  import { assertSafeNavigationUrl } from "./url-safety.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";
8
8
  import { applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDataJson } from "../client/vinext-next-data.js";
9
9
  import { isValidModulePath } from "../client/validate-module-path.js";
10
10
  import { addLocalePrefix, getDomainLocaleUrl, getLocalePathPrefix } from "../utils/domain-locale.js";
11
- import { buildPagesDataHref } from "./internal/pages-data-url.js";
11
+ import { fillRoutePatternSegments, matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
12
12
  import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../utils/deployment-id.js";
13
- import { dedupedPagesDataFetch } from "./internal/pages-data-fetch-dedup.js";
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";
17
- import { getPagesRouterComponentsMap, markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
13
+ import { dedupedPagesDataFetch, evictPagesDataCache, fetchCachedPagesData, fetchStaticPagesData, getPagesStaticDataCache } from "./internal/pages-data-fetch-dedup.js";
14
+ import { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
15
+ import { getPagesRouterComponentsMap } from "./internal/pages-router-components.js";
16
+ import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
17
+ import { resolveDirectHybridClientRouteOwner } from "./internal/hybrid-client-route-owner-direct.js";
18
18
  import { installWindowNext } from "../client/window-next.js";
19
19
  import { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
20
+ import { addQueryParam, appendSearchParamsToUrl, mergeRewriteQuery, mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
20
21
  import { scrollToHashTarget } from "./hash-scroll.js";
21
22
  import { installPagesRouterRuntime, setPagesRouterPopStateHandler, setStampInitialHistoryState } from "./pages-router-runtime.js";
22
23
  import { interpolateDynamicRouteHref } from "./internal/interpolate-as.js";
@@ -186,6 +187,7 @@ function createPagesRouterRuntimeState() {
186
187
  activeAbortController: null,
187
188
  cancelPendingRenderCommit: null,
188
189
  lastPathnameAndSearch: typeof window !== "undefined" ? window.location.pathname + window.location.search : "",
190
+ lastHash: typeof window !== "undefined" ? window.location.hash : "",
189
191
  isFirstPopStateEvent: true,
190
192
  routerDidNavigate: false,
191
193
  deprecatedEventBridgeInstalled: false,
@@ -840,31 +842,185 @@ function resolveLocalRedirectUrl(location) {
840
842
  if (appPath === null) return null;
841
843
  return normalizePathTrailingSlash(toBrowserNavigationHref(stripLocalePrefixForApiRedirect(appPath), window.location.href, __basePath), __trailingSlash);
842
844
  }
843
- function hasVinextMiddleware(nextData) {
844
- if (!isUnknownRecord(nextData)) return false;
845
- const vinext = nextData.__vinext;
846
- return isUnknownRecord(vinext) && vinext.hasMiddleware === true;
845
+ function hasClientRewriteRules() {
846
+ const rewrites = window.__VINEXT_CLIENT_REWRITES__;
847
+ return Boolean(rewrites && (rewrites.beforeFiles.length > 0 || rewrites.afterFiles.length > 0 || rewrites.fallback.length > 0));
847
848
  }
848
- function getMiddlewarePagesDataFetchUrl(browserUrl) {
849
- const nextData = window.__NEXT_DATA__;
850
- if (!nextData || !hasVinextMiddleware(nextData)) return null;
851
- const buildId = nextData.buildId;
852
- if (typeof buildId !== "string" || buildId.length === 0) return null;
849
+ function hasClientRedirectRules() {
850
+ const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
851
+ return Array.isArray(redirects) && redirects.length > 0;
852
+ }
853
+ function hasClientAppRouteManifest() {
854
+ const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
855
+ return Array.isArray(routes) && routes.length > 0;
856
+ }
857
+ function getClientConfigRouteContext(href) {
853
858
  let parsed;
854
859
  try {
855
- parsed = new URL(browserUrl, window.location.href);
860
+ parsed = new URL(href, window.location.href);
856
861
  } catch {
857
862
  return null;
858
863
  }
859
864
  if (parsed.origin !== getWindowOrigin()) return null;
860
- return buildPagesDataHref(__basePath, buildId, stripBasePath(parsed.pathname, __basePath), parsed.search);
865
+ const hadBasePath = __basePath ? hasBasePath(parsed.pathname, __basePath) : true;
866
+ const pathname = hadBasePath ? stripBasePath(parsed.pathname, __basePath) : parsed.pathname;
867
+ const headers = new Headers({ "user-agent": globalThis.navigator?.userAgent ?? "" });
868
+ return {
869
+ basePathState: {
870
+ basePath: __basePath,
871
+ hadBasePath
872
+ },
873
+ context: {
874
+ cookies: parseCookieHeader(globalThis.document?.cookie ?? ""),
875
+ headers,
876
+ host: parsed.hostname,
877
+ query: parsed.searchParams
878
+ },
879
+ pathname,
880
+ search: parsed.search
881
+ };
882
+ }
883
+ async function resolveClientConfigRedirect(href) {
884
+ const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
885
+ if (!redirects || redirects.length === 0) return null;
886
+ const routeContext = getClientConfigRouteContext(href);
887
+ if (!routeContext) return null;
888
+ const { isExternalUrl, matchRedirect, preserveRedirectDestinationQuery } = await import("../config/config-matchers.js");
889
+ const redirect = matchRedirect(routeContext.pathname, redirects, routeContext.context, routeContext.basePathState);
890
+ if (!redirect) return null;
891
+ return preserveRedirectDestinationQuery(__basePath && routeContext.basePathState.hadBasePath && !isExternalUrl(redirect.destination) && !hasBasePath(redirect.destination, __basePath) ? __basePath + redirect.destination : redirect.destination, routeContext.search);
892
+ }
893
+ async function applyClientConfigRewrite(href, rewrite) {
894
+ const routeContext = getClientConfigRouteContext(href);
895
+ if (!routeContext) return null;
896
+ const { isExternalUrl, matchRewrite } = await import("../config/config-matchers.js");
897
+ const rewritten = matchRewrite(routeContext.pathname, [rewrite], routeContext.context, routeContext.basePathState);
898
+ if (rewritten === null) return null;
899
+ if (isExternalUrl(rewritten)) return { kind: "document" };
900
+ return {
901
+ href: mergeRewriteQuery(href, rewritten),
902
+ kind: "rewrite"
903
+ };
904
+ }
905
+ function shouldEvaluateClientConfigRule(ruleBasePath, state) {
906
+ if (!state.basePath) return true;
907
+ return ruleBasePath === false ? !state.hadBasePath : state.hadBasePath;
908
+ }
909
+ function matchSimpleClientConfigPattern(pathname, source) {
910
+ if (source.includes("(") || source.includes("\\") || /:[\w-]+[*+][^/]/.test(source)) return;
911
+ const sourceParts = removeTrailingSlash(source).split("/");
912
+ const pathParts = removeTrailingSlash(pathname).split("/");
913
+ const params = {};
914
+ let pathIndex = 0;
915
+ for (let sourceIndex = 0; sourceIndex < sourceParts.length; sourceIndex++) {
916
+ const sourcePart = sourceParts[sourceIndex];
917
+ const pathPart = pathParts[pathIndex];
918
+ if (sourcePart.startsWith(":")) {
919
+ const catchAll = sourcePart.match(/^:([\w-]+)([*+])$/);
920
+ if (catchAll) {
921
+ const rest = pathParts.slice(pathIndex).join("/");
922
+ if (catchAll[2] === "+" && rest === "") return null;
923
+ params[catchAll[1]] = rest;
924
+ return sourceIndex === sourceParts.length - 1 ? params : void 0;
925
+ }
926
+ if (pathPart === void 0) return null;
927
+ params[sourcePart.slice(1)] = pathPart;
928
+ pathIndex++;
929
+ continue;
930
+ }
931
+ if (pathPart !== sourcePart) return null;
932
+ pathIndex++;
933
+ }
934
+ return pathIndex === pathParts.length ? params : null;
935
+ }
936
+ function simpleClientConfigSourceCouldMatch(pathname, source) {
937
+ const wildcardIndex = source.search(/[:(\\*+?]/);
938
+ const normalizedPrefix = removeTrailingSlash(wildcardIndex === -1 ? source : source.slice(0, wildcardIndex));
939
+ if (!normalizedPrefix || normalizedPrefix === "/") return true;
940
+ const normalizedPathname = removeTrailingSlash(pathname);
941
+ return normalizedPathname === normalizedPrefix || normalizedPathname.startsWith(`${normalizedPrefix}/`);
942
+ }
943
+ function substituteSimpleClientConfigDestination(destination, params) {
944
+ const keys = Object.keys(params);
945
+ if (keys.length === 0) return destination;
946
+ const alternation = keys.sort((a, b) => b.length - a.length).map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
947
+ return destination.replace(new RegExp(`:(${alternation})([+*])?(?![A-Za-z0-9_])`, "g"), (_token, key) => params[key] ?? _token);
948
+ }
949
+ function isExternalClientConfigUrl(url) {
950
+ return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith("//");
951
+ }
952
+ function clientConfigRedirectCouldMatch(href) {
953
+ const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
954
+ if (!redirects || redirects.length === 0) return false;
955
+ const routeContext = getClientConfigRouteContext(href);
956
+ if (!routeContext) return false;
957
+ for (const redirect of redirects) {
958
+ if (!shouldEvaluateClientConfigRule(redirect.basePath, routeContext.basePathState)) continue;
959
+ if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, redirect.source)) continue;
960
+ if (matchSimpleClientConfigPattern(routeContext.pathname, redirect.source) !== null) return true;
961
+ }
962
+ return false;
963
+ }
964
+ function resolveClientConfigRewriteSync(href) {
965
+ const rewrites = window.__VINEXT_CLIENT_REWRITES__;
966
+ if (!rewrites) return null;
967
+ let currentHref = href;
968
+ let matched = false;
969
+ for (const rewrite of rewrites.beforeFiles) {
970
+ const routeContext = getClientConfigRouteContext(currentHref);
971
+ if (!routeContext) return null;
972
+ if (!shouldEvaluateClientConfigRule(rewrite.basePath, routeContext.basePathState)) continue;
973
+ if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, rewrite.source)) continue;
974
+ if (rewrite.has || rewrite.missing) return void 0;
975
+ const params = matchSimpleClientConfigPattern(routeContext.pathname, rewrite.source);
976
+ if (params === void 0) return void 0;
977
+ if (params === null) continue;
978
+ const rewritten = substituteSimpleClientConfigDestination(rewrite.destination, params);
979
+ if (isExternalClientConfigUrl(rewritten)) return { kind: "document" };
980
+ currentHref = mergeRewriteQuery(currentHref, rewritten);
981
+ matched = true;
982
+ }
983
+ return matched ? {
984
+ href: currentHref,
985
+ kind: "rewrite"
986
+ } : null;
987
+ }
988
+ async function resolveClientConfigRewrite(href) {
989
+ const rewrites = window.__VINEXT_CLIENT_REWRITES__;
990
+ if (!rewrites) return null;
991
+ let currentHref = href;
992
+ let matched = false;
993
+ for (const rewrite of rewrites.beforeFiles) {
994
+ const result = await applyClientConfigRewrite(currentHref, rewrite);
995
+ if (result?.kind === "document") return result;
996
+ if (result?.kind !== "rewrite") continue;
997
+ currentHref = result.href;
998
+ matched = true;
999
+ }
1000
+ return matched ? {
1001
+ href: currentHref,
1002
+ kind: "rewrite"
1003
+ } : null;
1004
+ }
1005
+ function getMiddlewarePagesDataFetchUrl(browserUrl) {
1006
+ return getPagesMiddlewareDataHref(browserUrl, __basePath);
1007
+ }
1008
+ function getPagesDataCacheHref(dataHref) {
1009
+ try {
1010
+ return new URL(dataHref, window.location.href).href;
1011
+ } catch {
1012
+ return dataHref;
1013
+ }
1014
+ }
1015
+ function shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget) {
1016
+ return middlewareEffect?.redirectLocation != null || dataTarget?.dataKind !== "static";
861
1017
  }
862
1018
  async function resolveMiddlewareDataEffect(browserUrl, signal) {
863
1019
  const dataUrl = getMiddlewarePagesDataFetchUrl(browserUrl);
864
1020
  if (!dataUrl) return null;
865
1021
  if (signal.aborted) throw new DOMException("Aborted", "AbortError");
866
1022
  try {
867
- const res = await dedupedPagesDataFetch(dataUrl, {
1023
+ const res = await fetchCachedPagesData(dataUrl, {
868
1024
  headers: {
869
1025
  Accept: "application/json",
870
1026
  "x-nextjs-data": "1"
@@ -872,6 +1028,7 @@ async function resolveMiddlewareDataEffect(browserUrl, signal) {
872
1028
  signal
873
1029
  });
874
1030
  return {
1031
+ dataHref: getPagesDataCacheHref(dataUrl),
875
1032
  redirectLocation: res.headers.get("x-nextjs-redirect"),
876
1033
  rewriteTarget: res.headers.get("x-nextjs-rewrite"),
877
1034
  response: res
@@ -899,6 +1056,110 @@ function handleDataRedirect(destination, redirectBasePath, mode = "push") {
899
1056
  if (!(destination.startsWith("/") && redirectBasePath !== false)) scheduleHardNavigationAndThrow(destination, "Navigation redirected externally");
900
1057
  performNavigation(destination, void 0, { locale: false }, mode);
901
1058
  }
1059
+ async function loadTargetPageModule(target, url, failurePrefix) {
1060
+ try {
1061
+ return await target.loader();
1062
+ } catch (err) {
1063
+ console.error("[vinext] Page loader threw during navigation:", err);
1064
+ scheduleHardNavigationAndThrow(url, `${failurePrefix}: page loader threw`);
1065
+ }
1066
+ }
1067
+ async function loadPagesAppComponent() {
1068
+ let AppComponent = window.__VINEXT_APP__;
1069
+ if (!AppComponent && typeof window.__VINEXT_APP_LOADER__ === "function") try {
1070
+ const appModule = await window.__VINEXT_APP_LOADER__();
1071
+ AppComponent = isAppComponent(appModule.default) ? appModule.default : void 0;
1072
+ if (AppComponent) window.__VINEXT_APP__ = AppComponent;
1073
+ } catch {}
1074
+ return AppComponent;
1075
+ }
1076
+ function buildPagesNavigationNextData(target, props) {
1077
+ const mergedQuery = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
1078
+ const prev = window.__NEXT_DATA__;
1079
+ const nextLocale = (window.__VINEXT_LOCALES__?.length ?? 0) > 0 ? target.locale ?? window.__VINEXT_DEFAULT_LOCALE__ : prev?.locale;
1080
+ return {
1081
+ ...prev,
1082
+ props,
1083
+ page: target.pattern,
1084
+ query: mergedQuery,
1085
+ buildId: target.buildId,
1086
+ isFallback: false,
1087
+ ...nextLocale !== void 0 ? { locale: nextLocale } : {}
1088
+ };
1089
+ }
1090
+ function propsObject(value) {
1091
+ return isUnknownRecord(value) ? value : {};
1092
+ }
1093
+ async function loadComponentOnlyProps(PageComponent, AppComponent, target, asPath) {
1094
+ const query = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
1095
+ const ctx = {
1096
+ pathname: target.pattern,
1097
+ query,
1098
+ asPath,
1099
+ locale: target.locale ?? window.__VINEXT_LOCALE__,
1100
+ locales: window.__VINEXT_LOCALES__,
1101
+ defaultLocale: window.__VINEXT_DEFAULT_LOCALE__
1102
+ };
1103
+ if (typeof AppComponent?.getInitialProps === "function") {
1104
+ const AppTree = (appProps) => createElement(AppComponent, {
1105
+ ...appProps,
1106
+ Component: PageComponent,
1107
+ router: Router
1108
+ });
1109
+ return propsObject(await AppComponent.getInitialProps({
1110
+ Component: PageComponent,
1111
+ AppTree,
1112
+ ctx,
1113
+ router: Router
1114
+ }));
1115
+ }
1116
+ if (typeof PageComponent.getInitialProps === "function") return { pageProps: propsObject(await PageComponent.getInitialProps(ctx)) };
1117
+ return { pageProps: {} };
1118
+ }
1119
+ async function renderPagesNavigationTarget(url, target, props, options, assertStillCurrent, preloaded) {
1120
+ const pageModule = preloaded?.pageModule ?? await loadTargetPageModule(target, url, "Navigation failed");
1121
+ assertStillCurrent();
1122
+ const PageComponent = pageModule.default;
1123
+ if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Navigation failed: page module default export is not a component");
1124
+ const AppComponent = preloaded?.appComponent ?? await loadPagesAppComponent();
1125
+ assertStillCurrent();
1126
+ const React = (await import("react")).default;
1127
+ assertStillCurrent();
1128
+ const rawPageProps = props.pageProps;
1129
+ const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
1130
+ let element;
1131
+ if (AppComponent) element = React.createElement(AppComponent, {
1132
+ ...props,
1133
+ Component: PageComponent,
1134
+ pageProps: rawPageProps,
1135
+ router: Router
1136
+ });
1137
+ else element = React.createElement(PageComponent, pageProps);
1138
+ const nextData = buildPagesNavigationNextData(target, props);
1139
+ window.__NEXT_DATA__ = nextData;
1140
+ applyVinextLocaleGlobals(window, nextData);
1141
+ await renderPagesRouterElement(element, options.scroll);
1142
+ assertStillCurrent();
1143
+ }
1144
+ async function navigateClientNoData(url, target, controller, assertStillCurrent, options = {}) {
1145
+ if (!window.__VINEXT_ROOT__) {
1146
+ window.location.href = url;
1147
+ return;
1148
+ }
1149
+ if (controller.signal.aborted) throw new NavigationCancelledError(url);
1150
+ const pageModule = await loadTargetPageModule(target, url, "Navigation failed");
1151
+ assertStillCurrent();
1152
+ const PageComponent = pageModule.default;
1153
+ if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Navigation failed: page module default export is not a component");
1154
+ const AppComponent = await loadPagesAppComponent();
1155
+ assertStillCurrent();
1156
+ const props = await loadComponentOnlyProps(PageComponent, AppComponent, target, url);
1157
+ assertStillCurrent();
1158
+ await renderPagesNavigationTarget(url, target, props, options, assertStillCurrent, {
1159
+ appComponent: AppComponent,
1160
+ pageModule
1161
+ });
1162
+ }
902
1163
  /**
903
1164
  * Perform client-side navigation via the `/_next/data/<id>/<page>.json`
904
1165
  * endpoint. Used when `__VINEXT_PAGE_LOADERS__` has a matching code-split
@@ -926,7 +1187,7 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
926
1187
  };
927
1188
  const deploymentId = getDeploymentId();
928
1189
  if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
929
- res = await dedupedPagesDataFetch(initialTarget.dataHref, {
1190
+ res = await (initialTarget.dataKind === "static" ? fetchStaticPagesData : dedupedPagesDataFetch)(initialTarget.dataHref, {
930
1191
  headers,
931
1192
  signal: controller.signal
932
1193
  });
@@ -935,12 +1196,16 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
935
1196
  throw err;
936
1197
  }
937
1198
  assertStillCurrent();
1199
+ const responseDeploymentId = res.headers.get("x-nextjs-deployment-id");
1200
+ const currentDeploymentId = getDeploymentId() ?? null;
1201
+ if (responseDeploymentId !== null && responseDeploymentId !== currentDeploymentId) scheduleHardNavigationAndThrow(url, "Loaded static props were from an outdated deployment");
938
1202
  const softRedirect = res.headers.get("x-nextjs-redirect");
939
1203
  if (softRedirect) {
940
1204
  const redirectedUrl = resolveLocalRedirectUrl(softRedirect);
941
1205
  if (!redirectedUrl) scheduleHardNavigationAndThrow(softRedirect, "Navigation redirected externally");
942
1206
  window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
943
1207
  routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1208
+ routerRuntimeState.lastHash = window.location.hash;
944
1209
  await navigateClientHtml(redirectedUrl, redirectedUrl, controller, navId, assertStillCurrent);
945
1210
  return;
946
1211
  }
@@ -958,54 +1223,13 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
958
1223
  const props = isUnknownRecord(body) ? body : {};
959
1224
  const rawPageProps = props.pageProps;
960
1225
  const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
1226
+ if (initialTarget.dataKind === "server") evictPagesDataCache(initialTarget.dataHref);
961
1227
  const redirectDestination = pageProps.__N_REDIRECT;
962
1228
  if (typeof redirectDestination === "string") {
963
1229
  handleDataRedirect(redirectDestination, pageProps.__N_REDIRECT_BASE_PATH, options.mode);
964
1230
  throw new NavigationCancelledError(url);
965
1231
  }
966
- let pageModule;
967
- try {
968
- pageModule = await target.loader();
969
- } catch (err) {
970
- console.error("[vinext] Page loader threw during navigation:", err);
971
- scheduleHardNavigationAndThrow(url, "Data navigation failed: page loader threw");
972
- }
973
- assertStillCurrent();
974
- const PageComponent = pageModule.default;
975
- if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Data navigation failed: page module default export is not a component");
976
- let AppComponent = window.__VINEXT_APP__;
977
- if (!AppComponent && typeof window.__VINEXT_APP_LOADER__ === "function") try {
978
- const appModule = await window.__VINEXT_APP_LOADER__();
979
- AppComponent = isAppComponent(appModule.default) ? appModule.default : void 0;
980
- if (AppComponent) window.__VINEXT_APP__ = AppComponent;
981
- } catch {}
982
- assertStillCurrent();
983
- const React = (await import("react")).default;
984
- assertStillCurrent();
985
- let element;
986
- if (AppComponent) element = React.createElement(AppComponent, {
987
- ...props,
988
- Component: PageComponent,
989
- pageProps: rawPageProps,
990
- router: Router
991
- });
992
- else element = React.createElement(PageComponent, pageProps);
993
- const mergedQuery = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
994
- const prev = window.__NEXT_DATA__;
995
- const nextLocale = (window.__VINEXT_LOCALES__?.length ?? 0) > 0 ? target.locale ?? window.__VINEXT_DEFAULT_LOCALE__ : prev?.locale;
996
- const nextData = {
997
- ...prev,
998
- props,
999
- page: target.pattern,
1000
- query: mergedQuery,
1001
- buildId: target.buildId,
1002
- isFallback: false,
1003
- ...nextLocale !== void 0 ? { locale: nextLocale } : {}
1004
- };
1005
- window.__NEXT_DATA__ = nextData;
1006
- applyVinextLocaleGlobals(window, nextData);
1007
- await renderPagesRouterElement(element, options.scroll);
1008
- assertStillCurrent();
1232
+ await renderPagesNavigationTarget(url, target, props, options, assertStillCurrent);
1009
1233
  }
1010
1234
  /**
1011
1235
  * Perform client-side navigation by fetching the page's full HTML and
@@ -1099,6 +1323,7 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
1099
1323
  if (pendingRedirectHistoryUrl) {
1100
1324
  window.history.replaceState(window.history.state ?? {}, "", pendingRedirectHistoryUrl);
1101
1325
  routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1326
+ routerRuntimeState.lastHash = window.location.hash;
1102
1327
  }
1103
1328
  window.__NEXT_DATA__ = nextData;
1104
1329
  applyVinextLocaleGlobals(window, nextData);
@@ -1127,6 +1352,7 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
1127
1352
  const controller = new AbortController();
1128
1353
  routerRuntimeState.activeAbortController = controller;
1129
1354
  const navId = ++routerRuntimeState.navigationId;
1355
+ let middlewareDataCacheEvictHref = null;
1130
1356
  /** Check if this navigation is still the active one. If not, throw. */
1131
1357
  function assertStillCurrent() {
1132
1358
  if (navId !== routerRuntimeState.navigationId) throw new NavigationCancelledError(url);
@@ -1136,35 +1362,70 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
1136
1362
  else {
1137
1363
  let browserUrl = url;
1138
1364
  let htmlFetchUrl = fetchUrl;
1139
- let dataTarget = resolvePagesDataNavigationTarget(routeUrl, __basePath);
1365
+ const configRedirect = hasClientRedirectRules() && clientConfigRedirectCouldMatch(browserUrl) ? await resolveClientConfigRedirect(browserUrl) : null;
1366
+ if (configRedirect) {
1367
+ const redirectedUrl = resolveLocalRedirectUrl(configRedirect);
1368
+ if (!redirectedUrl) scheduleHardNavigationAndThrow(configRedirect, "Navigation redirected externally");
1369
+ window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
1370
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1371
+ routerRuntimeState.lastHash = window.location.hash;
1372
+ browserUrl = redirectedUrl;
1373
+ htmlFetchUrl = redirectedUrl;
1374
+ }
1375
+ let routeLookupUrl = configRedirect ? browserUrl : routeUrl;
1376
+ if (routeUrl === url && hasClientRewriteRules()) {
1377
+ const syncConfigRewrite = hasClientAppRouteManifest() ? void 0 : resolveClientConfigRewriteSync(browserUrl);
1378
+ const configRewrite = syncConfigRewrite === void 0 ? await resolveClientConfigRewrite(browserUrl) : syncConfigRewrite;
1379
+ if (configRewrite?.kind === "document") scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a document route");
1380
+ else if (configRewrite?.kind === "rewrite") {
1381
+ routeLookupUrl = configRewrite.href;
1382
+ htmlFetchUrl = configRewrite.href;
1383
+ }
1384
+ }
1385
+ let dataTarget = resolvePagesDataNavigationTarget(routeLookupUrl, __basePath);
1140
1386
  let middlewareDataResponse;
1141
- if (!dataTarget) {
1142
- let middlewareEffect;
1387
+ let middlewareEffect = null;
1388
+ let middlewareRewrittenTarget;
1389
+ const middlewareProbeDataHref = getMiddlewarePagesDataFetchUrl(browserUrl);
1390
+ if (middlewareProbeDataHref !== null) {
1391
+ middlewareDataCacheEvictHref = getPagesDataCacheHref(middlewareProbeDataHref);
1143
1392
  try {
1144
1393
  middlewareEffect = await resolveMiddlewareDataEffect(browserUrl, controller.signal);
1145
1394
  } catch (err) {
1146
1395
  if (err instanceof DOMException && err.name === "AbortError") throw new NavigationCancelledError(browserUrl);
1147
1396
  throw err;
1148
1397
  }
1398
+ if (middlewareEffect?.rewriteTarget) middlewareRewrittenTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
1399
+ if (middlewareEffect) if (shouldEvictMiddlewareDataCache(middlewareEffect, middlewareRewrittenTarget !== void 0 ? middlewareRewrittenTarget : dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
1400
+ else middlewareDataCacheEvictHref = null;
1149
1401
  assertStillCurrent();
1150
- const redirectLocation = middlewareEffect?.redirectLocation ?? null;
1151
- if (redirectLocation) {
1152
- const redirectedUrl = resolveLocalRedirectUrl(redirectLocation);
1153
- if (!redirectedUrl) scheduleHardNavigationAndThrow(redirectLocation, "Navigation redirected externally");
1154
- window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
1155
- routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1156
- browserUrl = redirectedUrl;
1157
- htmlFetchUrl = redirectedUrl;
1158
- } else if (middlewareEffect?.rewriteTarget) {
1159
- dataTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
1160
- if (dataTarget) middlewareDataResponse = middlewareEffect.response;
1402
+ }
1403
+ const redirectLocation = middlewareEffect?.redirectLocation ?? null;
1404
+ if (redirectLocation) {
1405
+ const redirectedUrl = resolveLocalRedirectUrl(redirectLocation);
1406
+ if (!redirectedUrl) scheduleHardNavigationAndThrow(redirectLocation, "Navigation redirected externally");
1407
+ window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
1408
+ routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1409
+ routerRuntimeState.lastHash = window.location.hash;
1410
+ browserUrl = redirectedUrl;
1411
+ htmlFetchUrl = redirectedUrl;
1412
+ } else if (middlewareEffect) {
1413
+ if (middlewareEffect.rewriteTarget || routeUrl === url) middlewareDataResponse = middlewareEffect.response;
1414
+ if (middlewareEffect.rewriteTarget) {
1415
+ const rewrittenTarget = middlewareRewrittenTarget ?? resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
1416
+ if (!rewrittenTarget) scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a non-Pages route");
1417
+ dataTarget = rewrittenTarget;
1161
1418
  }
1162
1419
  }
1163
- if (dataTarget) await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options, middlewareDataResponse);
1420
+ if (middlewareEffect && shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
1421
+ else if (middlewareEffect) middlewareDataCacheEvictHref = null;
1422
+ if (dataTarget?.dataKind === "static" || dataTarget?.dataKind === "server") await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options, middlewareDataResponse);
1423
+ else if (dataTarget) await navigateClientNoData(browserUrl, dataTarget, controller, assertStillCurrent, options);
1164
1424
  else await navigateClientHtml(browserUrl, htmlFetchUrl, controller, navId, assertStillCurrent, options);
1165
1425
  }
1166
1426
  } finally {
1167
1427
  if (navId === routerRuntimeState.navigationId) routerRuntimeState.activeAbortController = null;
1428
+ if (middlewareDataCacheEvictHref !== null) evictPagesDataCache(middlewareDataCacheEvictHref);
1168
1429
  }
1169
1430
  }
1170
1431
  /**
@@ -1263,6 +1524,7 @@ function updateHistory(mode, fullUrl, navState) {
1263
1524
  else window.history.replaceState(state, "", fullUrl);
1264
1525
  routerRuntimeState.currentHistoryKey = key;
1265
1526
  routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
1527
+ routerRuntimeState.lastHash = window.location.hash;
1266
1528
  routerRuntimeState.routerDidNavigate = true;
1267
1529
  }
1268
1530
  function createHistoryKey() {
@@ -1386,7 +1648,14 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1386
1648
  const appPath = getLocalPathname(resolved);
1387
1649
  const appPathNorm = appPath !== null ? removeTrailingSlash(appPath) : null;
1388
1650
  const appPathEntry = appPathNorm !== null ? getPagesRouterComponentsMap()[appPathNorm] : void 0;
1389
- if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter || ["app", "document"].includes(resolveHybridClientRouteOwner(resolved, __basePath) ?? "")) {
1651
+ if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter) {
1652
+ if (mode === "push") window.location.assign(full);
1653
+ else window.location.replace(full);
1654
+ return new Promise(() => {});
1655
+ }
1656
+ const rewrites = window.__VINEXT_CLIENT_REWRITES__;
1657
+ const hybridOwner = rewrites && (rewrites.beforeFiles.length > 0 || rewrites.afterFiles.length > 0 || rewrites.fallback.length > 0) && hasClientAppRouteManifest() ? (await import("./internal/hybrid-client-route-owner.js")).resolveHybridClientRouteOwner(resolved, __basePath) : resolveDirectHybridClientRouteOwner(resolved, __basePath);
1658
+ if (["app", "document"].includes(hybridOwner ?? "")) {
1390
1659
  if (mode === "push") window.location.assign(full);
1391
1660
  else window.location.replace(full);
1392
1661
  return new Promise(() => {});
@@ -1412,12 +1681,11 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1412
1681
  * Prefetch the resources needed for a future Pages Router navigation.
1413
1682
  *
1414
1683
  * When the client has a registered code-split loader for the target route
1415
- * (the prod hot path), we prefetch in parallel:
1416
- * 1. The `/_next/data/<buildId>/<page>.json` payload same URL the actual
1417
- * navigation will request, so a cache hit is automatic.
1418
- * 2. The page's JS chunk by invoking the loader thunk now. Vite's
1419
- * dynamic `import()` machinery is responsible for fetching + caching;
1420
- * the returned Promise is intentionally discarded.
1684
+ * (the prod hot path), we warm the page's JS chunk by invoking the loader
1685
+ * thunk now. Vite's dynamic `import()` machinery is responsible for fetching
1686
+ * and caching it; the returned Promise is intentionally discarded. SSG routes
1687
+ * also prefetch their `/_next/data/<buildId>/<page>.json` payload, matching
1688
+ * Next.js's Pages Router `_isSsg(route)` gate.
1421
1689
  *
1422
1690
  * When no loader is registered (dev server, or an unmapped route), we fall
1423
1691
  * back to the legacy `<link rel="prefetch" as="document">` hint, which lets
@@ -1427,17 +1695,22 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1427
1695
  * Ported from Next.js: `packages/next/src/client/page-loader.ts` `prefetch`
1428
1696
  * (the data + chunk parallel prefetch shape).
1429
1697
  */
1430
- async function prefetchUrl(url) {
1698
+ async function prefetchUrl(url, as) {
1431
1699
  if (typeof document === "undefined") return;
1700
+ const displayUrl = as ?? url;
1432
1701
  const dataTarget = resolvePagesDataNavigationTarget(url, __basePath);
1433
1702
  if (dataTarget) {
1434
- prefetchPagesData(dataTarget);
1703
+ const middlewareDataHref = displayUrl === url ? dataTarget.middlewareDataHref : getPagesMiddlewareDataHref(displayUrl, __basePath) ?? void 0;
1704
+ prefetchPagesData({
1705
+ ...dataTarget,
1706
+ middlewareDataHref
1707
+ });
1435
1708
  return;
1436
1709
  }
1437
- markAppRouteDetectedOnPrefetch(url, __basePath);
1710
+ await markAppRouteDetectedOnPrefetch(displayUrl, __basePath);
1438
1711
  const link = document.createElement("link");
1439
1712
  link.rel = "prefetch";
1440
- link.href = url;
1713
+ link.href = displayUrl;
1441
1714
  link.as = "document";
1442
1715
  document.head.appendChild(link);
1443
1716
  }
@@ -1519,6 +1792,10 @@ function getRouterStateKey(state) {
1519
1792
  if (!isNextRouterState(state)) return void 0;
1520
1793
  return typeof state.key === "string" ? state.key : void 0;
1521
1794
  }
1795
+ function getTrackedPagesRouterAsPath() {
1796
+ const trackedUrl = new URL(routerRuntimeState.lastPathnameAndSearch, window.location.href);
1797
+ return removeNavigationLocalePrefix(stripBasePath(trackedUrl.pathname, __basePath) + trackedUrl.search);
1798
+ }
1522
1799
  function handlePagesRouterPopState(e) {
1523
1800
  const browserUrl = window.location.pathname + window.location.search;
1524
1801
  const appUrl = stripBasePath(window.location.pathname, __basePath) + window.location.search;
@@ -1528,9 +1805,10 @@ function handlePagesRouterPopState(e) {
1528
1805
  if (state !== null && state !== void 0 && !isNextRouterState(state)) return;
1529
1806
  if (wasFirst && !routerRuntimeState.routerDidNavigate && isNextRouterState(state)) {
1530
1807
  const currentLocale = window.__VINEXT_LOCALE__;
1531
- if (state.options?.locale === currentLocale && typeof state.as === "string" && withBasePath(state.as, __basePath) === routerRuntimeState.lastPathnameAndSearch) return;
1808
+ if (state.options?.locale === currentLocale && typeof state.as === "string" && state.as === getTrackedPagesRouterAsPath()) return;
1532
1809
  }
1533
- const isHashOnly = browserUrl === routerRuntimeState.lastPathnameAndSearch;
1810
+ const currentHash = window.location.hash;
1811
+ const isHashOnly = browserUrl === routerRuntimeState.lastPathnameAndSearch && (currentHash !== routerRuntimeState.lastHash || currentHash !== "");
1534
1812
  const targetKey = getRouterStateKey(state);
1535
1813
  let forcedScroll;
1536
1814
  if (manualScrollRestoration) {
@@ -1555,6 +1833,7 @@ function handlePagesRouterPopState(e) {
1555
1833
  }
1556
1834
  if (targetKey !== void 0) routerRuntimeState.currentHistoryKey = targetKey;
1557
1835
  routerRuntimeState.lastPathnameAndSearch = browserUrl;
1836
+ routerRuntimeState.lastHash = currentHash;
1558
1837
  if (isHashOnly) {
1559
1838
  const hashUrl = appUrl + window.location.hash;
1560
1839
  routerEvents.emit("hashChangeStart", hashUrl, { shallow: false });
@@ -1643,6 +1922,7 @@ function withRouter(ComposedComponent) {
1643
1922
  const RouterMethods = {
1644
1923
  /** See `_components` comment above for the dual role this map plays. */
1645
1924
  components: getPagesRouterComponentsMap(),
1925
+ sdc: getPagesStaticDataCache(),
1646
1926
  push: (url, as, options) => {
1647
1927
  if (typeof window === "undefined") throwNoRouterInstance();
1648
1928
  assertSafeNavigationUrl(resolveUrl(url));
@@ -1663,9 +1943,9 @@ const RouterMethods = {
1663
1943
  if (typeof window === "undefined") throwNoRouterInstance();
1664
1944
  window.location.reload();
1665
1945
  },
1666
- prefetch: (url) => {
1946
+ prefetch: (url, as) => {
1667
1947
  if (typeof window === "undefined") throwNoRouterInstance();
1668
- return prefetchUrl(url);
1948
+ return prefetchUrl(url, as);
1669
1949
  },
1670
1950
  beforePopState: (cb) => {
1671
1951
  if (typeof window === "undefined") throwNoRouterInstance();