Commit Graph
34723 Commits
Author SHA1 Message Date
Tim NeutkensandGitHub 0f01364309 Add React sync development skill (#95620)
### What?

Add a repository skill for building local React stable and experimental
bundles, syncing them into Next.js, and verifying the integration.

### Why?

Testing upstream React changes in Next.js requires a precise bundle
list, both React release channels, and the repository-pinned pnpm
version. Capturing the workflow as a skill makes it repeatable and
avoids global pnpm versions bypassing workspace linking.

### How?

Add `$react-sync` with a reusable build helper and document it in
`AGENTS.md`. The sync command puts the Corepack shim first on `PATH` so
nested pnpm commands use the version pinned by Next.js.

### Verification

- `bash -n .agents/skills/react-sync/scripts/build-for-next.sh`
- `python3
~/.codex/skills/.system/skill-creator/scripts/quick_validate.py
.agents/skills/react-sync`
- Prettier check for `AGENTS.md` and `SKILL.md`
- Full local React build and `pnpm sync-react` workflow completed
successfully
- `pnpm --filter=next build`

<!-- NEXT_JS_LLM_PR -->
2026-07-14 12:49:59 +02:00
JosephandGitHub cecb6f3276 docs: useSearchParams example stray link (#95759)
Link pointing back to its own section.
2026-07-14 12:03:47 +02:00
Luke SandbergandGitHub e0b2cebde5 Improve the NFT error message and ignore comment handling (#95144)
Fixes #95125 in two ways

The OP admits that they misread the message in a few ways, but we can
fix all of them

1. Be specific about what function might need an annotation in the error
message. A user with a nearby `path.join` might think that that is where
the annotation belongs instead of on the function with the warning.

2. Be more flexible with how these `ignore` comments are interpreted
`fs.readFileSync(path.join(process.cwd(), someVar))` shouldn't require 2
annotations. Handle this by checking for and detecting `turbopackIgnore`
comments in all expressions! This will then bubble up through the linker
and just cause us to ignore corresponding fs access apis.
2026-07-14 08:13:12 +02:00
Niklas MischkulnigandGitHub d774f7db29 Upgrade to swc 73 (#95731)
- [x] Waiting for a swc major bump in
https://github.com/swc-project/plugins...
2026-07-14 08:03:43 +02:00
next-js-bot[bot]andGitHub 1ecd8f1b63 v16.3.0-canary.85 v16.3.0-canary.85 2026-07-13 23:32:10 +00:00
Sam PoderandGitHub f1185f1341 [turbopack] Switch make_production_chunks to use floats (#95749)
We've talked about making this switch, making this switch because
without it the diff for https://github.com/vercel/next.js/pull/95157 was
very difficult to read and follow.
2026-07-13 16:23:33 -07:00
Luke SandbergandGitHub 63375cd1f7 Fix termination handling (#95692)
## Follow-ups for the experimental TypeScript CLI checker

Two independent improvements to the `experimental.useTypeScriptCli`
build path.

### 1. Make `tsc` responsive to interruption

When `next build` is interrupted (Ctrl-C / `SIGTERM`), the TypeScript 7
native compiler could keep running to completion instead of stopping —
leaving a CPU-heavy process alive after the build was abandoned.

The teardown already handled termination signals and killed the whole
process group; the problem was the signal it sent. The native compiler
ignores `SIGTERM`/`SIGINT`, so the graceful signal never stopped it. We
now escalate to `SIGKILL` (Windows: `taskkill /T /F`), which reaps the
compiler on interrupt (measured ~200ms vs. running to completion).

The compiler's signal handling may be improved upstream — see
[microsoft/typescript-go#4592](https://github.com/microsoft/typescript-go/pull/4592),
which threads an interruption `context` through `tsc build`. That work
is still in progress; until it lands and ships, this escalation is what
makes interruption reliable.

### 2. Skip the jest worker for the CLI checker

The type-check runs in a jest worker to isolate the TypeScript
compiler-API heap so it can be freed after checking. In CLI mode the
compiler runs in a separate `tsc` process, so there is no heap to
isolate and the worker adds nothing but an extra process and
indirection. CLI mode now runs the setup/config path in-process and
spawns `tsc` directly. The TypeScript-API checker is unchanged and still
uses the worker.

### Testing

- Unit tests for `runTypeScriptCli` (spawn options, group-SIGKILL
teardown, signal handling, listener cleanup, captured-output decoding).
- Existing `test/production/app-dir/typescript-cli` integration suite
passes (TS 6, TS 7, opt-in-required, `ignoreBuildErrors`,
`--debug-build-paths`).
- Manually verified against a TypeScript 7 project large enough to
distinguish a real kill from natural completion: the native compiler is
reaped ~200ms after interrupt.

<!-- NEXT_JS_LLM_PR -->
2026-07-13 20:37:03 +00:00
next-js-bot[bot]andGitHub 08f7c980bf Restore canary version 16.3.0-canary.84 after v16.3.0-preview.6 preview release 2026-07-13 19:58:15 +00:00
next-js-bot[bot]andGitHub ea219c9088 v16.3.0-preview.6 v16.3.0-preview.6 2026-07-13 19:58:13 +00:00
Tobias KoppersandGitHub b78f7d3f79 Turbopack: order CSS modules by chunk-group co-occurrence in linearize (#95579)
## Summary

The graph-based CSS chunker's `linearize` step produces the global
module order that `split_into_chunks` then cuts into chunks. It
previously broke ties between ready modules using a weight-sorted stack.

It now prefers the ready module that shares the most chunk groups with
the previously placed module, so modules that are loaded together end up
adjacent in the global order and split into better-aligned chunks. On a
real world example this measurably lowers the modeled chunk-loading
cost, with fewer requests and less over-fetched CSS.

The shared-group count is read from edge weights (how many chunk groups
two modules co-occur in). Since `make_acyclic` deletes edges to break
cycles, it now returns the edges it cut so `linearize` can still count
those conflicting-order co-occurrences — reconstructing the full
co-occurrence without cloning the graph.

## Verification

- `cargo test -p turbopack-core style_groups_graph::tests` (all pass)
- Validated on a real world example that the resulting global order is
deterministic and the modeled chunk-loading cost decreases.

<!-- NEXT_JS_LLM_PR -->
2026-07-13 17:30:46 +00:00
Sebastian "Sebbie" SilbermannandGitHub 41b823880d [test] Disable i18n-api-support deploy test for Turbopack with adapters (#95739) 2026-07-13 14:52:27 +00:00
Sebastian "Sebbie" SilbermannandGitHub a3d7ab97be Fork navigation-testing-lock module (#95611)
Ensures the module graph is not bundled. Right now this has no effect
since all the modules imported by `navigation-test-lock` have legit uses
in prod builds.

Also nice to not have to fork every single implementation inline.
2026-07-13 15:58:02 +02:00
JosephandGitHub c3d1e893b7 docs: runtime prefetching update (#95564)
Sync the runtime prefetching guide with latest App Shell changes
2026-07-13 14:50:06 +02:00
Jimmy LaiandGitHub 4a4590a37c request insights: add agent diagnosis access (4/5) (#93977)
## What

Adds `next experimental-diagnose` and an MCP `get_request_insights` tool
so agents and local users can inspect Request Insights without opening
the DevTools overlay.

Stack:

1. request insights: record local framework spans (1/5)
2. request insights: derive request history and fetch data (2/5)
3. request insights: expose dev snapshots to tools and HMR (3/5)
4. request insights: add agent diagnosis access (4/5) ← current
5. request insights: add DevTools request panel (5/5)

## Review Focus

- CLI error handling and raw JSON output.
- MCP gating when Request Insights is unavailable.
- Telemetry registration for the new MCP tool name.

## Proof In This PR

- `pnpm jest packages/next/src/telemetry/events/mcp-telemetry.test.ts
--runInBand`
- `pnpm --filter=next types`
- Stack-tip smoke verifies `next experimental-diagnose --url
http://localhost:3003 --json` against a real dev server.

## Deferred Coverage

- A more curated agent summary format is intentionally deferred until
the raw private snapshot contract settles.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tim Neutkens <[email protected]>
2026-07-13 14:01:53 +02:00
Niklas MischkulnigandGitHub 93249ee06d Fix Pages router 404 runtime rendering with Adapter (#95264)
The problem is that the adapter expected a `output.pages` for the `/404`
route so that it can add these files to other Pages handlers so that
they can render a 404 at runtime (getStaticProps with
revaliate/getServerSideProps):


https://github.com/nextjs/adapter-vercel/blob/650effd340b4f676a9bca6e0cdaba9bf7d34595a/packages/adapter/src/outputs.ts#L421-L438

https://github.com/nextjs/adapter-vercel/blob/650effd340b4f676a9bca6e0cdaba9bf7d34595a/packages/adapter/src/node-handler.ts#L331-L340

But this 404 Pages handler was not actually emitted if it was
prerendered, where it only emitted the `/404.html` static file. But
that's not what the adapter needs.

Tests:
1. Run as an e2e test
2. Add a variant with dynamically rendered 404 pages

Full e2e test run:
~~https://github.com/vercel/next.js/actions/runs/29081105397~~
https://github.com/vercel/next.js/actions/runs/29087851475

Closes NEXT-4947
2026-07-13 09:56:16 +02:00
Niklas MischkulnigandGitHub db1f3a64da Fix duplicate static files in adapter (#95681)
When using `nextConfig.i18n`, then static files for `404.html` and
`500.html` were added multiple times to the list.

These duplicate entries in `outputs.staticFiles` ended up causing race
conditions in the Vercel adapter because the same output file path was
written concurrently by multiple file operations.
2026-07-13 09:44:27 +02:00
Vercel Release BotGitHubnext-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
4736452efa Update font data (#95725)
This auto-generated PR updates font data with latest available

Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-13 09:03:46 +02:00
eaf66e8e19 [test] Disable middleware-rewrites deploy test for Turbopack with adapters (#95680)
Co-authored-by: Niklas Mischkulnig <[email protected]>
2026-07-13 06:36:36 +00:00
next-js-bot[bot]andGitHub a7bf1202de v16.3.0-canary.84 v16.3.0-canary.84 2026-07-12 23:33:22 +00:00
Jimmy LaiandGitHub 31541356c2 request insights: expose dev snapshots to tools and HMR (3/5) (#93976)
## What

Adds the `experimental.requestInsights` flag, a private dev snapshot
endpoint, and HMR snapshot/update transport so running dev servers can
expose recent request insights to tools and browser clients.

Stack:

1. request insights: record local framework spans (1/5)
2. request insights: derive request history and fetch data (2/5)
3. request insights: expose dev snapshots to tools and HMR (3/5) ←
current
4. request insights: add agent diagnosis access (4/5)
5. request insights: add DevTools request panel (5/5)

## Review Focus

- Dev-only gating for `experimental.requestInsights`.
- Private endpoint behavior when enabled and disabled.
- HMR snapshot/update shape and client-side retention.

## Proof In This PR

- `pnpm --filter=next types`
- Stack-tip Cache Components smoke verifies the endpoint and HMR-fed
overlay state against a running dev server.

## Deferred Coverage

- A dedicated isolated dev-server transport test can follow if reviewers
want cheaper per-PR coverage than the stack-tip smoke.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tim Neutkens <[email protected]>
2026-07-12 13:47:39 +02:00
Jimmy LaiandGitHub 510d00b51f request insights: derive request history and fetch data (2/5) (#93975)
## What

Builds the bounded request history store on top of local spans and fetch
metrics. Request Insights now keeps the last 100 requests, dedupes fetch
records, and preserves raw span details for later verbose consumers.

Stack:

1. request insights: record local framework spans (1/5)
2. request insights: derive request history and fetch data (2/5) ←
current
3. request insights: expose dev snapshots to tools and HMR (3/5)
4. request insights: add agent diagnosis access (4/5)
5. request insights: add DevTools request panel (5/5)

## Review Focus

- The request insight schema shared by server, tools, and DevTools.
- Fetch cache/status mapping from existing `AppRender.fetch` spans.
- Dedupe between completed fetch spans and direct fetch metrics.

## Proof In This PR

- `pnpm jest packages/next/src/server/lib/trace/request-insights.test.ts
packages/next/src/server/lib/patch-fetch.test.ts --runInBand`
- `pnpm --filter=next types`

## Deferred Coverage

- Browser/HMR transport, CLI/MCP access, and the visual panel are later
PRs.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tim Neutkens <[email protected]>
2026-07-12 13:47:38 +02:00
Jimmy LaiandGitHub fab0afcbe4 request insights: record local framework spans (1/5) (#93974)
## What

Adds a dev-only local recorder for framework OTEL spans. This lets Next
mirror span data into an in-memory store when local span capture is
enabled, without requiring a user to run an OTEL provider.

Stack:

1. request insights: record local framework spans (1/5) ← current
2. request insights: derive request history and fetch data (2/5)
3. request insights: expose dev snapshots to tools and HMR (3/5)
4. request insights: add agent diagnosis access (4/5)
5. request insights: add DevTools request panel (5/5)

## Review Focus

- Local recorder behavior when no OTEL provider is installed.
- Preserving existing OTEL span API behavior when a provider is
installed.
- Request identity propagation through existing app render async
storage.

## Proof In This PR

- `pnpm jest packages/next/src/server/lib/trace/tracer.test.ts
packages/next/src/server/lib/trace/span-store.test.ts --runInBand`
- `pnpm --filter=next types`

## Deferred Coverage

- Request-level aggregation, fetch enrichment, dev transport, CLI/MCP
access, and the DevTools panel are later PRs in this stack.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tim Neutkens <[email protected]>
2026-07-12 13:47:38 +02:00
next-js-bot[bot]andGitHub 1bd2fd585a v16.3.0-canary.83 v16.3.0-canary.83 2026-07-10 23:34:00 +00:00
Will Binns-SmithandGitHub 8b7b6fea86 Turbopack tests: remove assertions that duplicate webpack results (#95688)
We forked test assertions in places in the early days of merging
Turbopack. Now that we more closely align, a bunch of these had the
exact same assertions. Fold them into one.
2026-07-10 12:11:26 -07:00
Sam PoderandGitHub 4b1c74a3bc Fix support for custom-media-queries in LightningCSS (#95689)
Closes https://github.com/vercel/next.js/issues/95677. Added an e2e test
that roughly matches the original issue and tests that it works.
2026-07-10 19:07:17 +00:00
Benjamin WoodruffandGitHub 0cfc85ceae Clarify AI-assisted contribution policy in PR template and AGENTS.md (#95629)
## Summary

Documents the policy around AI-assisted contributions, for both humans
and agents:

- `.github/pull_request_template.md`: notes that AI use is encouraged
for researching, creating, and reviewing changes, but contributors must
deeply understand their contributions, and PR descriptions from external
contributors must be written by a human.
- `.github/ISSUE_TEMPLATE/1.bug_report.yml`: adds the equivalent note
for bug reports — issue descriptions from external contributors must be
written by a human, though AI may help create reproductions.
- `AGENTS.md`: replaces the old "PR Descriptions" section with two new
sections. "GitHub Pull Requests" distinguishes branch PRs (agents may
write descriptions) from fork PRs targeting `vercel/next.js` (agents may
not). "GitHub Issues, Comments, and Discussions" restricts agent-written
issues, discussions, and comments to members of the
`vercel`/`vercel-labs` GitHub orgs, tells agents how to check membership
via the GitHub API, lists what agents can still help non-members with
(drafting details, reviewing, reproductions, translation, searching for
duplicates), and carves out exceptions (commenting on the user's own PR,
Vercel-operated bots, GitHub/Graphite review bots, and forks of the
repo).
- Renames the LLM watermark marker from `NEXT_JS_LLM_PR` to
`NEXT_JS_LLM` everywhere it appears (`AGENTS.md`,
`contributing/repository/pull-request-descriptions.md`, and the
`create-pr`/`backport-pr` skills), since it now also applies to issues,
discussions, and comments. Nothing in the repo consumes the old marker
name.
- `.agents/skills/create-pr/SKILL.md`: adds a "Fork PRs vs Branch PRs"
section referencing the `AGENTS.md` policy. Assorted typo fixes along
the way.

## Verification

- `gh api /user/memberships/orgs` and `gh api
orgs/vercel/members/<login>` (confirmed the documented membership checks
work and return the documented statuses)
- Not run: no test/build commands (docs-only change; prettier applied
via the pre-commit hook)

<!-- NEXT_JS_LLM -->
2026-07-10 11:27:52 -07:00
Aurora ScharffandGitHub 2ff53d5e6a docs: add Building guide (#94999)
Adds a **Building** guide (`docs/01-app/02-guides/building.mdx`): what
`next build` does, how to read the route table (`○` Static, `◐` Partial
Prerender, `ƒ` Dynamic), prerendering dynamic routes with
`generateStaticParams`, streaming request-time work, and debugging
prerender errors. Also links the guide from the deploying page and the
`next build` CLI reference.
2026-07-10 19:00:21 +02:00
Aurora ScharffandGitHub 736ec44388 docs: add incremental adoption path to Cache Components migration guide (#95325)
## Summary

Adds a clear incremental adoption path to the Cache Components migration
guide and reorganizes the workflow sections so they read in dependency
order.

- New **Adopting incrementally** section documenting the staged flow:
enable the flag, opt routes out with `instant = false` (including the
`cache-components-instant-false` codemod for a one-pass opt-out), fix
synchronous IO, then convert routes one at a time.
- Makes explicit that **synchronous IO cannot be deferred** by `instant
= false` (it is an unconditional prerender build error), and documents
the actual fix: move the call to request time via `<Suspense>` +
`connection()` or a Client Component. Previously the guide only said to
"fix it," implying every route could be deferred.
- Groups the workflow sections (`Following validation`, `Opting out of
validation`, `Adopting incrementally`) together before the per-API
reference, instead of leaving them stranded in the middle of the
reference list.
- Cross-links the adoption skill's **Incremental** mode to the manual
`Adopting incrementally` flow so readers see they are the same workflow,
automated vs. by hand.

## Verification

- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--write docs/01-app/02-guides/migrating-to-cache-components.mdx` (clean)
- Verified the sync-IO behavior against source (`throwIfSyncIOUsed` runs
before the `allowEmptyStaticShell` / `instant = false` gate in
`dynamic-rendering.ts`).
- All intra-page anchor links and the `cache-components-instant-false`
codemod anchor confirmed to resolve.

<!-- NEXT_JS_LLM_PR -->
2026-07-10 18:14:37 +02:00
Janka UrygaandGitHub 46681d90f0 [PPF] Sync IO is only allowed in the dynamic stage (#95384)
This PR makes Sync IO behavior more restrictive when
`partialPrefetching` is on (either globally or for a page).

- Previously, we allowed `await cookies(); Date.now()` in in segments
that won't ever be runtime prefetched. This was achieved by separating
segments into "early" and "late" stages and only erroring in the "early"
ones.
- After this PR, it will always be an error to do sync IO anywhere other
than after `io()`/`connection()`/uncached IO (i.e. outside the Dynamic
stage).

We're doing this mainly because with `partialPrefetching`, `cookies()`
resolves in App Shells, and sync IO causes a severe deopt in any
prerender. `allow-runtime` also opts a route into `partialPrefetching`,
which means that even the segments above the runtime prefetch boundary
will need an App Shell and can't tolerate Sync IO.

This PR removes all early/late stage separation, because we no longer
need to vary the Sync IO behavior on the segment. Instead, we now pick
whether a stageController should use
- `SyncIOMode.AllowedInRuntimeOrDynamic` (legacy)
- `SyncIOMode.AllowedInDynamic` (`partialPrefetching`)
- `SyncIOMode.Untracked` if it needs to opt out

I've removed the existing tests that asserted that sync IO is allowed in
segments above the `allow-runtime` boundary. Instead, we check that sync
io either errors (if partialPrefetching is on) or is allowed (if
partialPrefetching is off)

Closes NAR-855
2026-07-10 15:36:41 +00:00
Janka UrygaandGitHub 3c995a87c1 refactor: remove unnecessary switches from StagedRenderingController (#95383)
We have a couple switches in `StagedRenderingController` where the main
purpose ends up being eliminating `Before/Dynamic/Abandoned` (i.e. the
start and the end stages). Since we migrated everything to
`RENDER_STAGE_ORDER` loops, we no longer really need to list all the
intermediate stages out explicitly in these switches. It's enough to
rule out the "special" stages and let the rest of the code be generic.
This saves some work when adding/removing intermediate stages.

View with "hide whitespace", otherwise it looks messy.
2026-07-10 14:47:05 +00:00
3bb780e7d6 Keep the request body a plain Readable after middleware so Readable.toWeb() doesn't hang (#95607)
Recreation of https://github.com/vercel/next.js/pull/95370

### What's the problem?

A `POST` (or `PUT`/`PATCH`) request that passes through middleware
returning `NextResponse.next()` hangs indefinitely when the downstream
handler reads the body via Node's `Readable.toWeb()`. The request never
completes and eventually times out.

Reproduction: https://github.com/abir-taheer/next-js-readable-stream-bug

### Root cause

When middleware runs, `runMiddleware` clones the request body and later
calls `finalize()`, which grafts the buffered stream back onto the
original `IncomingMessage` via `replaceRequestBody()`
(`packages/next/src/server/body-streams.ts`). `replaceRequestBody`
copies the buffered stream's enumerable properties onto the request.

The buffered stream (`p2`) was a `PassThrough` — a `Duplex` — so its
writable-side internals (`_writableState` plus the enumerable `Writable`
methods like `write`/`end`) were copied onto the `IncomingMessage`.
Because that `_writableState.finished` is `false`, Node stream utilities
that inspect it — including `Readable.toWeb()`, which uses
`finished()`/end-of-stream detection — treat the request as a still-open
writable stream and wait forever.

`NextResponse.rewrite()` is unaffected (it builds a new internal request
and skips this path), and `GET`/`HEAD` requests are fine because there
is no body to clone.

### The fix

`p2` is only ever fed with `.push()`, so it never needs a writable side.
Making it a plain `Readable` instead of a `PassThrough` keeps the
finalized request a pure `Readable`, so `Readable.toWeb()` (and any
other duck-typing based on `_writableState`) behaves correctly. No
behavior change for the existing consumers, which only read the stream.

### Testing

Added `test/unit/body-streams.test.ts`, which drives the real clone →
`finalize()` flow and asserts the finalized request:
- is no longer writable (`_writableState` is `undefined`), and
- is fully consumable via `Readable.toWeb()` (this hangs before the
fix).

Fixes #95335

<!-- NEXT_JS_LLM_PR -->

Co-authored-by: UditDewan <[email protected]>
Co-authored-by: Baradhan-Madhu <[email protected]>
2026-07-10 15:55:29 +02:00
JosephandGitHub a37068f525 docs: note default error/not-found UI follows OS color scheme, not app theme (#95673)
Guidance for those who don't customize their own not-found page, pages
router's 404, etc, because the defaults honor the system style, not any
app-level theme settings.
2026-07-10 15:40:39 +02:00
Janka UrygaandGitHub 50510910f8 test: skip redbox check in "static prefetch - missing suspense around search params" (#95670)
this has been very flaky recently, see
[datadog](https://app.datadoghq.com/ci/test/runs?query=test_level%3Atest%20%40git.repository.id%3A%22github.com%2Fvercel%2Fnext.js%22%20%40test.name%3A%22instant%20validation%20dev%20-%20client%20navigation%20invalid%20-%20static%20prefetch%20-%20missing%20suspense%20around%20search%20params%22%20%40test.type%3A%22turbopack%22%20%40test.status%3A%22fail%22&agg_m=count&agg_m_source=base&agg_t=count&fromUser=false&index=citest&start=1783042724737&end=1783647524737&paused=true)

we had similar problems with the `runtime prefetch - missing suspense
around search params` test from the same suite. still unsure about the
cause, but redbox seems to not appear sometimes during client
navigations. this does not seem to be a problem with instant validation
itself, because it runs and forwards the errors to the browser as
expected, so i suspect this is a bug with the redbox. as a workaround we
assert on the instant validation CLI output instead.
2026-07-10 15:17:19 +02:00
Janka UrygaandGitHub 5b4d844a04 test: allow-runtime breaks Link's Server component child detection (#95596)
See NAR-876. We discovered this problem in #95384, when removing the
Early/Late stage split, but it turns out that this was a preexisting
race that occurs for runtime-prefetchable segments the problem existed
before for runtime (which currently render in EarlyStatic, a task
earlier than non-runtime-prefetchable segments)

adds failing tests for `passHref` with allow-runtime (i.e. when the
segment runs early), and passing tests for it in the dynamic stage (when
the passHref is gated behind dynamic, which seems to delay it long
enough for the debug channel to initialize)
2026-07-10 15:16:41 +02:00
Niklas MischkulnigandGitHub 3ebd45b154 docs: Immutable static assets (#95348)
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Signed commits

- This repository requires verified commit signatures on protected
branches.
- If this pull request is blocked for unsigned commits, re-sign the
commits and force-push the branch.
- A `Signed-off-by` line in the commit message is not enough.


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2026-07-10 10:54:55 +02:00
Sam PoderandGitHub 359d66817a [turbopack] Simplify service worker e2e tests (#95672)
This PR simplifies the way that we're preserving
`registration.updateViaCache` after the code-gen that rewrites the
options in the service worker registration
2026-07-10 10:50:03 +02:00
Sam PoderandGitHub 9317a54179 [docs] Update "Handling a Custom Service Worker" in the CRA migration docs (#95434)
This is a follow-up to https://github.com/vercel/next.js/pull/95431; I
think we can directly mention this in this guide to make people's lives
easier (the PWA guide is quite long for this small chunk of code)
2026-07-09 23:05:00 -07:00
Sam PoderGitHubvercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
affd86f0bf [docs] Update progressive web apps documentation for new service worker syntax (#95431)
We recently rolled out this new syntax for bundling service workers with
Turbopack:

```
await navigator.serviceWorker.register(new URL('../lib/service-workers/1.js', import.meta.url), ...)
```

This PR updates the documentation that previously mentioned service
workers.

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-07-09 23:05:00 -07:00
Tim NeutkensandGitHub a249dcbcee (TypeScript 7 Support) Add experimental TypeScript CLI backend (#95639)
## Summary

- add `experimental.useTypeScriptCli` so projects can explicitly run
their local `tsc` during `next build`, including TypeScript 7 while the
legacy JavaScript API is unavailable
- preserve the TypeScript API backend as the default, with TypeScript
6-compatible dependency installation and actionable TypeScript 7
migration guidance
- load effective compiler metadata through `tsc --showConfig`, preserve
inherited path origins, stream native diagnostics, redirect incremental
state, and forward worker termination to the compiler process tree
- document the experimental behavior and cover TypeScript 6/7, both
bundlers, raw diagnostics, full-project checking, dependency selection,
and cleanup

## Demo

```
pnpm build

> [email protected] build /Users/timneutkens/projects/sandbox/cna
> next build

▲ Next.js 16.3.0-canary.81 (Turbopack)
✓ Running next.config.ts took 23ms
- Cache Components enabled
- Experiments (use with caution):
  ✓ useTypeScriptCli

  Creating an optimized production build ...
✓ Compiled successfully in 3.9s
  Running TypeScript ...
app/page.tsx:8:3 - error TS2322: Type 'string' is not assignable to type 'number'.

8   return count++ + "abc";
    ~~~~~~


Found 1 error in app/page.tsx:8

Failed to type check.

Next.js build worker exited with code: 1 and signal: null
 ELIFECYCLE  Command failed with exit code 1.
```


## Verification

- `pnpm test-start-turbo
test/production/app-dir/typescript-cli/typescript-cli.test.ts`
- `pnpm test-start-webpack
test/production/app-dir/typescript-cli/typescript-cli.test.ts`
- `pnpm test-start-turbo
test/production/ci-missing-typescript-deps/index.test.ts`
- `pnpm test-dev-turbo
test/development/typescript-native-preview/index.test.ts`
- `pnpm test-start-turbo test/production/typescript-basic/index.test.ts`

<!-- NEXT_JS_LLM_PR -->
2026-07-09 18:43:12 -07:00
next-js-bot[bot]andGitHub a30d8b2c17 v16.3.0-canary.82 v16.3.0-canary.82 2026-07-09 23:41:26 +00:00
Sam PoderandGitHub c594b9fb4b [turbopack] Compile service workers registered from pages router pages (#95583)
Thanks @mischnic for catching this! I've added a test to ensure that
service workers work in pages router.
2026-07-09 16:26:18 -07:00
Sam PoderandGitHub 29bbdfbdee [turbopack] Output service workers to /_next/static/ (#95554)
This should fix deployment tests because this now re-uses Vercel's
support for static JS files
2026-07-09 15:17:50 -07:00
Luke SandbergandGitHub fb55cfb0dc Reduce the size of OperationVc from 8 bytes to 4 (#95614)
Reduce the size, i don't really expect much of a win, but this is low
hanging fruit and removes a few branches as well.

Consolidate the implementation of CollectibleSource, no need for
OperationVc to delegate to RawVc here.
2026-07-09 22:17:26 +00:00
Vercel Release BotGitHubnext-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
90dd06c240 Upgrade React from df4bd1b4-20260708 to 5123b063-20260708 (#95642)
Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-09 21:45:06 +02:00
Tim NeutkensandGitHub 836ba3708b Add attribute rendering benchmark (#95621)
### What?

Add two dynamic routes to the render-pipeline benchmark and include both
in the default route suite:

- `/attributes` renders 1,000 rows with string, data, ARIA, title, and
inline-style attributes.
- `/tailwind` renders a realistic dashboard with dense Tailwind-style
utility class names across navigation, metrics, project cards, and an
activity table.

### Why?

The existing benchmark routes focus on lightweight rendering or Suspense
and Flight payload stress. They do not provide focused integration
coverage for React Fizz attribute serialization.

`/attributes` provides a synthetic stress case modeled after the
upstream React benchmark for facebook/react#36899. `/tailwind`
complements it with a production-like component tree and realistic class
strings, including responsive, state, dark-mode, and arbitrary-value
utilities.

### How?

Both fixtures run through the real Next.js production-server
render-pipeline harness and are forced dynamic so every request
exercises server rendering.

The Tailwind-style fixture contains 18 project cards, 36 activity rows,
and 101 `className` attributes. It intentionally does not install or
configure Tailwind because the benchmark targets React serialization of
the class strings, not generated CSS or visual styling.

The new routes are registered in the default stress suite and documented
in the benchmark playbook and render-pipeline README.

### Verification

- Prettier for all changed files
- ESLint for both benchmark fixtures and
`bench/render-pipeline/benchmark.ts`
- Production `next build` + `next start` smoke benchmark for
`/tailwind`; single-client and under-load phases completed with zero
request errors
- Three interleaved base/head `/attributes` runs with 500 serial and
5,000 loaded requests
- `/attributes` PR-head median throughput: +8.26% single-client and
+10.85% under load
- `/attributes` PR-head median p95: 7.91% better single-client and 9.61%
better under load
- `git diff --check`

<!-- NEXT_JS_LLM_PR -->
2026-07-09 20:43:31 +02:00
d44ee523d8 docs(opengraph-image): load assets at module scope to keep route static under Cache Components (#95246)
### What?

Document loading request-independent assets at module scope, and update
the OG image examples to follow it.

### Why?

Reading a local asset inside the component is async I/O during render,
so the route defers to request time. A top-level `await` at module scope
keeps the route prerendered without reaching for `use cache`. The
pattern previously only lived as an inline snippet in the OG image docs.

### How?

- Add an "Asynchronous I/O at module scope" section to the Cache
Components guide as the canonical explanation.
- Load fonts and local assets at module scope in `opengraph-image.mdx`
and `image-response.mdx`, and link both to the new section.

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Joseph <[email protected]>
2026-07-09 19:59:00 +02:00
Jude GaoandGitHub 34d92a5026 Convert agent-041's blocking-data check to the agentic LLM judge (#95630)
Make the ppr test accept diverse solutions as long as they lead to a
static shell. Achieved by `expect(environment).toSatisfyCriterion`
(a.k.a., llm-as-judge)
2026-07-09 10:13:37 -04:00
Vercel Release BotGitHubnext-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
216c900597 Upgrade React from 12a4baec-20260707 to df4bd1b4-20260708 (#95612)
Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-09 10:37:34 +02:00
Jude GaoandGitHub eeb59c12aa Make the agent-rules block verifiable and self-upgrading (#95467)
Agents have started flagging the managed `nextjs-agent-rules` block as
prompt injection and refusing to follow or commit it (#95130). Headless
A/B evals (Claude Code + Sonnet 5, pnpm-monorepo and standalone-npm
fixtures, `[email protected]`) isolate the triggers:
`node_modules/next/dist/docs/` doesn't resolve from the workspace root
in non-hoisted installs, the "maintained by `next dev`" claim is
unverifiable, and the **Keep this block** paragraph reads as a
self-persisting instruction. The failure concentrates on the uncommitted
state a fresh `next dev` run produces.

The block now anchors the docs path to the block file's directory with a
monorepo note, and replaces the commit imperative with a verify pointer
to `generate-agent-files.js` plus the reason committing it keeps the
tree clean. This is the only change in this PR, and it was ablated in
isolation — an A/A run of the baseline first established the noise floor
(block committal 0/5, 0/8, 1/8 across three independent baseline
batches):

| Metric | Old block | New block |
|
---------------------------------------------------------------------------------
| --------- | --------- |
| Uncommitted block, diff-review prompt — committed the block | 1/21 |
8/20 |
| Uncommitted block, diff-review prompt — final message calls it a
prompt injection | 12/21 | 4/20 |
| Committed block, task prompts — injection flags | 0/15 | 0/15 |
| Docs reads/run — standalone app, write tests (n=2) | 4.5 | 5.0 |
| Docs reads/run — monorepo, add page (n=3) | 3.7 | 4.0 |
| Docs reads/run — monorepo, write tests (n=10) | 3.4 | 2.6 |

Committal improves at p = 0.008 and injection accusations drop at p =
0.016 (Fisher exact); runs that follow the verify pointer conclude
"genuine framework-scaffolded content, not injected". A candidate
follow-up — appending "commit this change" to the dev-server log line —
was ablated separately and does nothing: the line reaches the agent's
transcript in 12/12 dev-session runs but committal stayed 0/6 vs 0/6, so
it is not included. The upsert machinery that delivers this rewording to
existing projects is #95470.
2026-07-08 22:59:06 -04:00
Jude GaoandGitHub 86ff18a4be Refresh outdated agent-rules blocks on next dev and codemod upgrade (#95470)
Once the managed agent-rules block is installed, `next dev` never
touches it again — `ensureAgentRulesForDev` gates on marker presence —
and `@next/codemod upgrade` doesn't refresh it either, so changes to the
block's content (like the wording fix in #95467) never reach existing
projects.

`next dev` now gates on `hasCurrentAgentRules` and re-upserts a block
whose content differs from canonical, targeting whichever file already
hosts it so an upgrade rewrites the block in place instead of
duplicating it into a second file; legacy `NEXT-AGENTS-MD` blocks
migrate the same way, and CRLF files keep their line endings.
`@next/codemod upgrade` refreshes the block after the version bump by
delegating to the installed package's own generator
(`next/dist/server/lib/generate-agent-files`), so the codemod never
carries a copy of the wording and no-ops below 16.3 or when the project
never adopted the block. A malformed block (start marker without end)
converges to a single canonical block within two runs rather than
growing unboundedly.

The e2e test now covers the in-place upgrade (surrounding content
preserved, exactly one block, no `CLAUDE.md` created when `AGENTS.md`
hosts it) and idempotence across dev-server restarts, using the real
generator's output rather than hardcoded wording.
2026-07-08 22:58:49 -04:00