vinext 1.0.0-beta.1 → 1.0.0-beta.2

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 (175) hide show
  1. package/README.md +4 -1
  2. package/dist/build/client-build-config.js +1 -0
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +15 -2
  6. package/dist/cli.js +3 -2
  7. package/dist/config/config-matchers.d.ts +13 -37
  8. package/dist/config/config-matchers.js +31 -121
  9. package/dist/config/next-config.d.ts +3 -2
  10. package/dist/config/next-config.js +3 -1
  11. package/dist/config/request-context.d.ts +14 -0
  12. package/dist/config/request-context.js +26 -0
  13. package/dist/entries/app-rsc-entry.js +27 -9
  14. package/dist/entries/app-rsc-manifest.js +17 -0
  15. package/dist/entries/pages-server-entry.js +3 -2
  16. package/dist/index.js +82 -58
  17. package/dist/init.d.ts +6 -4
  18. package/dist/init.js +20 -22
  19. package/dist/plugins/og-assets.js +1 -1
  20. package/dist/routing/app-route-graph.d.ts +13 -5
  21. package/dist/routing/app-route-graph.js +59 -13
  22. package/dist/routing/app-router.js +12 -6
  23. package/dist/routing/file-matcher.d.ts +11 -22
  24. package/dist/routing/file-matcher.js +21 -33
  25. package/dist/routing/pages-router.js +23 -29
  26. package/dist/routing/route-matching.d.ts +14 -1
  27. package/dist/routing/route-matching.js +13 -1
  28. package/dist/routing/route-pattern.d.ts +2 -1
  29. package/dist/routing/route-pattern.js +7 -4
  30. package/dist/routing/route-trie.d.ts +5 -1
  31. package/dist/routing/route-trie.js +5 -2
  32. package/dist/server/app-browser-entry.js +7 -6
  33. package/dist/server/app-browser-history-controller.d.ts +1 -1
  34. package/dist/server/app-browser-history-controller.js +3 -3
  35. package/dist/server/app-browser-navigation-controller.js +1 -1
  36. package/dist/server/app-browser-state.js +1 -1
  37. package/dist/server/app-browser-visible-commit.js +1 -1
  38. package/dist/server/app-fallback-renderer.d.ts +3 -0
  39. package/dist/server/app-fallback-renderer.js +4 -2
  40. package/dist/server/app-middleware.js +2 -1
  41. package/dist/server/app-page-boundary-render.d.ts +12 -1
  42. package/dist/server/app-page-boundary-render.js +84 -2
  43. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  44. package/dist/server/app-page-cache.d.ts +1 -1
  45. package/dist/server/app-page-dispatch.d.ts +11 -2
  46. package/dist/server/app-page-dispatch.js +14 -17
  47. package/dist/server/app-page-element-builder.d.ts +7 -2
  48. package/dist/server/app-page-element-builder.js +112 -27
  49. package/dist/server/app-page-head.d.ts +54 -2
  50. package/dist/server/app-page-head.js +164 -78
  51. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  52. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  53. package/dist/server/app-page-render.d.ts +2 -2
  54. package/dist/server/app-page-render.js +1 -1
  55. package/dist/server/app-page-request.d.ts +12 -0
  56. package/dist/server/app-page-request.js +133 -13
  57. package/dist/server/app-page-route-wiring.d.ts +9 -0
  58. package/dist/server/app-page-route-wiring.js +43 -3
  59. package/dist/server/app-post-middleware-context.d.ts +1 -1
  60. package/dist/server/app-post-middleware-context.js +1 -1
  61. package/dist/server/app-route-handler-dispatch.js +31 -17
  62. package/dist/server/app-route-handler-execution.d.ts +6 -1
  63. package/dist/server/app-route-handler-execution.js +42 -16
  64. package/dist/server/app-route-handler-policy.d.ts +2 -0
  65. package/dist/server/app-route-handler-policy.js +3 -3
  66. package/dist/server/app-route-module-loader.d.ts +3 -1
  67. package/dist/server/app-route-module-loader.js +1 -0
  68. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  69. package/dist/server/app-rsc-errors.d.ts +1 -1
  70. package/dist/server/app-rsc-errors.js +12 -2
  71. package/dist/server/app-rsc-handler.d.ts +10 -5
  72. package/dist/server/app-rsc-handler.js +52 -24
  73. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  74. package/dist/server/app-rsc-request-normalization.js +8 -2
  75. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  76. package/dist/server/app-rsc-response-finalizer.js +5 -11
  77. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  78. package/dist/server/app-rsc-route-matching.js +87 -11
  79. package/dist/server/app-segment-config.js +13 -3
  80. package/dist/server/app-server-action-execution.d.ts +3 -1
  81. package/dist/server/app-server-action-execution.js +9 -7
  82. package/dist/server/app-ssr-entry.js +2 -2
  83. package/dist/server/app-ssr-stream.d.ts +1 -7
  84. package/dist/server/app-ssr-stream.js +2 -10
  85. package/dist/server/config-headers.d.ts +24 -0
  86. package/dist/server/config-headers.js +52 -0
  87. package/dist/server/dev-initial-server-error.d.ts +1 -1
  88. package/dist/server/dev-server.js +29 -13
  89. package/dist/server/isr-cache.d.ts +1 -1
  90. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  91. package/dist/server/middleware-matcher-pattern.js +219 -0
  92. package/dist/server/middleware-matcher.d.ts +2 -7
  93. package/dist/server/middleware-matcher.js +13 -60
  94. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  95. package/dist/server/middleware-path-to-regexp.js +228 -0
  96. package/dist/server/middleware-runtime.js +4 -3
  97. package/dist/server/middleware.d.ts +1 -1
  98. package/dist/server/middleware.js +2 -1
  99. package/dist/server/pages-data-route.d.ts +11 -1
  100. package/dist/server/pages-data-route.js +16 -1
  101. package/dist/server/pages-get-initial-props.d.ts +15 -2
  102. package/dist/server/pages-get-initial-props.js +16 -6
  103. package/dist/server/pages-page-data.d.ts +3 -1
  104. package/dist/server/pages-page-data.js +16 -7
  105. package/dist/server/pages-page-handler.d.ts +4 -2
  106. package/dist/server/pages-page-handler.js +16 -17
  107. package/dist/server/pages-page-response.js +1 -1
  108. package/dist/server/pages-readiness.d.ts +3 -3
  109. package/dist/server/pages-request-pipeline.d.ts +1 -0
  110. package/dist/server/pages-request-pipeline.js +25 -11
  111. package/dist/server/pages-router-entry.js +6 -0
  112. package/dist/server/prerender-route-params.js +2 -2
  113. package/dist/server/prod-server.d.ts +1 -4
  114. package/dist/server/prod-server.js +36 -23
  115. package/dist/server/request-pipeline.d.ts +15 -29
  116. package/dist/server/request-pipeline.js +24 -59
  117. package/dist/server/rsc-stream-hints.js +122 -18
  118. package/dist/shims/app.d.ts +1 -1
  119. package/dist/shims/cache-request-state.d.ts +27 -1
  120. package/dist/shims/cache-request-state.js +60 -1
  121. package/dist/shims/cache-runtime.d.ts +12 -1
  122. package/dist/shims/cache-runtime.js +22 -7
  123. package/dist/shims/cache.d.ts +5 -5
  124. package/dist/shims/cache.js +26 -10
  125. package/dist/shims/document.d.ts +42 -83
  126. package/dist/shims/document.js +62 -53
  127. package/dist/shims/dynamic.d.ts +5 -25
  128. package/dist/shims/dynamic.js +29 -8
  129. package/dist/shims/error.d.ts +1 -1
  130. package/dist/shims/error.js +1 -1
  131. package/dist/shims/fetch-cache.js +12 -3
  132. package/dist/shims/font-google-base.d.ts +11 -4
  133. package/dist/shims/font-local.d.ts +10 -3
  134. package/dist/shims/head.d.ts +13 -2
  135. package/dist/shims/head.js +3 -3
  136. package/dist/shims/headers.d.ts +28 -31
  137. package/dist/shims/headers.js +109 -49
  138. package/dist/shims/image.d.ts +27 -37
  139. package/dist/shims/image.js +21 -14
  140. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  141. package/dist/shims/internal/cookie-serialize.js +3 -1
  142. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  143. package/dist/shims/internal/utils.d.ts +3 -3
  144. package/dist/shims/legacy-image.d.ts +3 -37
  145. package/dist/shims/legacy-image.js +6 -16
  146. package/dist/shims/link.d.ts +15 -22
  147. package/dist/shims/link.js +20 -11
  148. package/dist/shims/navigation-context-state.d.ts +1 -1
  149. package/dist/shims/navigation.d.ts +7 -3
  150. package/dist/shims/navigation.js +24 -13
  151. package/dist/shims/navigation.react-server.js +1 -1
  152. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  153. package/dist/shims/next-shims-public.d.ts +1 -0
  154. package/dist/shims/public-shim-map.json.js +103 -0
  155. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  156. package/dist/shims/readonly-url-search-params.js +3 -3
  157. package/dist/shims/request-state-types.d.ts +1 -1
  158. package/dist/shims/router.d.ts +55 -21
  159. package/dist/shims/router.js +162 -37
  160. package/dist/shims/script.d.ts +6 -10
  161. package/dist/shims/script.js +6 -3
  162. package/dist/shims/server.d.ts +45 -22
  163. package/dist/shims/server.js +44 -5
  164. package/dist/shims/unified-request-context.d.ts +1 -1
  165. package/dist/shims/unified-request-context.js +2 -0
  166. package/dist/shims/url-safety.d.ts +1 -1
  167. package/dist/shims/url-safety.js +2 -2
  168. package/dist/typegen.d.ts +8 -2
  169. package/dist/typegen.js +76 -15
  170. package/dist/utils/domain-locale.d.ts +2 -2
  171. package/dist/utils/external-url.d.ts +5 -0
  172. package/dist/utils/external-url.js +7 -0
  173. package/dist/utils/regex-safety.d.ts +8 -0
  174. package/dist/utils/regex-safety.js +737 -0
  175. package/package.json +13 -2
