vinext 1.0.0-beta.2 → 1.0.0-beta.3

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 (126) hide show
  1. package/README.md +6 -9
  2. package/dist/build/client-build-config.js +7 -1
  3. package/dist/check.js +4 -0
  4. package/dist/config/config-matchers.js +4 -1
  5. package/dist/config/next-config.d.ts +12 -3
  6. package/dist/config/next-config.js +4 -0
  7. package/dist/entries/app-browser-entry.d.ts +4 -10
  8. package/dist/entries/app-browser-entry.js +20 -4
  9. package/dist/entries/app-rsc-entry.js +3 -0
  10. package/dist/entries/app-rsc-manifest.js +19 -0
  11. package/dist/entries/pages-client-entry.js +0 -1
  12. package/dist/entries/pages-server-entry.js +10 -3
  13. package/dist/index.js +112 -43
  14. package/dist/init-cloudflare.d.ts +3 -1
  15. package/dist/init-cloudflare.js +59 -5
  16. package/dist/plugins/extensionless-dynamic-import.js +23 -18
  17. package/dist/plugins/ignore-dynamic-requests.js +3 -1
  18. package/dist/plugins/import-meta-url.js +17 -6
  19. package/dist/plugins/require-context.js +20 -15
  20. package/dist/plugins/transform-cache.d.ts +19 -0
  21. package/dist/plugins/transform-cache.js +36 -0
  22. package/dist/routing/app-route-graph.d.ts +14 -6
  23. package/dist/routing/app-route-graph.js +106 -16
  24. package/dist/server/api-handler.d.ts +2 -0
  25. package/dist/server/api-handler.js +3 -3
  26. package/dist/server/app-browser-entry.js +103 -31
  27. package/dist/server/app-browser-navigation-controller.d.ts +23 -21
  28. package/dist/server/app-browser-navigation-controller.js +1 -1
  29. package/dist/server/app-page-cache-finalizer.js +1 -1
  30. package/dist/server/app-page-cache.d.ts +1 -1
  31. package/dist/server/app-page-cache.js +16 -2
  32. package/dist/server/app-page-dispatch.d.ts +8 -0
  33. package/dist/server/app-page-dispatch.js +31 -6
  34. package/dist/server/app-page-element-builder.d.ts +2 -0
  35. package/dist/server/app-page-element-builder.js +33 -7
  36. package/dist/server/app-page-head.d.ts +3 -3
  37. package/dist/server/app-page-head.js +58 -13
  38. package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -2
  39. package/dist/server/app-page-http-access-fallback-metadata.js +9 -1
  40. package/dist/server/app-page-probe.d.ts +4 -0
  41. package/dist/server/app-page-probe.js +6 -2
  42. package/dist/server/app-page-request.d.ts +3 -0
  43. package/dist/server/app-page-request.js +1 -1
  44. package/dist/server/app-page-response.js +1 -1
  45. package/dist/server/app-page-route-wiring.d.ts +7 -0
  46. package/dist/server/app-page-route-wiring.js +211 -49
  47. package/dist/server/app-pages-bridge.d.ts +1 -1
  48. package/dist/server/app-pages-bridge.js +2 -1
  49. package/dist/server/app-route-handler-cache.js +4 -0
  50. package/dist/server/app-route-handler-dispatch.js +9 -3
  51. package/dist/server/app-route-handler-response.js +1 -1
  52. package/dist/server/app-route-module-loader.d.ts +6 -0
  53. package/dist/server/app-route-module-loader.js +3 -0
  54. package/dist/server/app-router-entry.js +6 -3
  55. package/dist/server/app-rsc-errors.js +10 -0
  56. package/dist/server/app-rsc-handler.js +21 -9
  57. package/dist/server/app-rsc-route-matching.d.ts +9 -0
  58. package/dist/server/app-rsc-route-matching.js +6 -0
  59. package/dist/server/app-ssr-entry.js +4 -4
  60. package/dist/server/cache-control.d.ts +2 -2
  61. package/dist/server/cache-control.js +2 -1
  62. package/dist/server/dev-server.d.ts +3 -1
  63. package/dist/server/dev-server.js +145 -312
  64. package/dist/server/headers.d.ts +2 -2
  65. package/dist/server/headers.js +4 -3
  66. package/dist/server/isr-cache.d.ts +10 -33
  67. package/dist/server/isr-cache.js +33 -43
  68. package/dist/server/isr-decision.d.ts +2 -2
  69. package/dist/server/pages-api-route.d.ts +2 -0
  70. package/dist/server/pages-api-route.js +4 -1
  71. package/dist/server/pages-dev-hydration.js +0 -1
  72. package/dist/server/pages-get-initial-props.d.ts +1 -1
  73. package/dist/server/pages-get-initial-props.js +1 -4
  74. package/dist/server/pages-i18n.js +64 -16
  75. package/dist/server/pages-node-compat.d.ts +2 -0
  76. package/dist/server/pages-node-compat.js +7 -3
  77. package/dist/server/pages-page-data.d.ts +61 -9
  78. package/dist/server/pages-page-data.js +334 -74
  79. package/dist/server/pages-page-handler.d.ts +5 -1
  80. package/dist/server/pages-page-handler.js +115 -19
  81. package/dist/server/pages-page-response.d.ts +5 -3
  82. package/dist/server/pages-page-response.js +23 -26
  83. package/dist/server/pages-request-pipeline.d.ts +7 -0
  84. package/dist/server/pages-request-pipeline.js +5 -1
  85. package/dist/server/pages-revalidate.d.ts +1 -1
  86. package/dist/server/pages-revalidate.js +54 -8
  87. package/dist/server/pages-router-entry.d.ts +1 -0
  88. package/dist/server/pages-router-entry.js +10 -4
  89. package/dist/server/prod-server.d.ts +2 -1
  90. package/dist/server/prod-server.js +37 -13
  91. package/dist/server/revalidation-host.d.ts +11 -0
  92. package/dist/server/revalidation-host.js +19 -0
  93. package/dist/server/worker-revalidation-context.d.ts +13 -0
  94. package/dist/server/worker-revalidation-context.js +29 -0
  95. package/dist/shims/cache-handler.d.ts +1 -1
  96. package/dist/shims/cache-handler.js +10 -7
  97. package/dist/shims/cache-runtime.d.ts +6 -0
  98. package/dist/shims/cache-runtime.js +4 -1
  99. package/dist/shims/cache.js +1 -1
  100. package/dist/shims/error.js +1 -1
  101. package/dist/shims/fetch-cache.js +1 -1
  102. package/dist/shims/font-google-base.js +17 -8
  103. package/dist/shims/font-local.js +41 -10
  104. package/dist/shims/headers.d.ts +10 -13
  105. package/dist/shims/headers.js +85 -36
  106. package/dist/shims/internal/cookie-serialize.d.ts +10 -9
  107. package/dist/shims/internal/cookie-serialize.js +9 -8
  108. package/dist/shims/internal/interpolate-as.d.ts +15 -1
  109. package/dist/shims/internal/interpolate-as.js +27 -2
  110. package/dist/shims/link.js +18 -6
  111. package/dist/shims/metadata.d.ts +7 -17
  112. package/dist/shims/metadata.js +74 -24
  113. package/dist/shims/navigation.js +1 -1
  114. package/dist/shims/request-context.d.ts +4 -1
  115. package/dist/shims/router.js +18 -7
  116. package/dist/shims/script.js +1 -1
  117. package/dist/shims/server.d.ts +7 -6
  118. package/dist/shims/server.js +156 -57
  119. package/dist/shims/unified-request-context.d.ts +21 -2
  120. package/dist/shims/unified-request-context.js +82 -1
  121. package/dist/utils/cache-control-metadata.d.ts +2 -1
  122. package/dist/utils/cache-control-metadata.js +5 -1
  123. package/dist/utils/html-limited-bots.js +1 -1
  124. package/dist/utils/protocol-headers.d.ts +7 -1
  125. package/dist/utils/protocol-headers.js +7 -1
  126. package/package.json +1 -1
