Commit Graph

1561 Commits

Author SHA1 Message Date
github-actions[bot] 5471b41eec chore: version packages (#2428)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@vinext/cloudflare@0.2.1 vinext@0.2.1
2026-07-03 09:40:50 +00:00
Steve Faulkner b7455c3fa6 fix: fully elide inline type-only import specifiers (#2498)
Vite 8's OXC transform (and Vite 7's esbuild transform) honour
`"verbatimModuleSyntax": true` from the app's tsconfig, so
`import { type Metadata } from "next"` leaves a side-effect
`import "next"` behind when every specifier is type-only. Next.js
(SWC) — and esbuild/tsc without verbatimModuleSyntax — elide the whole
statement. create-t3-app and other scaffolds emit both the tsconfig
option and the inline-type import form stock, so on vinext the real
Next.js server runtime was pulled into the RSC graph (dev 500
"require is not defined", build failures via styled-jsx/client-only)
and server-only modules were pulled into the browser bundle when a
"use client" file imported only types from them (t3's tRPC router
shipped to clients and crashed hydration).

Force `typescript.onlyRemoveTypeImports: false` in the oxc transform
options (and `verbatimModuleSyntax: false` in the Vite 7 esbuild
tsconfigRaw) so type-import elision matches Next.js regardless of the
app's tsconfig.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:35:59 +01:00
James Anderson 5915c87116 fix(app-router): limit mounted slot cache variants (#2497) 2026-07-03 00:05:47 +01:00
James Anderson 336450ae47 fix(config): escape destination query params (#2494) 2026-07-03 00:00:45 +01:00
James Anderson e0db846716 fix(cloudflare): respect TPR cache opt-outs (#2493) 2026-07-02 23:38:48 +01:00
James Anderson 20e1076452 chore(release): reclassify reactStrictMode entry (#2496) 2026-07-02 22:29:17 +00:00
Nathan Nguyen a9a30a5c85 fix(app-router): omit pending RSC cache state for query renders (#2488)
Co-authored-by: James Anderson <james@eli.cx>
2026-07-02 22:46:53 +01:00
James Anderson 6c7b71eb12 fix(app-router): isolate global not-found css (#2444)
* fix(app-router): isolate global not-found css

* fix(app-router): cover global not-found css review gaps
2026-07-02 21:35:52 +01:00
James Anderson 8b122744ef fix(pages): align middleware data prefetch caching (#2451)
* fix(pages): align middleware data prefetch caching

* fix(pages): guard middleware prefetch data kind

* fix(dev): lazily classify pages data kind

* fix(pages): preserve legacy prefetch fallback

* fix(pages): reject unknown prefetch data kind
2026-07-02 21:33:32 +01:00
James Anderson 6bd1ee0153 fix(app-router): expose app rewrites to pages data clients (#2468) 2026-07-02 21:03:05 +01:00
James Anderson 5a90172a6b fix(pages): honor basePath false rewrites (#2442) 2026-07-02 21:01:24 +01:00
James Anderson e453928dda fix(app-router): publish committed no-prefetch navigations (#2469)
* fix(app-router): publish committed no-prefetch navigations

* fix(app-router): remove unreachable visited-cache fallback

* fix(app-router): replay committed no-prefetch cache payloads

* fix(app-router): remove dead committed cache guard
2026-07-02 20:58:48 +01:00
dependabot[bot] e82cc60de8 chore(deps): bump voidzero-dev/setup-vp from 1.12.0 to 1.13.0 (#2491)
Bumps [voidzero-dev/setup-vp](https://github.com/voidzero-dev/setup-vp) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/voidzero-dev/setup-vp/releases)
- [Commits](https://github.com/voidzero-dev/setup-vp/compare/2dec1e33f4ab2c6d5bce1b0c4607961bb1a3f7a1...35171c92dd08b67d5a9d3f2a4327800e58396f2a)

---
updated-dependencies:
- dependency-name: voidzero-dev/setup-vp
  dependency-version: 1.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-02 20:44:44 +01:00
James Anderson 5343a3ff32 fix(app-router): cache segment prefetches by rendered search params (#2477)
* fix(app-router): cache segment prefetches by rendered search params

* fix(app-router): protect rendered prefetch alias header

* fix(app-router): repair segment prefetch merge
2026-07-02 19:42:46 +00:00
James Anderson 04a7ed3a10 fix(app-router): skip readiness waits for speculative prerenders (#2457)
* fix(app-router): skip readiness waits for speculative prerenders

* test(request-pipeline): assert speculative header stripping

* fix(app-router): keep speculative prerender shell errors throwable

* fix(app-router): capture speculative prerender cache metadata
2026-07-02 20:25:31 +01:00
James Anderson 5f8048f660 fix(app-router): align app static ISR lifecycle (#2472)
* fix(app-router): align app static ISR lifecycle

* fix(fetch-cache): honor shorter revalidate on hits

* fix(cache): honor read-time revalidate in KV cache
2026-07-02 20:19:02 +01:00
James Anderson 9e1866abb9 fix(pages): normalize data routes for trailing slash middleware (#2470)
* fix(pages): normalize data routes for trailing slash middleware

* fix(pages): gate data trailing slash normalization on middleware
2026-07-02 20:04:25 +01:00
James Anderson 1500fe61d7 fix(pages): align prerender functional parity (#2471)
* fix(pages): align prerender functional parity

* fix(pages): harden preview bypass comparison
2026-07-02 19:57:40 +01:00
James Anderson 239595e69e fix(app-router): reuse metadata rewrite prefetches (#2455)
* fix(app-router): reuse metadata rewrite prefetches

* fix(app-router): normalize rsc reference validation ids

* Revert "fix(app-router): normalize rsc reference validation ids"

This reverts commit bbff1eb13a.

* chore: format link shim
2026-07-01 17:02:35 +00:00
James Anderson ebf8e59289 fix(app-router): avoid runtime route-tree prefetch sizing (#2467)
* fix(app-router): start optimistic prefetches immediately

* fix(app-router): support route tree prefetch inlining

* fix(app-router): dedupe max prefetch inlining requests

* fix(app-router): cap route-tree prefetch size reads

* fix(app-router): avoid runtime route-tree prefetch sizing

* Fixed CI type error, flagged parity gap

Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>

* fix(app-router): preserve negative prefetch inlining thresholds

* fix(app-router): normalize rsc reference validation ids

* Revert "fix(app-router): normalize rsc reference validation ids"

This reverts commit 68b96b596c.

* fix(app-router): keep route-tree prefetch metadata scoped

---------

Co-authored-by: ask-bonk[bot] <ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>
2026-07-01 17:47:08 +01:00
James Anderson 03f02177ec fix(app-router): start optimistic prefetches immediately (#2440)
* fix(app-router): start optimistic prefetches immediately

* fix(app-router): normalize rsc reference validation ids

* Revert "fix(app-router): normalize rsc reference validation ids"

This reverts commit 34a37658c2.
2026-07-01 16:45:35 +00:00
James Anderson 2256fdd53b fix(app-router): normalize rsc reference validation ids (#2480)
* fix(app-router): normalize rsc reference validation ids

* fix(app-router): scope rsc validation normalizer to dev
2026-07-01 14:30:22 +01:00
James Anderson 81e925eb66 fix(ci): harden perf publisher tree validation (#2478) 2026-07-01 13:39:20 +01:00
James Anderson 9ec793244e fix(app-router): send deployment id on RSC responses (#2452)
* fix(app-router): send deployment id on RSC responses

* test(app-router): isolate deployment id integration coverage
2026-07-01 11:27:22 +01:00
James Anderson 97cd5c3fb4 fix(app-router): separate header-only full-route rsc requests (#2445)
* fix(app-router): separate header-only full-route rsc requests

* test(app-router): assert header RSC redirect
2026-07-01 11:17:10 +01:00
James Anderson b0367f1448 fix(link): avoid reusing dynamic app route prefetches (#2450)
* fix(link): avoid reusing dynamic app route prefetches

* fix(link): preserve static dynamic app prefetches

* test(e2e): scope segment cache client params to prod
2026-07-01 11:14:11 +01:00
James Anderson fd8dd3de09 fix(app-router): preserve app rewrite filtering (#2441) 2026-07-01 11:08:31 +01:00
James Anderson de733ce4aa fix(app-router): revalidate dynamic intercepted actions (#2443) 2026-07-01 11:02:53 +01:00
James Anderson bc1dfce00f fix(app-router): evict segment prefetches under memory pressure (#2466)
* fix(app-router): evict segment prefetches under memory pressure

* fix(app-router): hold prefetch queue slots until body read
2026-07-01 10:54:47 +01:00
Nathan Nguyen 4dd64dd87f fix(build): handle dynamic requests in JS files with JSX (#1736)
* fix(build): parse dynamic request JS files as JSX

* fix(build): parse mjs cjs dynamic requests as JSX

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 23:25:47 +01:00
Yunfei He fae1a4f949 fix(dev): treat .js as JSX in the optimizeDeps scanner (#2434)
* fix(dev): treat .js as JSX in the optimizeDeps scanner

The dep optimizer (scanner + pre-bundler) runs its own Rolldown/esbuild
pipeline that does not go through the `vinext:jsx-in-js` transform plugin,
so JSX in plain `.js`/`.mjs` source files made the dependency scan fail with
"Unexpected JSX expression" and aborted pre-bundling.

Configure the dep optimizer to treat `.js`/`.mjs` as JSX
(`optimizeDeps.rolldownOptions.moduleTypes` on Vite 8,
`optimizeDeps.esbuildOptions.loader` on Vite 7), mirroring how the main
transform treats `.js`/`.mjs` (its `/\.m?js$/` filter). Applied to the
top-level optimizeDeps and the per-environment (rsc/ssr/client) blocks via
getDepOptimizeNodeEnvOptions.

The motivating real-world symptom is that, once the scan aborts,
pre-bundling is skipped and UMD/CJS deps can fail to interop under SSR
("window is not defined"). That downstream cascade runs through a different
optimizer path and is not what this change is verified to fix — the added
tests assert only that the dependency scan no longer aborts on
JSX-in-`.js`/`.mjs`.

* test(dev): cover pages jsx optimizer scan

* test(dev): strengthen jsx optimizer scan coverage

* fix(dev): apply jsx optimizer config to pages build clients

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 23:07:30 +01:00
Yunfei He feb78add12 feat(pages): enforce reactStrictMode by wrapping client root in <StrictMode> (#2433)
* feat(pages): enforce reactStrictMode by wrapping client root in <StrictMode>

`reactStrictMode: true` was recognized but not enforced — the app root was
never wrapped in <React.StrictMode>, so dev-time strict checks (double-invoked
effects/render, deprecation warnings) were silently lost.

Resolve `reactStrictMode` from next.config (preserved as `boolean | null` so
each router applies its own default) and, for the Pages Router, wrap the
client tree in <React.StrictMode> when the value is `true`. The default
matches Next.js: `null`/unset is OFF for the Pages Router
(`reactStrictMode === null ? false` in define-env.ts).

The wrap lives in `wrapWithRouterContext` (next/router) — the single seam every
render path funnels through: the initial hydration entry (production AND the
dev server's inline hydration script) and every client-side navigation
`root.render()` in shims/router.ts. This mirrors Next.js, whose `doRender`
closure wraps in <React.StrictMode> for both the initial hydrate and subsequent
`reactRoot.render()` calls (client/index.tsx). Wrapping only the production
client entry would have been inert — StrictMode does nothing in production, and
the dev server hydrates via a separate template — so the flag is also threaded
into createSSRHandler and the dev hydration script. The wrap is gated on a
client-only `window.__VINEXT_REACT_STRICT_MODE__` flag so the server-rendered
tree is never wrapped (Next.js wraps client-side only); StrictMode renders no
DOM, so SSR markup and hydration are unaffected. The CommitBoundary stays
outside StrictMode so its commit effect is not double-invoked (Next.js keeps
`<Root>` outside <StrictMode> too).

`vinext check` reports reactStrictMode as "partial": enforced for the Pages
Router, but the App Router is not yet wrapped (its root is mounted by the RSC
client runtime, not vinext-owned code, and Next.js defaults App Router strict
mode on).

* test(pages): cover strict mode navigation renders

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 23:06:25 +01:00
Yunfei He 13d36378f8 perf(build): parallelize prerender across a pool of render processes (#2437)
* perf(build): parallelize prerender across a pool of render processes

Build-time prerender rendered every static route by fetching it from a
single in-process production server driven by a promise pool. React
SSR/RSC rendering is CPU-bound JS, so the pool only overlaps I/O — every
render serialized on one core, and raising --prerender-concurrency did
nothing. Next.js forks a worker pool and saturates every core.

Fork a pool of production-server child processes (one per core, capped)
and round-robin the per-route render fetch across them, keeping route
scanning, getStaticPaths/static-params resolution, file writing and the
manifest on the main process. Pool size scales by cores AND routes, so
small apps, low-memory machines, and --prerender-concurrency 1 keep the
single in-process server (no fork, no regression); running from source
(no built .js worker entry) also falls back to single-process.

child_process, not worker_threads: worker threads contend for CPU on this
workload (measured ~2x slower per route and non-scaling), which is also
why Next.js uses processes.

react.dev (809 routes, cold cache, same machine): 29.9s -> 15.1s, now
faster than its own Next.js build (~19.3s). An 801-route static fixture:
~22s -> ~2-6s. Prerender output is byte-identical to the single-process
path on deterministic renders; workers install the same NoOp cache
handler the in-process path uses. A worker that exits unexpectedly fails
the build loudly instead of shipping partial output.

* fix(build): harden prerender worker pool

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 23:04:02 +01:00
Yunfei He 6e9fa0b0b1 fix(config): resolve and bundle extensionless .cjs config imports (#2435)
* fix(config): resolve and bundle extensionless .cjs config imports

`vinext init` renames CJS config files (tailwind.config.js,
postcss.config.js) to .cjs when it adds "type": "module", and app code
imports them extensionlessly (import cfg from "../tailwind.config").

Two problems blocked this on the app module graph:

1. vinext overrides resolve.extensions for every Vite environment with a
   list that, like Vite's default, omits .cjs/.cts, so the extensionless
   import failed with [UNRESOLVED_IMPORT]. Append .cjs/.cts (lowest
   priority) to buildViteResolveExtensions' default list.

2. Once resolved, vite-plugin-commonjs rewrote the .cjs module.exports to
   ESM export {}, but rolldown infers moduleType: cjs from the extension
   and re-parsed the output as CommonJS, failing with "Cannot use export
   statement outside a module". Return false from the commonjs() filter for
   project-local .cjs/.cts so vite-plugin-commonjs skips them and rolldown's
   own CJS interop bundles them. Everything else returns undefined, which
   preserves the plugin's defaults, including its existing skip of
   node_modules .cjs files.

Fixes cloudflare/vinext#13.

* fix(config): harden local cjs commonjs filter

* docs(config): fix cjs regression references

* test(config): cover extensionless cts config imports

* docs(config): clarify cjs resolve extension defaults

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 23:00:55 +01:00
James Anderson 2da8287e89 fix(app-router): honor basePath false rewrites (#2370)
* fix(app-router): honor basePath false rewrites

* fix(app-router): preserve basePath routing boundaries

* test(app-router): cover basePath handler boundaries

* fix(app-router): track basePath rewrite claims

* chore(app-router): remove stale basePath note

* fix(app-router): allow late rewrite route posts

* fix(app-router): short-circuit unclaimed basePath misses

* fix(app-router): preserve out-of-basePath 404 semantics

* fix(app-router): validate late basePath rewrites

* docs(app-router): clarify late action rewrites

* fix(app-router): resolve progressive action rewrites
2026-06-30 21:16:27 +01:00
James Anderson e0cb913922 fix(app-router): preserve rewritten route identity (#2358)
* fix(app-router): preserve rewritten route identity

* test(app-router): isolate rewrite prefetch regression

* test(app-router): cover rewritten element keys

* test(app-router): remove orphaned rewrite fixture

* fix(prerender): avoid reloading RSC entry after path injection
2026-06-30 21:14:04 +01:00
James Anderson d7e8bc5f53 chore: add script for targetted e2e (#2439) 2026-06-30 19:56:06 +00:00
James Anderson 328f01b09d fix(app-router): support styled-jsx from next (#2341)
* fix(app-router): support styled-jsx from next

* fix(app-router): preserve styled jsx refresh

* test(app-router): exercise styled jsx compiler

* fix(app-router): keep styled jsx refresh server-safe

* fix(app-router): keep styled jsx refresh server-safe

* test(app-router): cover server-safe styled jsx dev

* fix(app-router): detect styled jsx syntax variants

* fix(app-router): scope styled jsx detection

* fix(app-router): parse styled jsx attributes

* fix(app-router): delegate styled jsx detection

* fix(app-router): preserve vinext-only style builds

* fix(app-router): detect styled jsx with AST

* fix(app-router): prefer Next styled jsx runtime

* fix(app-router): skip styled-jsx transforms in dependencies
2026-06-30 20:54:17 +01:00
James Anderson 8df2344e77 fix(css): preserve Sass partial asset URLs (#2338)
* fix(css): preserve Sass partial asset URLs

* fix(css): preserve Sass use namespaces

* fix(css): match Sass namespace derivation
2026-06-30 20:31:49 +01:00
James Anderson 49945a9e05 fix(link): reuse full prefetch loading shells (#2332)
* fix(link): reuse full prefetch loading shells

* fix(link): share loading shell prefetch ownership
2026-06-30 19:34:50 +01:00
Yunfei He c1672a1acb test(routing): cover optional catch-all root with empty params (#2436)
* test(routing): cover optional catch-all root with empty params

Add a regression test for a ROOT-level optional catch-all page
pages/[[...markdownPath]].js whose getStaticPaths emits the empty-params
entry { markdownPath: [] } (the react.dev shape). Verifies the dev server
serves the root / HTML, the /_next/data/<id>/index.json endpoint, a
non-root concrete path, and a 404 for unlisted paths under fallback:false.

The existing optional catch-all test only covers a non-root subpath; this
guards the empty-params-at-root case, which routes through the trie's
0-segment optional catch-all match (route-trie.ts) and the empty-array
path normalization (route-pattern.ts / pages-page-data.ts).

* test(routing): tighten optional catch-all root coverage

---------

Co-authored-by: James <james@eli.cx>
2026-06-30 18:31:56 +01:00
James Anderson 6a787de547 feat(benchmarks): add local profile tooling (#2432) 2026-06-30 16:06:13 +00:00
James Anderson 427e0ef154 fix(dev): seed Cloudflare Pages Router worker deps (#2430)
* fix(dev): seed Cloudflare Pages Router worker deps

* fix(dev): include external store selector dep

* fix(dev): guard optional worker optimizer dep

* Revert "fix(dev): guard optional worker optimizer dep"

This reverts commit 65530f1d0c.

* fix(dev): suppress optional worker optimizer warning

* fix(dev): harden optional optimizer warning filter
2026-06-30 12:26:16 +01:00
James Anderson b0de1af028 fix(cloudflare): support Sentry request errors on Workers (#2425)
* fix(cloudflare): support sentry request errors on workers

* fix(cloudflare): avoid worker conditions in node pages builds

* test(cloudflare): run sentry worker e2es in ci

* test(cloudflare): cover sentry render errors

* test(cloudflare): mirror sentry next setup in fixtures

* update lockfile

* update lockfile

* test(cloudflare): cover sentry client instrumentation
2026-06-30 10:58:04 +01:00
James Anderson f4a96c993b fix(pages): preload initial dev stylesheets (#2423)
* fix(pages): preload initial dev stylesheets

* fix(pages): keep dev module path encoder internal

* fix(pages): harden dev stylesheet parity

* fix(pages): preserve hybrid app HMR

* fix(pages): preserve CSS resource query imports
2026-06-30 10:10:16 +01:00
James Anderson b5aded498a fix(cloudflare): allow pages deploy without custom worker (#2429) 2026-06-30 08:21:47 +00:00
James Anderson c02f30484b fix(pages): route dotted dynamic paths in dev (#2424)
* fix(pages): route dotted dynamic paths in dev

* fix(pages): preserve i18n dotted dynamic routes

* chore(pages): clarify dotted route preflight

* chore(pages): share dev hostname parsing

* chore(pages): reuse dev request origin
2026-06-30 09:19:27 +01:00
Arnold K 53da079f86 fix: use normalizePathSeparators in formatAppFilePath for Windows compatibility (#2426) 2026-06-30 07:53:52 +00:00
Jerry Zhao c54614f2ed refactor(app-router): build discoverSiblingInterceptingRoutes paths with path.posix (#2306) 2026-06-30 08:49:53 +01:00
Jerry Zhao 7de1edf79d refactor(app-router): descend collectInterceptingPages with path.posix.join (#2307) 2026-06-30 08:49:46 +01:00