@@ -2,6 +2,7 @@ import { splitPathSegments } from "../routing/utils.js";
2
2
  import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
3
3
  import { parseCookieHeader } from "../utils/parse-cookie.js";
4
4
  import { assertSafeNavigationUrl } from "./url-safety.js";
5
+ import { isExternalUrl } from "../utils/external-url.js";
5
6
  import { isUnknownRecord } from "../utils/record.js";
6
7
  import { AppRouterContext } from "./internal/app-router-context.js";
7
8
  import { RouterContext } from "./internal/router-context.js";
@@ -217,7 +218,8 @@ function getPagesRouterRuntimeComponents() {
217
218
  }
218
219
  function resolveUrl(url) {
219
220
  if (typeof url === "string") return url;
220
- const hasQuery = url.query !== void 0 && Object.keys(url.query).length > 0;
221
+ const query = url.query && typeof url.query === "object" ? url.query : void 0;
222
+ const hasQuery = query !== void 0 && Object.keys(query).length > 0;
221
223
  const hasSearch = typeof url.search === "string" && url.search.length > 0;
222
224
  const hasHash = typeof url.hash === "string" && url.hash.length > 0;
223
225
  const inheritsVisiblePath = url.pathname === void 0 && (hasQuery || hasSearch || hasHash);
@@ -227,7 +229,7 @@ function resolveUrl(url) {
227
229
  const hashIndex = search.indexOf("#");
228
230
  result += hashIndex === -1 ? search : `${search.slice(0, hashIndex)}%23${search.slice(hashIndex + 1)}`;
229
231
  } else if (hasQuery) {
230
- const params = urlQueryToSearchParams(url.query);
232
+ const params = urlQueryToSearchParams(query);
231
233
  result = appendSearchParamsToUrl(result, params);
232
234
  } else if (hasHash && typeof window !== "undefined") result += window.location.search;
233
235
  if (hasHash) result += url.hash.startsWith("#") ? url.hash : `#${url.hash}`;
@@ -245,6 +247,23 @@ function resolveUrl(url) {
245
247
  function resolveNavigationTarget(url, as, locale, replaceExistingLocale = false) {
246
248
  return applyNavigationLocale(as ?? resolveUrl(url), locale, replaceExistingLocale);
247
249
  }
250
+ /**
251
+ * Next.js's internal `_h` replacement receives browser-visible URLs, which may
252
+ * already contain basePath and a locale prefix. Convert those back to app
253
+ * paths before the normal history/data URL builders run; otherwise basePath is
254
+ * added twice and locale-domain routing can turn a same-document hydration
255
+ * update into an external navigation.
256
+ */
257
+ function normalizeHydrationNavigationUrl(url) {
258
+ try {
259
+ const parsed = new URL(url, window.location.href);
260
+ const origin = getWindowOrigin();
261
+ if (!origin || parsed.origin !== origin) return url;
262
+ return stripBasePath(parsed.pathname, __basePath) + parsed.search + parsed.hash;
263
+ } catch {
264
+ return url;
265
+ }
266
+ }
248
267
  var HrefInterpolationError = class extends Error {};
249
268
  function interpolateCurrentDynamicRoute(resolved) {
250
269
  if (typeof window === "undefined") return resolved;
@@ -376,10 +395,6 @@ function getPagesHtmlFetchUrl(browserUrl, locale) {
376
395
  const parsed = new URL(browserUrl, window.location.href);
377
396
  return normalizePathTrailingSlash(toBrowserNavigationHref(`${normalizePathTrailingSlash(`/${locale}`, __trailingSlash)}${parsed.search}${parsed.hash}`, window.location.href, __basePath), __trailingSlash);
378
397
  }
379
- /** Check if a URL is external (any URL scheme per RFC 3986, or protocol-relative) */
380
- function isExternalUrl(url) {
381
- return isAbsoluteOrProtocolRelativeUrl(url);
382
- }
383
398
  /** Resolve a hash URL to a basePath-stripped app URL for event payloads */
384
399
  function resolveHashUrl(url) {
385
400
  if (typeof window === "undefined") return url;
@@ -579,7 +594,7 @@ function getPagesNavigationContext() {
579
594
  return ctx;
580
595
  }
581
596
  if (!isPagesRouterDocumentActive()) return null;
582
- const resolvedPath = stripBasePath(window.location.pathname, __basePath);
597
+ const resolvedPath = removeNavigationLocalePrefix(stripBasePath(window.location.pathname, __basePath));
583
598
  const nextData = window.__NEXT_DATA__;
584
599
  const pattern = resolvePagesRoutePatternForPath(nextData?.page, resolvedPath);
585
600
  if (!pattern) return null;
@@ -626,6 +641,12 @@ function resolvePagesRoutePatternForPath(nextDataPage, resolvedPath) {
626
641
  _cachedPagesRoutePattern = resolved;
627
642
  return resolved;
628
643
  }
644
+ function getSerializedRouteQuery(nextData) {
645
+ const query = {};
646
+ for (const [key, value] of Object.entries(nextData?.query ?? {})) if (typeof value === "string") query[key] = value;
647
+ else if (Array.isArray(value)) query[key] = [...value];
648
+ return query;
649
+ }
629
650
  function extractRouteParamsFromPath(pattern, pathname) {
630
651
  return matchRoutePattern(splitPathSegments(pathname), routePatternParts(pattern));
631
652
  }
@@ -687,6 +708,11 @@ function getPathnameAndQuery() {
687
708
  const canonicalResolvedPath = removeNavigationLocalePrefix(resolvedPath);
688
709
  const pathname = window.__NEXT_DATA__?.page ?? canonicalResolvedPath;
689
710
  const nextData = window.__NEXT_DATA__;
711
+ if (!isPagesRouterReady() && !routerRuntimeState.routerDidNavigate && nextData) return {
712
+ pathname,
713
+ query: getSerializedRouteQuery(nextData),
714
+ asPath: getCurrentHistoryAsPath() ?? canonicalResolvedPath + window.location.search + window.location.hash
715
+ };
690
716
  const routeQuery = getRouteQueryFromNextData(nextData, resolvedPath);
691
717
  const searchQuery = {};
692
718
  const params = new URLSearchParams(window.location.search);
@@ -801,6 +827,7 @@ function cancelPreviousRenderCommit() {
801
827
  routerRuntimeState.cancelPendingRenderCommit = null;
802
828
  }
803
829
  function scheduleHardNavigationAndThrow(url, message) {
830
+ assertSafeNavigationUrl(url, HardNavigationScheduledError);
804
831
  if (typeof window === "undefined") throw new HardNavigationScheduledError(message);
805
832
  window.location.href = url;
806
833
  throw new HardNavigationScheduledError(message);
@@ -888,7 +915,7 @@ async function resolveClientConfigRedirect(href) {
888
915
  if (!redirects || redirects.length === 0) return null;
889
916
  const routeContext = getClientConfigRouteContext(href);
890
917
  if (!routeContext) return null;
891
- const { isExternalUrl, matchRedirect, preserveRedirectDestinationQuery } = await import("../config/config-matchers.js");
918
+ const { matchRedirect, preserveRedirectDestinationQuery } = await import("../config/config-matchers.js");
892
919
  const redirect = matchRedirect(routeContext.pathname, redirects, routeContext.context, routeContext.basePathState);
893
920
  if (!redirect) return null;
894
921
  return preserveRedirectDestinationQuery(__basePath && routeContext.basePathState.hadBasePath && !isExternalUrl(redirect.destination) && !hasBasePath(redirect.destination, __basePath) ? __basePath + redirect.destination : redirect.destination, routeContext.search);
@@ -896,7 +923,7 @@ async function resolveClientConfigRedirect(href) {
896
923
  async function applyClientConfigRewrite(href, rewrite) {
897
924
  const routeContext = getClientConfigRouteContext(href);
898
925
  if (!routeContext) return null;
899
- const { isExternalUrl, matchRewrite } = await import("../config/config-matchers.js");
926
+ const { matchRewrite } = await import("../config/config-matchers.js");
900
927
  const rewritten = matchRewrite(routeContext.pathname, [rewrite], routeContext.context, routeContext.basePathState);
901
928
  if (rewritten === null) return null;
902
929
  if (isExternalUrl(rewritten)) return { kind: "document" };
@@ -1111,13 +1138,13 @@ async function loadComponentOnlyProps(PageComponent, AppComponent, target, asPat
1111
1138
  const AppTree = (appProps) => createElement(AppComponent, {
1112
1139
  ...appProps,
1113
1140
  Component: PageComponent,
1114
- router: Router
1141
+ router: singletonRouter
1115
1142
  });
1116
1143
  return propsObject(await AppComponent.getInitialProps({
1117
1144
  Component: PageComponent,
1118
1145
  AppTree,
1119
1146
  ctx,
1120
- router: Router
1147
+ router: singletonRouter
1121
1148
  }));
1122
1149
  }
1123
1150
  if (typeof PageComponent.getInitialProps === "function") return { pageProps: propsObject(await PageComponent.getInitialProps(ctx)) };
@@ -1139,7 +1166,7 @@ async function renderPagesNavigationTarget(url, target, props, options, assertSt
1139
1166
  ...props,
1140
1167
  Component: PageComponent,
1141
1168
  pageProps: rawPageProps,
1142
- router: Router
1169
+ router: singletonRouter
1143
1170
  });
1144
1171
  else element = React.createElement(PageComponent, pageProps);
1145
1172
  const nextData = buildPagesNavigationNextData(target, props);
@@ -1194,7 +1221,7 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
1194
1221
  };
1195
1222
  const deploymentId = getDeploymentId();
1196
1223
  if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
1197
- res = await (initialTarget.dataKind === "static" && Router.isPreview !== true ? fetchStaticPagesData : dedupedPagesDataFetch)(initialTarget.dataHref, {
1224
+ res = await (initialTarget.dataKind === "static" && singletonRouter.isPreview !== true ? fetchStaticPagesData : dedupedPagesDataFetch)(initialTarget.dataHref, {
1198
1225
  headers,
1199
1226
  signal: controller.signal
1200
1227
  });
@@ -1235,7 +1262,7 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
1235
1262
  const rawPageProps = props.pageProps;
1236
1263
  const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
1237
1264
  if (initialTarget.dataKind === "server") evictPagesDataCache(initialTarget.dataHref);
1238
- if (props.__N_PREVIEW === true || Router.isPreview === true) evictPagesDataCache(initialTarget.dataHref);
1265
+ if (props.__N_PREVIEW === true || singletonRouter.isPreview === true) evictPagesDataCache(initialTarget.dataHref);
1239
1266
  const redirectDestination = pageProps.__N_REDIRECT;
1240
1267
  if (typeof redirectDestination === "string") {
1241
1268
  handleDataRedirect(redirectDestination, pageProps.__N_REDIRECT_BASE_PATH, options.mode);
@@ -1329,7 +1356,7 @@ async function navigateClientHtml(url, fetchUrl, controller, navId, assertStillC
1329
1356
  ...props,
1330
1357
  Component: PageComponent,
1331
1358
  pageProps: rawPageProps,
1332
- router: Router
1359
+ router: singletonRouter
1333
1360
  });
1334
1361
  else element = React.createElement(PageComponent, pageProps);
1335
1362
  if (pendingRedirectHistoryUrl) {
@@ -1488,6 +1515,7 @@ function buildRouterValue(pathname, query, asPath, isReady, methods) {
1488
1515
  locales,
1489
1516
  defaultLocale,
1490
1517
  domainLocales,
1518
+ isLocaleDomain: typeof window !== "undefined" && domainLocales?.some((domain) => domain.domain === window.location.hostname) === true,
1491
1519
  isReady,
1492
1520
  isPreview: typeof window !== "undefined" ? nextData?.isPreview === true : _ssrState?.isPreview === true,
1493
1521
  isFallback: typeof window !== "undefined" ? nextData?.isFallback === true : _ssrState?.isFallback === true,
@@ -1577,11 +1605,12 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1577
1605
  if (typeof window === "undefined") throwNoRouterInstance();
1578
1606
  assertSafeNavigationUrl(resolveUrl(url));
1579
1607
  if (as !== void 0) assertSafeNavigationUrl(String(as));
1608
+ const isHydrationQueryUpdate = options?._h === 1;
1580
1609
  const navigationLocale = resolveTransitionLocale(options?.locale);
1581
- const replaceInheritedLocale = 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);
1582
- let resolved = resolveNavigationTarget(url, as, navigationLocale, replaceInheritedLocale);
1583
- let resolvedRoute = applyNavigationLocale(resolveUrl(url), navigationLocale, replaceInheritedLocale);
1584
- 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))) {
1610
+ const replaceInheritedLocale = as === void 0 && options?.locale !== void 0 && typeof url !== "string" && url.pathname === void 0 && (url.query !== null && typeof url.query === "object" && Object.keys(url.query).length > 0 || typeof url.search === "string" && url.search.length > 0 || typeof url.hash === "string" && url.hash.length > 0);
1611
+ let resolved = isHydrationQueryUpdate ? normalizeHydrationNavigationUrl(as ?? resolveUrl(url)) : resolveNavigationTarget(url, as, navigationLocale, replaceInheritedLocale);
1612
+ let resolvedRoute = isHydrationQueryUpdate ? normalizeHydrationNavigationUrl(resolveUrl(url)) : applyNavigationLocale(resolveUrl(url), navigationLocale, replaceInheritedLocale);
1613
+ if (as === void 0 && (typeof url === "string" && options?._vinextInterpolateDynamicRoute === true || typeof url !== "string" && url.pathname === void 0 && (url.query !== null && typeof url.query === "object" && Object.keys(url.query).length > 0 || typeof url.search === "string" && url.search.length > 0))) {
1585
1614
  resolved = interpolateCurrentDynamicRoute(resolved);
1586
1615
  resolvedRoute = interpolateCurrentDynamicRoute(resolvedRoute);
1587
1616
  }
@@ -1602,7 +1631,7 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
1602
1631
  resolvedRoute = normalizePathTrailingSlash(resolvedRoute, __trailingSlash);
1603
1632
  let interpolatedRoute = resolvedRoute;
1604
1633
  if (resolvedRoute.includes("[")) {
1605
- const projection = interpolateDynamicRouteHref(resolvedRoute, resolved, typeof url === "string" ? void 0 : url.query);
1634
+ const projection = interpolateDynamicRouteHref(resolvedRoute, resolved, typeof url === "string" || !url.query || typeof url.query === "string" ? void 0 : url.query);
1606
1635
  if (projection?.href) {
1607
1636
  interpolatedRoute = projection.href;
1608
1637
  if (as === void 0 && stripHash(resolved).split("?", 1)[0] === projection.routePathname) {
@@ -1742,7 +1771,7 @@ async function prefetchUrl(url, as) {
1742
1771
  function useRouter() {
1743
1772
  const router = useContext(RouterContext);
1744
1773
  if (router) return router;
1745
- if (typeof window !== "undefined" && window.__VINEXT_PAGE_LOADERS__ !== void 0) return Router;
1774
+ if (typeof window !== "undefined" && window.__VINEXT_PAGE_LOADERS__ !== void 0) return singletonRouter;
1746
1775
  throw new Error("NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted");
1747
1776
  }
1748
1777
  function PagesRouterProvider({ children }) {
@@ -1767,12 +1796,13 @@ function PagesRouterProvider({ children }) {
1767
1796
  };
1768
1797
  }, []);
1769
1798
  const router = useMemo(() => buildRouterValue(pathname, query, asPath, isReady, {
1770
- push: Router.push,
1771
- replace: Router.replace,
1772
- back: Router.back,
1773
- reload: Router.reload,
1774
- prefetch: Router.prefetch,
1775
- beforePopState: Router.beforePopState
1799
+ push: singletonRouter.push,
1800
+ replace: singletonRouter.replace,
1801
+ back: singletonRouter.back,
1802
+ forward: singletonRouter.forward,
1803
+ reload: singletonRouter.reload,
1804
+ prefetch: singletonRouter.prefetch,
1805
+ beforePopState: singletonRouter.beforePopState
1776
1806
  }), [
1777
1807
  pathname,
1778
1808
  query,
@@ -1782,23 +1812,23 @@ function PagesRouterProvider({ children }) {
1782
1812
  const appRouter = useMemo(() => ({
1783
1813
  bfcacheId: "0",
1784
1814
  back() {
1785
- Router.back();
1815
+ singletonRouter.back();
1786
1816
  },
1787
1817
  forward() {
1788
1818
  if (typeof window === "undefined") throwNoRouterInstance();
1789
1819
  window.history.forward();
1790
1820
  },
1791
1821
  refresh() {
1792
- Router.reload();
1822
+ singletonRouter.reload();
1793
1823
  },
1794
1824
  push(href, options) {
1795
- Router.push(href, void 0, { scroll: options?.scroll });
1825
+ singletonRouter.push(href, void 0, { scroll: options?.scroll });
1796
1826
  },
1797
1827
  replace(href, options) {
1798
- Router.replace(href, void 0, { scroll: options?.scroll });
1828
+ singletonRouter.replace(href, void 0, { scroll: options?.scroll });
1799
1829
  },
1800
1830
  prefetch(href) {
1801
- Router.prefetch(href);
1831
+ singletonRouter.prefetch(href);
1802
1832
  }
1803
1833
  }), []);
1804
1834
  const content = createElement(RouterContext.Provider, { value: router }, createElement(Fragment, null, children, createElement(PagesRouterHydrationMarker)));
@@ -1941,6 +1971,11 @@ function withRouter(ComposedComponent) {
1941
1971
  return WithRouterWrapper;
1942
1972
  }
1943
1973
  const RouterMethods = {
1974
+ router: null,
1975
+ readyCallbacks: [],
1976
+ ready(callback) {
1977
+ callback();
1978
+ },
1944
1979
  /** See `_components` comment above for the dual role this map plays. */
1945
1980
  components: getPagesRouterComponentsMap(),
1946
1981
  sdc: getPagesStaticDataCache(),
@@ -1960,6 +1995,10 @@ const RouterMethods = {
1960
1995
  if (typeof window === "undefined") throwNoRouterInstance();
1961
1996
  window.history.back();
1962
1997
  },
1998
+ forward: () => {
1999
+ if (typeof window === "undefined") throwNoRouterInstance();
2000
+ window.history.forward();
2001
+ },
1963
2002
  reload: () => {
1964
2003
  if (typeof window === "undefined") throwNoRouterInstance();
1965
2004
  window.location.reload();
@@ -1974,7 +2013,7 @@ const RouterMethods = {
1974
2013
  },
1975
2014
  events: routerEvents
1976
2015
  };
1977
- const Router = Object.defineProperties(RouterMethods, {
2016
+ const singletonRouter = Object.defineProperties(RouterMethods, {
1978
2017
  pathname: {
1979
2018
  enumerable: true,
1980
2019
  get() {
@@ -2034,6 +2073,14 @@ const Router = Object.defineProperties(RouterMethods, {
2034
2073
  return window.__NEXT_DATA__?.domainLocales;
2035
2074
  }
2036
2075
  },
2076
+ isLocaleDomain: {
2077
+ enumerable: true,
2078
+ get() {
2079
+ const domainLocales = typeof window === "undefined" ? _getSSRContext()?.domainLocales : window.__NEXT_DATA__?.domainLocales;
2080
+ if (!domainLocales || typeof window === "undefined") return false;
2081
+ return domainLocales.some((domain) => domain.domain === window.location.hostname);
2082
+ }
2083
+ },
2037
2084
  isReady: {
2038
2085
  enumerable: true,
2039
2086
  get() {
@@ -2055,7 +2102,7 @@ const Router = Object.defineProperties(RouterMethods, {
2055
2102
  }
2056
2103
  }
2057
2104
  });
2058
- routerRuntimeState.publicRouter = Router;
2105
+ routerRuntimeState.publicRouter = singletonRouter;
2059
2106
  const deprecatedRouterEvents = [
2060
2107
  "routeChangeStart",
2061
2108
  "beforeHistoryChange",
@@ -2069,7 +2116,7 @@ if (!routerRuntimeState.deprecatedEventBridgeInstalled) {
2069
2116
  for (const event of deprecatedRouterEvents) {
2070
2117
  const eventField = `on${event.charAt(0).toUpperCase()}${event.substring(1)}`;
2071
2118
  routerEvents.on(event, (...args) => {
2072
- const handler = (routerRuntimeState.publicRouter ?? Router)[eventField];
2119
+ const handler = (routerRuntimeState.publicRouter ?? singletonRouter)[eventField];
2073
2120
  if (typeof handler === "function") try {
2074
2121
  handler(...args);
2075
2122
  } catch (err) {
@@ -2081,9 +2128,87 @@ if (!routerRuntimeState.deprecatedEventBridgeInstalled) {
2081
2128
  }
2082
2129
  if (typeof window !== "undefined") {
2083
2130
  installPagesRouterRuntime();
2084
- installWindowNext({ router: Router });
2131
+ installWindowNext({ router: singletonRouter });
2085
2132
  }
2086
2133
  const _PAGES_NAVIGATION_ACCESSOR_KEY = Symbol.for("vinext.navigation.pagesNavigationContextAccessor");
2087
2134
  globalThis[_PAGES_NAVIGATION_ACCESSOR_KEY] = getPagesNavigationContext;
2135
+ /**
2136
+ * Constructible named export matching `next/router`'s Router class surface.
2137
+ * Vinext owns one browser history runtime, so instances delegate to that
2138
+ * shared runtime while preserving the class/static-events API used by apps.
2139
+ */
2140
+ var Router = class {
2141
+ static events = routerEvents;
2142
+ constructor(..._args) {}
2143
+ get route() {
2144
+ return singletonRouter.route;
2145
+ }
2146
+ get pathname() {
2147
+ return singletonRouter.pathname;
2148
+ }
2149
+ get query() {
2150
+ return singletonRouter.query;
2151
+ }
2152
+ get asPath() {
2153
+ return singletonRouter.asPath;
2154
+ }
2155
+ get basePath() {
2156
+ return singletonRouter.basePath;
2157
+ }
2158
+ get locale() {
2159
+ return singletonRouter.locale;
2160
+ }
2161
+ get locales() {
2162
+ return singletonRouter.locales;
2163
+ }
2164
+ get defaultLocale() {
2165
+ return singletonRouter.defaultLocale;
2166
+ }
2167
+ get domainLocales() {
2168
+ return singletonRouter.domainLocales;
2169
+ }
2170
+ get isLocaleDomain() {
2171
+ return singletonRouter.isLocaleDomain;
2172
+ }
2173
+ get isReady() {
2174
+ return singletonRouter.isReady;
2175
+ }
2176
+ get isPreview() {
2177
+ return singletonRouter.isPreview;
2178
+ }
2179
+ get isFallback() {
2180
+ return singletonRouter.isFallback;
2181
+ }
2182
+ get events() {
2183
+ return singletonRouter.events;
2184
+ }
2185
+ get components() {
2186
+ return singletonRouter.components;
2187
+ }
2188
+ get sdc() {
2189
+ return singletonRouter.sdc;
2190
+ }
2191
+ push(url, as, options) {
2192
+ return singletonRouter.push(url, as, options);
2193
+ }
2194
+ replace(url, as, options) {
2195
+ return singletonRouter.replace(url, as, options);
2196
+ }
2197
+ reload() {
2198
+ singletonRouter.reload();
2199
+ }
2200
+ back() {
2201
+ singletonRouter.back();
2202
+ }
2203
+ forward() {
2204
+ singletonRouter.forward();
2205
+ }
2206
+ prefetch(url, as) {
2207
+ return singletonRouter.prefetch(url, as);
2208
+ }
2209
+ beforePopState(cb) {
2210
+ singletonRouter.beforePopState(cb);
2211
+ }
2212
+ };
2088
2213
  //#endregion
2089
- export { initializePagesRouterReadyFromNextData as _initializePagesRouterReadyFromNextData, markPagesRouterReady as _markPagesRouterReady, _registerRouterStateAccessors, applyNavigationLocale, Router as default, getPagesNavigationContext, getPagesNavigationIsReadyFromSerializedState, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
2214
+ export { Router, initializePagesRouterReadyFromNextData as _initializePagesRouterReadyFromNextData, markPagesRouterReady as _markPagesRouterReady, _registerRouterStateAccessors, applyNavigationLocale, singletonRouter as default, getPagesNavigationContext, getPagesNavigationIsReadyFromSerializedState, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
@@ -1,21 +1,18 @@
1
1
  import React from "react";
2
2
 
3
3
  //#region src/shims/script.d.ts
4
- type ScriptProps = {
4
+ type ScriptProps = React.ScriptHTMLAttributes<HTMLScriptElement> & {
5
5
  /** Script source URL */src?: string; /** Loading strategy. Default: "afterInteractive" */
6
6
  strategy?: "beforeInteractive" | "afterInteractive" | "lazyOnload" | "worker"; /** Unique identifier for the script */
7
7
  id?: string; /** Called when the script has loaded */
8
- onLoad?: (e: Event) => void; /** Called when the script is ready (after load, and on every re-render if already loaded) */
8
+ onLoad?: (e: unknown) => void; /** Called when the script is ready (after load, and on every re-render if already loaded) */
9
9
  onReady?: () => void; /** Called on script load error */
10
- onError?: (e: Event) => void; /** Inline script content */
11
- children?: React.ReactNode; /** Dangerous inner HTML */
12
- dangerouslySetInnerHTML?: {
13
- __html: string;
14
- }; /** Script type attribute */
10
+ onError?: (e: unknown) => void; /** Inline script content */
11
+ children?: React.ReactNode; /** Script type attribute */
15
12
  type?: string; /** Async attribute */
16
13
  async?: boolean; /** Defer attribute */
17
14
  defer?: boolean; /** Crossorigin attribute */
18
- crossOrigin?: string; /** Nonce for CSP */
15
+ crossOrigin?: React.ScriptHTMLAttributes<HTMLScriptElement>["crossOrigin"]; /** Nonce for CSP */
19
16
  nonce?: string; /** Integrity hash */
20
17
  integrity?: string;
21
18
  /**
@@ -27,8 +24,7 @@ type ScriptProps = {
27
24
  * `.nextjs-ref/packages/next/src/client/script.tsx` (`insertStylesheets`
28
25
  * and the `appDir` block).
29
26
  */
30
- stylesheets?: string[]; /** Additional attributes */
31
- [key: string]: unknown;
27
+ stylesheets?: string[];
32
28
  };
33
29
  /**
34
30
  * Load a script imperatively (outside of React).
@@ -78,9 +78,12 @@ function buildBeforeInteractiveScriptProps(options) {
78
78
  if (options.src) scriptProps.src = options.src;
79
79
  if (options.id) scriptProps.id = options.id;
80
80
  if (options.resolvedNonce) scriptProps.nonce = options.resolvedNonce;
81
- if (options.dangerouslySetInnerHTML) scriptProps.dangerouslySetInnerHTML = { __html: escapeInlineContent(options.dangerouslySetInnerHTML.__html, "script") };
81
+ if (options.dangerouslySetInnerHTML) scriptProps.dangerouslySetInnerHTML = { __html: escapeInlineContent(stringifyInlineContent(options.dangerouslySetInnerHTML.__html), "script") };
82
82
  return scriptProps;
83
83
  }
84
+ function stringifyInlineContent(value) {
85
+ return String(value);
86
+ }
84
87
  /**
85
88
  * Extract the inline script content for a `beforeInteractive` Script element
86
89
  * with no `src`. Returns `null` when the element has neither a string-shaped
@@ -93,7 +96,7 @@ function buildBeforeInteractiveScriptProps(options) {
93
96
  * to the emit point so the rule is obvious at the boundary).
94
97
  */
95
98
  function extractBeforeInteractiveInlineContent(children, dangerouslySetInnerHTML) {
96
- if (dangerouslySetInnerHTML && typeof dangerouslySetInnerHTML.__html === "string" && dangerouslySetInnerHTML.__html.length > 0) return dangerouslySetInnerHTML.__html;
99
+ if (dangerouslySetInnerHTML && stringifyInlineContent(dangerouslySetInnerHTML.__html).length > 0) return stringifyInlineContent(dangerouslySetInnerHTML.__html);
97
100
  if (typeof children === "string" && children.length > 0) return children;
98
101
  if (Array.isArray(children) && children.every((c) => typeof c === "string")) {
99
102
  const joined = children.join("");
@@ -220,7 +223,7 @@ function loadClientScript(props, options) {
220
223
  onReady?.();
221
224
  };
222
225
  if (dangerouslySetInnerHTML?.__html) {
223
- el.innerHTML = dangerouslySetInnerHTML.__html;
226
+ el.innerHTML = stringifyInlineContent(dangerouslySetInnerHTML.__html);
224
227
  markLoaded();
225
228
  } else if (children && typeof children === "string") {
226
229
  el.textContent = children;
@@ -9,28 +9,36 @@
9
9
  * This is a pragmatic subset — we implement the most commonly used APIs
10
10
  * rather than bug-for-bug parity with Next.js internals.
11
11
  */
12
+ /** @deprecated Import ImageResponse from `next/og` instead. */
13
+ declare function ImageResponse(): never;
14
+ type RequestInit = globalThis.RequestInit & {
15
+ nextConfig?: {
16
+ basePath?: string;
17
+ i18n?: {
18
+ locales: readonly string[];
19
+ defaultLocale: string;
20
+ domains?: ReadonlyArray<{
21
+ domain: string;
22
+ defaultLocale: string;
23
+ locales?: readonly string[];
24
+ http?: true;
25
+ }>;
26
+ } | null;
27
+ trailingSlash?: boolean;
28
+ };
29
+ signal?: AbortSignal;
30
+ duplex?: "half";
31
+ };
12
32
  declare class NextRequest extends Request {
13
33
  private _nextUrl;
14
34
  private _url;
15
35
  private _cookies;
16
- constructor(input: URL | RequestInfo, init?: RequestInit & {
17
- nextConfig?: {
18
- basePath?: string;
19
- i18n?: {
20
- locales: string[];
21
- defaultLocale: string;
22
- domains?: Array<{
23
- domain: string;
24
- defaultLocale: string;
25
- locales?: string[];
26
- }>;
27
- };
28
- trailingSlash?: boolean;
29
- };
30
- });
36
+ constructor(input: URL | RequestInfo, init?: RequestInit);
31
37
  get nextUrl(): NextURL;
32
38
  get url(): string;
33
39
  get cookies(): RequestCookies;
40
+ get page(): void;
41
+ get ua(): void;
34
42
  /**
35
43
  * Client IP address. Prefers Cloudflare's trusted CF-Connecting-IP header
36
44
  * over the spoofable X-Forwarded-For. Returns undefined if unavailable.
@@ -65,12 +73,16 @@ declare class NextResponse<_Body = unknown> extends Response {
65
73
  /**
66
74
  * Create a redirect response.
67
75
  */
68
- static redirect(url: string | URL | NextURL, init?: number | ResponseInit): NextResponse;
76
+ static redirect(url: string | URL | {
77
+ toString(): string;
78
+ }, init?: number | ResponseInit): NextResponse;
69
79
  /**
70
80
  * Create a rewrite response (middleware pattern).
71
81
  * Sets the x-middleware-rewrite header.
72
82
  */
73
- static rewrite(destination: string | URL | NextURL, init?: MiddlewareResponseInit): NextResponse;
83
+ static rewrite(destination: string | URL | {
84
+ toString(): string;
85
+ }, init?: MiddlewareResponseInit): NextResponse;
74
86
  /**
75
87
  * Continue to the next handler (middleware pattern).
76
88
  * Sets the x-middleware-next header.
@@ -176,6 +188,7 @@ declare class NextURL {
176
188
  get locales(): string[] | undefined;
177
189
  clone(): NextURL;
178
190
  toString(): string;
191
+ toJSON(): string;
179
192
  /**
180
193
  * The build ID of the Next.js application.
181
194
  * Set from `generateBuildId` in next.config.js, or a random UUID if not configured.
@@ -202,7 +215,7 @@ declare class RequestCookies {
202
215
  toString(): string;
203
216
  private _serialize;
204
217
  private _syncHeader;
205
- [Symbol.iterator](): IterableIterator<[string, CookieEntry]>;
218
+ [Symbol.iterator](): MapIterator<[string, CookieEntry]>;
206
219
  }
207
220
  declare function sealRequestHeaders(headers: Headers): Headers;
208
221
  declare function sealRequestCookies(cookies: RequestCookies): RequestCookies;
@@ -225,7 +238,7 @@ declare class ResponseCookies {
225
238
  delete(...args: [name: string] | [options: Omit<CookieOptions & {
226
239
  name: string;
227
240
  }, "maxAge" | "expires">]): this;
228
- [Symbol.iterator](): IterableIterator<[string, CookieEntry]>;
241
+ [Symbol.iterator](): MapIterator<[string, CookieEntry]>;
229
242
  /** Delete all Set-Cookie headers and re-append from the internal map. */
230
243
  private _syncHeaders;
231
244
  }
@@ -233,10 +246,12 @@ type CookieOptions = {
233
246
  path?: string;
234
247
  domain?: string;
235
248
  maxAge?: number;
236
- expires?: Date;
249
+ expires?: Date | number;
237
250
  httpOnly?: boolean;
238
251
  secure?: boolean;
239
- sameSite?: "Strict" | "Lax" | "None";
252
+ sameSite?: true | false | "strict" | "lax" | "none" | "Strict" | "Lax" | "None";
253
+ partitioned?: boolean;
254
+ priority?: "low" | "medium" | "high";
240
255
  };
241
256
  type MiddlewareResponseInit = {
242
257
  request?: {
@@ -253,8 +268,16 @@ declare class NextFetchEvent {
253
268
  sourcePage: string;
254
269
  private _waitUntilPromises;
255
270
  constructor(params: {
271
+ request?: Request;
256
272
  page: string;
273
+ context?: {
274
+ waitUntil(promise: Promise<unknown>): void;
275
+ };
257
276
  });
277
+ private _externalWaitUntil?;
278
+ get request(): void;
279
+ respondWith(): void;
280
+ passThroughOnException(): void;
258
281
  waitUntil(promise: Promise<unknown>): void;
259
282
  get waitUntilPromises(): Promise<unknown>[];
260
283
  /** Drain all waitUntil promises. Returns a single promise that settles when all are done. */
@@ -320,4 +343,4 @@ declare function connection(): Promise<void>;
320
343
  */
321
344
  declare const URLPattern: typeof globalThis.URLPattern;
322
345
  //#endregion
323
- export { MiddlewareResponseInit, NextFetchEvent, NextMiddleware, NextMiddlewareResult, NextRequest, NextResponse, NextURL, NextURLConfig, RequestCookies, ResponseCookies, URLPattern, UserAgent, after, connection, sealRequestCookies, sealRequestHeaders, userAgent, userAgentFromString };
346
+ export { ImageResponse, MiddlewareResponseInit, NextFetchEvent, NextMiddleware, NextMiddlewareResult, NextRequest, NextResponse, NextURL, NextURLConfig, RequestCookies, RequestInit, ResponseCookies, URLPattern, UserAgent, after, connection, sealRequestCookies, sealRequestHeaders, userAgent, userAgentFromString };