package/README.md CHANGED
@@ -345,24 +345,16 @@ Requires a custom domain (zone analytics are unavailable on `*.workers.dev`) and
345
345
 
346
346
  #### Custom Vite configuration
347
347
 
348
- If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. This is required for Cloudflare Workers deployment with the App Router (RSC needs explicit plugin configuration):
348
+ If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. For Cloudflare Workers deployment with the App Router, configure `@cloudflare/vite-plugin` so the RSC environment runs in workerd:
349
349
 
350
350
  ```ts
351
351
  import { defineConfig } from "vite";
352
352
  import vinext from "vinext";
353
- import rsc from "@vitejs/plugin-rsc";
354
353
  import { cloudflare } from "@cloudflare/vite-plugin";
355
354
 
356
355
  export default defineConfig({
357
356
  plugins: [
358
357
  vinext(),
359
- rsc({
360
- entries: {
361
- rsc: "virtual:vinext-rsc-entry",
362
- ssr: "virtual:vinext-app-ssr-entry",
363
- client: "virtual:vinext-app-browser-entry",
364
- },
365
- }),
366
358
  cloudflare({
367
359
  viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
368
360
  }),
@@ -370,6 +362,11 @@ export default defineConfig({
370
362
  });
371
363
  ```
372
364
 
365
+ > **Do not register `@vitejs/plugin-rsc` yourself.** It is an optional peer dependency, so it must be
366
+ > _installed_ in your project, but vinext auto-registers it whenever an `app/` directory is detected.
367
+ > Adding an explicit `rsc()` call fails the build with `[vinext] Duplicate @vitejs/plugin-rsc detected`.
368
+ > Pass `rsc: false` to `vinext()` only if you want to own that registration.
369
+
373
370
  See the [examples](#live-examples) for complete working configurations.
374
371
 
375
372
  ### Other platforms (via Nitro)
@@ -89,7 +89,13 @@ function createClientManualChunks(shimsDir, preserveRouteBoundaries = false) {
89
89
  if (id.includes("node_modules")) {
90
90
  const pkg = getPackageName(id);
91
91
  if (!pkg) return void 0;
92
- if (pkg === "react" || pkg === "react-dom" || pkg === "scheduler") return "framework";
92
+ if (pkg === "react-dom") {
93
+ const slashedId = toSlash(id);
94
+ const sub = slashedId.slice(slashedId.lastIndexOf("react-dom/") + 10);
95
+ if (sub.startsWith("server.") || sub.startsWith("static.") || sub.startsWith("cjs/react-dom-server")) return "react-dom-server";
96
+ return "framework";
97
+ }
98
+ if (pkg === "react" || pkg === "scheduler") return "framework";
93
99
  return;
94
100
  }
95
101
  const slashedId = toSlash(id);
package/dist/check.js CHANGED
@@ -230,6 +230,10 @@ const CONFIG_SUPPORT = {
230
230
  status: "supported",
231
231
  detail: "server actions via 'use server' directive"
232
232
  },
233
+ "experimental.allowedRevalidateHeaderKeys": {
234
+ status: "supported",
235
+ detail: "forwards explicitly allowed request headers during Pages Router revalidation"
236
+ },
233
237
  "experimental.prefetchInlining": {
234
238
  status: "partial",
235
239
  detail: "config recognized; Link prefetch preserves pending/dedup semantics, but vinext does not implement per-segment cache storage"
@@ -1,4 +1,4 @@
1
- import { VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
1
+ import { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
2
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
3
3
  import { analyzeRegexSafety } from "../utils/regex-safety.js";
4
4
  import { normalizeHost, parseCookies, requestContextFromRequest } from "./request-context.js";
@@ -835,6 +835,9 @@ async function proxyExternalRequest(request, externalUrl) {
835
835
  for (const key of keysToDelete) headers.delete(key);
836
836
  headers.delete(VINEXT_PRERENDER_SECRET_HEADER);
837
837
  headers.delete(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER);
838
+ headers.delete(PRERENDER_REVALIDATE_HEADER);
839
+ headers.delete(PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER);
840
+ headers.delete(VINEXT_REVALIDATE_HOST_HEADER);
838
841
  headers.delete(VINEXT_MW_CTX_HEADER);
839
842
  const method = request.method;
840
843
  const hasBody = method !== "GET" && method !== "HEAD";
@@ -100,7 +100,11 @@ type NextConfig = {
100
100
  * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix
101
101
  */
102
102
  assetPrefix?: string; /** Whether to add trailing slashes */
103
- trailingSlash?: boolean; /** Internationalization routing config */
103
+ trailingSlash?: boolean; /** TypeScript build settings. */
104
+ typescript?: {
105
+ /** Project-relative path to the TypeScript configuration file. */tsconfigPath?: string;
106
+ [key: string]: unknown;
107
+ }; /** Internationalization routing config */
104
108
  i18n?: NextI18nConfig; /** URL redirect rules */
105
109
  redirects?: () => Promise<NextRedirect[]> | NextRedirect[]; /** URL rewrite rules */
106
110
  rewrites?: () => Promise<NextRewrite[] | {
@@ -217,7 +221,8 @@ type NextConfig = {
217
221
  prefetchInlining?: boolean | {
218
222
  maxBundleSize?: number;
219
223
  maxSize?: number;
220
- };
224
+ }; /** Header names forwarded by Pages Router `res.revalidate()` internal requests. */
225
+ allowedRevalidateHeaderKeys?: string[];
221
226
  [key: string]: unknown;
222
227
  };
223
228
  /**
@@ -266,6 +271,9 @@ type ResolvedNextConfig = {
266
271
  */
267
272
  assetPrefix: string;
268
273
  trailingSlash: boolean;
274
+ typescript: {
275
+ tsconfigPath?: string;
276
+ };
269
277
  output: "" | "export" | "standalone";
270
278
  pageExtensions: string[];
271
279
  resolveExtensions: string[] | null;
@@ -295,7 +303,8 @@ type ResolvedNextConfig = {
295
303
  mdx: MdxOptions | null; /** Explicit module aliases preserved from wrapped next.config plugins. */
296
304
  aliases: Record<string, string>; /** Extra allowed origins for dev server access (from allowedDevOrigins). */
297
305
  allowedDevOrigins: string[]; /** Extra allowed origins for server action CSRF validation (from experimental.serverActions.allowedOrigins). */
298
- serverActionsAllowedOrigins: string[]; /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */
306
+ serverActionsAllowedOrigins: string[]; /** Header names forwarded by Pages Router `res.revalidate()` internal requests. */
307
+ allowedRevalidateHeaderKeys: string[]; /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */
299
308
  optimizePackageImports: string[]; /** Packages explicitly requested for server/client transpilation. */
300
309
  transpilePackages: string[]; /** Packages treated as application code by Turbopack's foreign-code condition. */
301
310
  turbopackTranspilePackages: string[]; /** Inline app CSS into production HTML (from experimental.inlineCss). */
@@ -658,6 +658,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
658
658
  basePath: "",
659
659
  assetPrefix: "",
660
660
  trailingSlash: false,
661
+ typescript: {},
661
662
  output: "",
662
663
  pageExtensions: normalizePageExtensions(),
663
664
  resolveExtensions: null,
@@ -679,6 +680,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
679
680
  aliases: {},
680
681
  allowedDevOrigins: [],
681
682
  serverActionsAllowedOrigins: [],
683
+ allowedRevalidateHeaderKeys: [],
682
684
  optimizePackageImports: [],
683
685
  transpilePackages: [],
684
686
  turbopackTranspilePackages: [...DEFAULT_TRANSPILED_PACKAGES],
@@ -833,6 +835,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
833
835
  basePath: config.basePath ?? "",
834
836
  assetPrefix: normalizeAssetPrefix(config.assetPrefix),
835
837
  trailingSlash: config.trailingSlash ?? false,
838
+ typescript: typeof config.typescript?.tsconfigPath === "string" ? { tsconfigPath: config.typescript.tsconfigPath } : {},
836
839
  output: output === "export" || output === "standalone" ? output : "",
837
840
  pageExtensions,
838
841
  resolveExtensions: resolveExtensions ?? webpackProbe.resolveExtensions,
@@ -851,6 +854,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
851
854
  aliases,
852
855
  allowedDevOrigins,
853
856
  serverActionsAllowedOrigins,
857
+ allowedRevalidateHeaderKeys: Array.isArray(experimental?.allowedRevalidateHeaderKeys) ? experimental.allowedRevalidateHeaderKeys.filter((value) => typeof value === "string").map((value) => value.toLowerCase()) : [],
854
858
  optimizePackageImports,
855
859
  transpilePackages,
856
860
  turbopackTranspilePackages,
@@ -15,15 +15,9 @@ declare function generateBrowserEntry(routes?: readonly AppRoute[], routeManifes
15
15
  beforeFiles: NextRewrite[];
16
16
  fallback: NextRewrite[];
17
17
  }): string;
18
- /**
19
- * Filter for routes that should appear in the `__VINEXT_LINK_PREFETCH_ROUTES__`
20
- * manifest. Exported so the Pages Router client entry can reuse it when
21
- * emitting the same manifest for hybrid builds — see issue #1526 and
22
- * `pages-client-entry.ts`.
23
- */
24
- declare function isLinkPrefetchRoute(route: AppRoute): boolean;
25
- declare function toDocumentOnlyAppRoute(route: AppRoute): VinextLinkPrefetchRoute;
26
18
  /** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
27
- declare function toLinkPrefetchRoute(route: AppRoute): VinextLinkPrefetchRoute;
19
+ declare function toLinkPrefetchRoute(route: AppRoute, hasSiblingInterceptLoading?: boolean): VinextLinkPrefetchRoute;
20
+ /** Project App routes together so sibling-intercept loading is applied to its target route. */
21
+ declare function toLinkPrefetchRoutes(routes: readonly AppRoute[]): VinextLinkPrefetchRoute[];
28
22
  //#endregion
29
- export { generateBrowserEntry, isLinkPrefetchRoute, toDocumentOnlyAppRoute, toLinkPrefetchRoute };
23
+ export { generateBrowserEntry, toLinkPrefetchRoute, toLinkPrefetchRoutes };
@@ -1,4 +1,5 @@
1
1
  import { resolveClientRuntimeModule, resolveRuntimeEntryModule } from "./runtime-entry-module.js";
2
+ import { patternsStructurallyEquivalent } from "../routing/app-route-graph.js";
2
3
  //#region src/entries/app-browser-entry.ts
3
4
  /**
4
5
  * Generate the virtual browser entry module.
@@ -14,7 +15,7 @@ function generateBrowserEntry(routes = [], routeManifest = null, pagesPrefetchRo
14
15
  }) {
15
16
  const entryPath = resolveRuntimeEntryModule("app-browser-entry");
16
17
  const navigationRuntimePath = resolveClientRuntimeModule("navigation-runtime");
17
- const prefetchRoutes = routes.map((route) => isLinkPrefetchRoute(route) ? toLinkPrefetchRoute(route) : toDocumentOnlyAppRoute(route));
18
+ const prefetchRoutes = toLinkPrefetchRoutes(routes);
18
19
  return `import { registerNavigationRuntimeBootstrap } from ${JSON.stringify(navigationRuntimePath)};
19
20
 
20
21
  window.__VINEXT_LINK_PREFETCH_ROUTES__ = ${JSON.stringify(prefetchRoutes)};
@@ -50,15 +51,30 @@ function toDocumentOnlyAppRoute(route) {
50
51
  function requiresDynamicNavigationRequest(route) {
51
52
  return route.isDynamic && route.parallelSlots.length > 0;
52
53
  }
54
+ function splitPatternParts(pattern) {
55
+ return pattern.split("/").filter(Boolean);
56
+ }
57
+ function interceptTargetsRoute(interceptTargetPattern, route) {
58
+ return patternsStructurallyEquivalent(splitPatternParts(interceptTargetPattern), route.patternParts);
59
+ }
60
+ function hasLoadingBoundary(route, hasSiblingInterceptLoading) {
61
+ return route.loadingPath !== null || (route.loadingPaths?.length ?? 0) > 0 || route.parallelSlots.some((slot) => slot.loadingPath !== null || (slot.loadingPaths?.length ?? 0) > 0 || slot.interceptingRoutes.some((intercept) => interceptTargetsRoute(intercept.targetPattern, route) && (intercept.loadingPaths?.length ?? 0) > 0)) || hasSiblingInterceptLoading;
62
+ }
53
63
  /** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
54
- function toLinkPrefetchRoute(route) {
64
+ function toLinkPrefetchRoute(route, hasSiblingInterceptLoading = route.siblingIntercepts.some((intercept) => interceptTargetsRoute(intercept.targetPattern, route) && (intercept.loadingPaths?.length ?? 0) > 0)) {
55
65
  return {
56
- canPrefetchLoadingShell: route.loadingPath !== null,
66
+ canPrefetchLoadingShell: hasLoadingBoundary(route, hasSiblingInterceptLoading),
57
67
  patternParts: [...route.patternParts],
58
68
  isDynamic: route.isDynamic,
59
69
  ...requiresDynamicNavigationRequest(route) ? { requiresDynamicNavigationRequest: true } : {}
60
70
  };
61
71
  }
72
+ /** Project App routes together so sibling-intercept loading is applied to its target route. */
73
+ function toLinkPrefetchRoutes(routes) {
74
+ const siblingInterceptLoadingTargets = [];
75
+ for (const route of routes) for (const intercept of route.siblingIntercepts) if ((intercept.loadingPaths?.length ?? 0) > 0) siblingInterceptLoadingTargets.push(splitPatternParts(intercept.targetPattern));
76
+ return routes.map((route) => isLinkPrefetchRoute(route) ? toLinkPrefetchRoute(route, siblingInterceptLoadingTargets.some((targetParts) => patternsStructurallyEquivalent(targetParts, route.patternParts))) : toDocumentOnlyAppRoute(route));
77
+ }
62
78
  function buildRouteManifestExpression(routeManifest) {
63
79
  if (routeManifest === null) return "null";
64
80
  const graph = routeManifest.segmentGraph;
@@ -84,4 +100,4 @@ function buildMapExpression(map) {
84
100
  return `new Map(${JSON.stringify(Array.from(map.entries()))})`;
85
101
  }
86
102
  //#endregion
87
- export { generateBrowserEntry, isLinkPrefetchRoute, toDocumentOnlyAppRoute, toLinkPrefetchRoute };
103
+ export { generateBrowserEntry, toLinkPrefetchRoute, toLinkPrefetchRoutes };
@@ -195,6 +195,7 @@ import {
195
195
  isrGet as __isrGet,
196
196
  isrSet as __isrSet,
197
197
  isrSetPrerenderedAppPage as __isrSetPrerenderedAppPage,
198
+ isOnDemandRevalidateRequest as __isOnDemandRevalidateRequest,
198
199
  triggerBackgroundRegeneration as __triggerBackgroundRegeneration,
199
200
  } from ${JSON.stringify(isrCachePath)};
200
201
  // Import server-only state module to register ALS-backed accessors.
@@ -436,6 +437,8 @@ async function buildPageElements(route, params, routePath, pageRequest, layoutPa
436
437
  }
437
438
 
438
439
  const __i18nConfig = ${JSON.stringify(i18nConfig)};
440
+ export { __i18nConfig };
441
+ export const authorizeOnDemandRevalidate = __isOnDemandRevalidateRequest;
439
442
  const __configRedirects = ${JSON.stringify(redirects)};
440
443
  const __configRewrites = ${JSON.stringify(rewrites)};
441
444
  const __configHeaders = ${JSON.stringify(headers)};
@@ -53,6 +53,7 @@ function registerRouteModules(routes, imports) {
53
53
  for (const layout of route.layouts) imports.getLazyLoaderVar(layout);
54
54
  for (const tmpl of route.templates) imports.getLazyLoaderVar(tmpl);
55
55
  if (route.loadingPath) imports.getLazyLoaderVar(route.loadingPath);
56
+ for (const loadingPath of route.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
56
57
  if (route.errorPath) imports.getLazyLoaderVar(route.errorPath);
57
58
  if (route.layoutErrorPaths) {
58
59
  for (const ep of route.layoutErrorPaths) if (ep) imports.getLazyLoaderVar(ep);
@@ -76,18 +77,21 @@ function registerRouteModules(routes, imports) {
76
77
  if (slot.layoutPath) imports.getLazyLoaderVar(slot.layoutPath);
77
78
  for (const layoutPath of slot.configLayoutPaths ?? []) imports.getLazyLoaderVar(layoutPath);
78
79
  if (slot.loadingPath) imports.getLazyLoaderVar(slot.loadingPath);
80
+ for (const loadingPath of slot.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
79
81
  if (slot.errorPath) imports.getLazyLoaderVar(slot.errorPath);
80
82
  if (slot.notFoundPath) imports.getLazyLoaderVar(slot.notFoundPath);
81
83
  for (const ir of slot.interceptingRoutes) {
82
84
  imports.getLazyLoaderVar(ir.pagePath);
83
85
  if (ir.notFoundPath) imports.getLazyLoaderVar(ir.notFoundPath);
84
86
  for (const layoutPath of ir.layoutPaths) imports.getLazyLoaderVar(layoutPath);
87
+ for (const loadingPath of ir.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
85
88
  }
86
89
  }
87
90
  for (const ir of route.siblingIntercepts ?? []) {
88
91
  imports.getLazyLoaderVar(ir.pagePath);
89
92
  if (ir.notFoundPath) imports.getLazyLoaderVar(ir.notFoundPath);
90
93
  for (const layoutPath of ir.layoutPaths) imports.getLazyLoaderVar(layoutPath);
94
+ for (const loadingPath of ir.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
91
95
  }
92
96
  }
93
97
  }
@@ -102,10 +106,12 @@ function buildRouteEntries(routes, imports) {
102
106
  const staticSiblings = route.isDynamic ? computeAppRouteStaticSiblings(routes, route) : [];
103
107
  const layoutLoaders = lazyLoaderArray(route.layouts, imports);
104
108
  const templateLoaders = lazyLoaderArray(route.templates, imports);
109
+ const loadingPaths = route.loadingPaths ?? [];
105
110
  const notFoundPaths = route.notFoundPaths ?? [];
106
111
  const forbiddenPaths = route.forbiddenPaths ?? [];
107
112
  const unauthorizedPaths = route.unauthorizedPaths ?? [];
108
113
  const notFoundLoaders = lazyLoaderArray(notFoundPaths, imports);
114
+ const loadingLoaders = lazyLoaderArray(loadingPaths, imports);
109
115
  const forbiddenLoaders = lazyLoaderArray(forbiddenPaths, imports);
110
116
  const unauthorizedLoaders = lazyLoaderArray(unauthorizedPaths, imports);
111
117
  const siblingInterceptEntries = (route.siblingIntercepts ?? []).map((ir) => ` {
@@ -118,6 +124,9 @@ function buildRouteEntries(routes, imports) {
118
124
  __loadInterceptLayouts: ${lazyLoaderArray(ir.layoutPaths, imports)},
119
125
  interceptLayoutSegments: ${JSON.stringify(ir.layoutSegments ?? [])},
120
126
  interceptBranchSegments: ${JSON.stringify(ir.branchSegments ?? [])},
127
+ interceptLoadings: ${moduleArray(ir.loadingPaths?.length ?? 0)},
128
+ __loadInterceptLoadings: ${lazyLoaderArray(ir.loadingPaths ?? [], imports)},
129
+ interceptLoadingTreePositions: ${JSON.stringify(ir.loadingTreePositions ?? [])},
121
130
  interceptNotFoundBranchSegments: ${JSON.stringify(ir.notFoundBranchSegments ?? ir.branchSegments ?? [])},
122
131
  page: null,
123
132
  __pageLoader: ${imports.getLazyLoaderVar(ir.pagePath)},
@@ -136,6 +145,9 @@ function buildRouteEntries(routes, imports) {
136
145
  __loadInterceptLayouts: ${lazyLoaderArray(ir.layoutPaths, imports)},
137
146
  interceptLayoutSegments: ${JSON.stringify(ir.layoutSegments ?? [])},
138
147
  interceptBranchSegments: ${JSON.stringify(ir.branchSegments ?? [])},
148
+ interceptLoadings: ${moduleArray(ir.loadingPaths?.length ?? 0)},
149
+ __loadInterceptLoadings: ${lazyLoaderArray(ir.loadingPaths ?? [], imports)},
150
+ interceptLoadingTreePositions: ${JSON.stringify(ir.loadingTreePositions ?? [])},
139
151
  interceptNotFoundBranchSegments: ${JSON.stringify(ir.notFoundBranchSegments ?? ir.branchSegments ?? [])},
140
152
  page: null,
141
153
  __pageLoader: ${imports.getLazyLoaderVar(ir.pagePath)},
@@ -147,6 +159,7 @@ function buildRouteEntries(routes, imports) {
147
159
  return ` ${JSON.stringify(slot.key)}: {
148
160
  id: ${JSON.stringify(slot.id ?? null)},
149
161
  name: ${JSON.stringify(slot.name)},
162
+ ownerTreePosition: ${slot.ownerTreePosition ?? "null"},
150
163
  page: null,
151
164
  __loadPage: ${slot.pagePath ? imports.getLazyLoaderVar(slot.pagePath) : "null"},
152
165
  default: null,
@@ -158,6 +171,9 @@ function buildRouteEntries(routes, imports) {
158
171
  configLayoutTreePositions: ${JSON.stringify(slot.configLayoutTreePositions ?? [])},
159
172
  loading: null,
160
173
  __loadLoading: ${slot.loadingPath ? imports.getLazyLoaderVar(slot.loadingPath) : "null"},
174
+ loadings: ${moduleArray(slot.loadingPaths?.length ?? 0)},
175
+ __loadLoadings: ${lazyLoaderArray(slot.loadingPaths ?? [], imports)},
176
+ loadingTreePositions: ${JSON.stringify(slot.loadingTreePositions ?? [])},
161
177
  error: null,
162
178
  __loadError: ${slot.errorPath ? imports.getLazyLoaderVar(slot.errorPath) : "null"},
163
179
  notFound: null,
@@ -200,6 +216,9 @@ ${interceptEntries.join(",\n")}
200
216
  layoutTreePositions: ${JSON.stringify(route.layoutTreePositions)},
201
217
  templates: ${moduleArray(route.templates.length)},
202
218
  __loadTemplates: ${templateLoaders},
219
+ loadings: ${moduleArray(loadingPaths.length)},
220
+ __loadLoadings: ${loadingLoaders},
221
+ loadingTreePositions: ${JSON.stringify(route.loadingTreePositions ?? null)},
203
222
  errors: ${moduleArray(layoutErrorPaths.length)},
204
223
  __loadErrors: ${layoutErrorLoaders},
205
224
  errorPaths: ${moduleArray(errorPaths.length)},
@@ -177,7 +177,6 @@ async function hydrate() {
177
177
  element = React.createElement(AppComponent, {
178
178
  ...props,
179
179
  Component: PageComponent,
180
- pageProps: rawPageProps,
181
180
  router: Router,
182
181
  });
183
182
  } catch {
@@ -24,6 +24,7 @@ const _pagesApiRoutePath = resolveEntryPath("../server/pages-api-route.js", impo
24
24
  const _serverGlobalsPath = resolveEntryPath("../server/server-globals.js", import.meta.url);
25
25
  const _queryUtilsPath = resolveEntryPath("../utils/query.js", import.meta.url);
26
26
  const _pagesPageHandlerPath = resolveEntryPath("../server/pages-page-handler.js", import.meta.url);
27
+ const _isrCachePath = resolveEntryPath("../server/isr-cache.js", import.meta.url);
27
28
  async function getPagesDataKind(filePath) {
28
29
  const source = await readFile(filePath, "utf8");
29
30
  if (hasExportedName(source, "getStaticProps")) return "static";
@@ -71,6 +72,7 @@ async function generateServerEntry(pagesDir, nextConfig, fileMatcher, middleware
71
72
  },
72
73
  headers: nextConfig?.headers ?? [],
73
74
  expireTime: nextConfig?.expireTime,
75
+ allowedRevalidateHeaderKeys: nextConfig?.allowedRevalidateHeaderKeys ?? [],
74
76
  cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
75
77
  htmlLimitedBots: nextConfig?.htmlLimitedBots,
76
78
  i18n: nextConfig?.i18n ?? null,
@@ -151,11 +153,17 @@ import { handlePagesApiRoute as __handlePagesApiRoute } from ${JSON.stringify(_p
151
153
  import { normalizePagesDataRequest as __normalizePagesDataRequest, buildNextDataNotFoundResponse as __buildNextDataNotFoundResponse } from ${JSON.stringify(_pagesDataRoutePath)};
152
154
  import { buildDefaultPagesNotFoundResponse as __buildDefaultPagesNotFoundResponse } from ${JSON.stringify(_pagesDefault404Path)};
153
155
  import { createPagesPageHandler as __createPagesPageHandler } from ${JSON.stringify(_pagesPageHandlerPath)};
156
+ import { isOnDemandRevalidateRequest as __isOnDemandRevalidateRequest } from ${JSON.stringify(_isrCachePath)};
154
157
  ${instrumentationImportCode}
155
158
  ${middlewareImportCode}
156
159
 
157
160
  ${instrumentationInitCode}
158
161
 
162
+ // The outer Node production pipeline runs outside this generated bundle, so
163
+ // it cannot safely validate against its own development fallback secret. Give
164
+ // it a verifier closed over this entry's build-time-baked secret instead.
165
+ export const authorizeOnDemandRevalidate = __isOnDemandRevalidateRequest;
166
+
159
167
  // i18n config (embedded at build time)
160
168
  const i18nConfig = ${i18nConfigJson};
161
169
 
@@ -344,7 +352,6 @@ const _renderPage = __createPagesPageHandler({
344
352
  ? React.createElement(AppComponent, {
345
353
  ...props,
346
354
  Component: PageComponent,
347
- pageProps: rawPageProps,
348
355
  router: Router,
349
356
  })
350
357
  : React.createElement(PageComponent, pageProps);
@@ -362,7 +369,6 @@ const _renderPage = __createPagesPageHandler({
362
369
  ? React.createElement(FinalApp, {
363
370
  ...props,
364
371
  Component: FinalComp,
365
- pageProps: rawPageProps,
366
372
  router: Router,
367
373
  })
368
374
  : React.createElement(FinalComp, pageProps);
@@ -379,7 +385,7 @@ export async function renderPage(request, url, manifest, ctx, middlewareHeaders,
379
385
 
380
386
 
381
387
 
382
- export async function handleApiRoute(request, url, ctx) {
388
+ export async function handleApiRoute(request, url, ctx, trustedRevalidateOrigin) {
383
389
  __registerConfiguredCacheAdapters();
384
390
  const match = matchRoute(url, apiRoutes);
385
391
  return __handlePagesApiRoute({
@@ -387,6 +393,7 @@ export async function handleApiRoute(request, url, ctx) {
387
393
  match,
388
394
  nextConfig: vinextConfig,
389
395
  request,
396
+ trustedRevalidateOrigin,
390
397
  url,
391
398
  reportRequestError(error, routePattern) {
392
399
  console.error("[vinext] API error:", error);