35031 Commits

Author SHA1 Message Date
next-js-bot[bot] d73f5622e2 v16.3.0 v16.3.0 2026-08-03 20:06:44 +00:00
Joseph 2e0d4cbe5d Edits to turbopackFileSystemCache (#96531)
- Rework the
`/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache`
API reference.
- Adjust the table notes in
`/docs/app/api-reference/turbopack#configuration` — `[^1]` works well,
but the table notes are auto-magically placed at the bottom of the page.
Going with this hand rolled table notes for now.
- Tidy the Build Caching section in
`/docs/app/api-reference/turbopack#configuration`
- Update the Upgrade to version 16 section on dev/build cache
- Removed the `Build caching` from Webpack gaps
  - Added Filesystem caching to Performance and Fast Refresh
2026-08-03 22:04:23 +02:00
Joseph 86df9c7588 docs: cover direct visits and client navigations in the instant() e2e example (#95803)
Reworks the instant-navigation guide's e2e testing example to cover both
ways a route is reached: a direct visit (SSR document load) and a client
navigation.

Each test wraps the navigation in `instant()` and asserts the shell
renders while the streamed content is held back, then appears after.

Also documents where the testing API is available: automatically under
`next dev`, and in a production build via
`experimental.exposeTestingApiInProductionBuild`.

Closes:
https://linear.app/vercel/issue/DOC-6477/instant-e2e-helper-for-ssr-and-soft-navs-snippets-show-difference

---------

Co-authored-by: Aurora Scharff <aurora.sofie@gmail.com>
Co-authored-by: Aurora Scharff <66901228+aurorascharff@users.noreply.github.com>
2026-08-03 22:00:06 +02:00
Sam Poder 47a52c0d6b [turbopack / next.js] Add an end-to-end test for new root detection (#96544)
Follow-up PR to https://github.com/vercel/next.js/pull/96159, adding an
end to end test that specifically tests the new stuff in that PR!
2026-08-03 12:58:53 -07:00
Andrew Clark 8e878d4848 Remove implicit Partial Prefetching opt-in from instant (#96539)
Previously, adding a truthy `instant` config to a route segment (e.g.
`export const instant = true`) did two things: it enabled instant
navigation validation, and it implicitly opted the route into Partial
Prefetching.

Now those concerns are fully separate. `instant` only controls
validation, so enabling it no longer silently changes how a route is
prefetched. Partial Prefetching is enabled with the `prefetch` segment
config (`'partial'` or `'unstable_eager'`), or globally with the
`partialPrefetching` option in next.config.

For routes whose only opt-in was a truthy `instant`, `<Link
prefetch={true}>` goes back to performing a legacy full prefetch instead
of being downgraded to a partial one. `instant = false` still opts a
route out of the dev-time `prefetch={true}` warning.

Adds a regression test asserting that a route that only exports `instant
= true` keeps the full-prefetch behavior.
2026-08-03 19:56:47 +00:00
Tim Neutkens e37ddd19f5 Fix deploy test TypeScript exclusions (#96545)
## Summary

Set `NEXT_PRIVATE_LOCAL_DEV=1` for directory fixtures in deploy mode,
matching the next-start setup. This keeps copied test runner files
excluded from TypeScript checks when deployment tests use
`tsconfig.test.json`.

## Verification

- `pnpm exec tsc --project test/lib/tsconfig.json --noEmit`
- Not run: deployment tests (requires Vercel deployment credentials)

<!-- NEXT_JS_LLM -->
2026-08-03 19:35:17 +00:00
Aurora Scharff 8a4920c15a docs: clarify first-party Skills workflows (#96495)
## Summary

- clarify how runtime foundations, interactive workflows, and unattended
loops fit into the AI agents and Instant Navigation guides
- harden the Cache Components and Partial Prefetching Skills around
capability checks, trustworthy `instant()` tests, route scope, and
real-app verification failures
- add migration-guide comments to temporary Partial Prefetching route
config and update `remove-partial-prefetch` to remove only generated
comments while preserving runtime-prefetch TODOs and user comments

This keeps the experimental Partial Prefetching optimizer in #96471
separate.

## Testing

- `pnpm --filter @next/codemod build`
- `pnpm --filter @next/codemod test --
transforms/__tests__/remove-partial-prefetch.test.js --runInBand`
2026-08-03 19:23:56 +00:00
Marcos Hernanz 4344b83a6b Flag newly disabled deploy tests (#96505)
## What changed

Added scoped review guidance under `test/` so Vercel Agent flags changes
that newly disable deploy-mode tests or assertions.

## Why

Deploy coverage should only be disabled for assertions that are
inherently self-hosted-specific. When deployed behavior differs, the
test should prefer documenting those semantics instead of skipping
deploy mode.

## Validation

- `pnpm install --frozen-lockfile`
- `pnpm build-all`
- Hosted Vercel Agent E2E: an intentional `skipDeployment: true` probe
was flagged inline, then removed
- Hosted Vercel Agent Review passed on the final diff
2026-08-03 19:29:36 +02:00
Joseph 459617a125 fix: double fragment on navigation (#93132)
Fixes: https://github.com/vercel/next.js/issues/93126,
https://github.com/vercel/next.js/issues/95551

Repro:

- from `/` navigate to `/abc#foo`
- on `/abc#foo` - now click `/abc#bar`
- the url is now at `/abc#foo#bar`

Unlike, https://github.com/vercel/next.js/pull/93855, this PR fixes what
gets stored in the segment cache navigation, rather than slicing away an
existing hash. It is plausible that dropping the hash from the segment
cache is not desired though.
2026-08-03 18:21:06 +02:00
Tim Neutkens cbf0cef687 Enable TypeScript CLI by default (#96497)
## Summary

Enable the project-local TypeScript CLI checker by default during `next
build`, while preserving `experimental.useTypeScriptCli: false` as an
opt-out to the TypeScript compiler API. Update the TypeScript 7
guidance, diagnostics, tests, and documentation to match the new
default.

## Verification

- `pnpm exec jest --runTestsByPath test/unit/isolated/config.test.ts`
- Pre-commit lint-staged checks passed (Prettier and ESLint)
- Not run: `pnpm test-start-turbo
test/production/app-dir/typescript-cli/typescript-cli.test.ts` (isolated
fixture dependency installation was blocked by unavailable npm registry
access)
- Not run: `pnpm --filter=next types` (repository has pre-existing
unrelated TypeScript errors)

<!-- NEXT_JS_LLM -->
2026-08-03 18:10:51 +02:00
Zack Tanner dcdacfd036 test: skip hybrid not-found coverage for the legacy builder (#96534)
## Summary

The `pages-router-app-not-found` test verifies behavior implemented by
the Next.js adapter. The legacy `@vercel/next` builder has a
pre-existing behavior where it prefers the Pages Router error page for
this hybrid routing case.

Skip this test when deployment tests run without the adapter. It will
continue running in development, `next start`, and adapter deployment
tests.

## Verification

- `NEXT_TEST_MODE=deploy NEXT_ENABLE_ADAPTER=0 pnpm testheadless
test/e2e/app-dir/pages-router-app-not-found/pages-router-app-not-found.test.ts`
- `pnpm testheadless
test/e2e/app-dir/pages-router-app-not-found/pages-router-app-not-found.test.ts`
2026-08-03 08:36:57 -07:00
Joseph 2aef3b816f docs: ISR with Cache Components and Partial Prefetching (#96526)
App Shell upgrade for prerendered fallbacks, are now gated behind
`partialPrefetching`.
2026-08-03 17:15:00 +02:00
David Alexandru Ilie da90782311 Fix App Router scroll padding visibility (#96308)
## Summary

- Treat the root `scroll-padding-top` as the lower boundary of the
usable viewport during App Router navigations, so content obscured by a
sticky header is not incorrectly considered visible.
- Preserve the merged Fragment scroll-ownership state machine: empty
Fragments remain unavailable targets, while real targets are classified
against the padding-aware viewport.
- Resolve pixel and percentage values and use the same visibility rule
in both the legacy element handler and the Fragment-ref handler.
- Add regression coverage showing that Next scrolls when the destination
is hidden inside the padding boundary, while preserving the current
scroll position when the destination is genuinely visible below it.

## Performance

The root computed style is resolved lazily, only after the candidate
produces client rects. Empty Fragments and hash navigations do not
perform this lookup. For a real route-scroll target, the resolved value
is cached locally and reused by the second geometry check after
`scrollTop = 0`.

This does not add work to scroll events or every render, and keeping the
value local allows responsive CSS, root classes, and custom properties
to change between navigations. In a 50-iteration dirty-style Chromium
probe, both the existing and updated paths reported 50 style
recalculations and 50 layouts, indicating that the lookup reused the
style/layout update already required by the handler in that test.

## Related work

#96342 is now merged into `canary` and handles empty Fragment scroll
ownership. This PR composes with its `NoClientRects` / `InViewport` /
`OutOfViewport` state machine by changing only the visible-region
boundary for real targets.

## Verification

- `HEADLESS=true pnpm test-dev-turbo
test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts -t "scroll
padding"` (3/3)
- `HEADLESS=true __NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER=false pnpm
test-dev-turbo
test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts -t "scroll
padding"` (3/3)
- `HEADLESS=true pnpm test-dev-turbo
test/e2e/app-dir/parallel-routes-scroll-owner/parallel-routes-scroll-owner.test.ts`
(8/8)
- `HEADLESS=true pnpm test-dev-webpack
test/e2e/app-dir/parallel-routes-scroll-owner/parallel-routes-scroll-owner.test.ts`
(8/8)
- `HEADLESS=true pnpm test-dev-turbo
test/e2e/app-dir/navigation-focus/navigation-focus.test.ts` (5/5)
- Manually compared the same sticky-header reproduction before and after
the change.

<!-- NEXT_JS_LLM -->
2026-08-03 16:00:14 +01:00
Hendrik Liebau c00449d52b [ci] Wait for the preview tarballs before running the deploy tests (#96527)
The "Test new and changed tests when deployed" jobs install Next.js from
the preview tarballs built for the commit under test, but nothing made
them wait for those tarballs to exist. Until #96438 the job was ordered
behind `test-prod` and the other new-test jobs, which delayed it long
enough that the tarballs had usually landed by the time it looked for
them. Now that it starts immediately it frequently fails with "Artifacts
not found for commit ...".

The ordering cannot be expressed as a `needs:` entry, because the
tarballs are published by a different workflow and, for pull requests
from branches in this repository, a different event than the
`build-and-test` run that consumes them. We therefore add a
`wait-for-preview-tarball` job that polls for the tarball instead, and
make both deploy test jobs depend on it. Doing the waiting in one cheap
job keeps the deploy test matrices off their 16-core runners until there
is something for them to install.

The new job is also listed in `tests-pass`. A dependency failure skips
the jobs that need it, and a skipped job does not count as a failure, so
without that entry a tarball that never arrives would have let the
required check pass with the deploy tests never having run.

`test-new-tests-deploy-cache-components` gets the same treatment,
dropping the incidental ordering it still inherited from
`test-cache-components-prod` and picking up the docs-only guard that
`test-new-tests-deploy` already had.
2026-08-03 16:27:51 +02:00
Steven 767e0e98db [turbotrace] bump test version of sharp (#96386)
Regenerate the lockfile to test if the previous PR still works with the
latest sharp

- https://github.com/vercel/next.js/pull/94845
2026-08-03 15:42:02 +02:00
Janka Uryga 331739243f [Cache] Make caches error if called after prerender aborts (#96426)
Closes #96339

Caches that started filling after a prerender was aborted would produce
an empty stream, because an aborted `renderSignal` made [the signal we
pass to `prerender()` inside `use-cache-wrapper`] be aborted
immediately. So we produced an empty entry and saved it, essentially
poisoning the cache.

Fixed by removing `renderSignal` from the `AbortSignal.any(...)` we pass
in and returning a rejected promise before we get to the cache filling
codepath. This should not be observable to userspace because the
prerender is already aborted.
2026-08-03 11:42:26 +00:00
next-js-bot[bot] 4fd843fb48 v16.3.0-canary.107 v16.3.0-canary.107 2026-08-02 23:34:28 +00:00
Tim Neutkens 3d4d46f1c9 Enable Turbopack build filesystem cache by default (#96493)
## Summary

Enable `experimental.turbopackFileSystemCacheForBuild` by default in all
environments, including generic CI. Explicitly setting the option to
`false` remains the opt-out. Update the focused coverage and
documentation to match.

## Verification

- `IS_TURBOPACK_TEST=1 pnpm test-start-turbo
test/e2e/filesystem-cache/build-cache-default.test.ts`
- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--check packages/next/src/server/config-shared.ts
test/e2e/filesystem-cache/build-cache-default.test.ts
docs/01-app/03-api-reference/08-turbopack.mdx
docs/01-app/03-api-reference/05-config/01-next-config-js/turbopackFileSystemCache.mdx`
- Not run: `pnpm --filter=next build` (the checkout has 11 pre-existing
TypeScript errors in unrelated files)

<!-- NEXT_JS_LLM -->
2026-08-02 11:33:33 -07:00
next-js-bot[bot] 9480f7f9ff v16.3.0-canary.106 v16.3.0-canary.106 2026-08-01 23:33:55 +00:00
Hendrik Liebau ccd47cfe53 Warn that experimental.useCache is deprecated (#96448) 2026-07-31 20:26:10 -04:00
Zack Tanner 893121b887 Fix hybrid Pages/App Router not-found rendering with adapters (#96392)
## Summary

When Pages Router and App Router routes coexist, a Pages Router route
that returns `notFound` will internally hand rendering to the App Router
not-found page. Next.js [prefers the App Router `/_not-found` entry for
404
responses](https://github.com/vercel/next.js/blob/5f5e4773bbb54f19697063ea093e8d89ca7d081a/packages/next/src/server/base-server.ts#L2965-L2980)
before falling back to a Pages Router `/404` page.

When deployed via an adapter, this means it would have attempted to
resume the Pages entry, which wouldn't contain the relevant prerendered
shell or postponed state. If the not-found page suspends, its response
cannot be resumed using the metadata associated with the Pages Router
output.

For adapter requests, this marks the handoff with an empty postponed
state. This uses the existing resume protocol to perform a complete,
non-cacheable dynamic render. `next start` continues to use the normal
PPR path, where it can load and resume the App Router not-found output
directly.

This trades PPR shell reuse for correctness only during this
cross-router not-found handoff. Longer term, adapters should have an
explicit contract for cross-output handoffs so they can select and
resume the App Router not-found output normally, without necessarily
declaring the pages router output PPR-capable.

The change also documents the empty postponed-state contract and adds
deployment regression coverage.

## Verification

- Added an end-to-end test that verifies a Pages Router `notFound`
response includes the dynamic App Router not-found content when
deployed.
- `pnpm testheadless test/e2e/app-dir/pages-router-app-not-found`
- `pnpm --filter=next types`

<!-- NEXT_JS_LLM -->
2026-07-31 16:40:37 -07:00
next-js-bot[bot] a8dcd2562f v16.3.0-canary.105 v16.3.0-canary.105 2026-07-31 23:35:12 +00:00
Zack Tanner f7f2036ee2 test: stabilize after() deploy revalidation checks (#96428)
## Summary

[PR #96354](https://github.com/vercel/next.js/pull/96354) changed
`retry()` to enforce its duration as a wall-clock budget instead of
effectively treating it as a retry count. This exposed the test’s
previous two-second budget, which did not reliably cover the intentional
one-second `after()` delay plus deployment and ISR latency.

Separates the callback delay from the ISR settling timeout and waits for
timestamp reads to stabilize before establishing a baseline.

<!-- NEXT_JS_LLM -->
2026-07-31 14:44:10 -07:00
Marcos Hernanz 439163392d Add automated code review workflow (#96359)
## Summary

Adds one protected `pull_request_target` workflow for advisory automated
review of non-draft, member-authored PRs.

The existing Vercel reviewer runs Codex, Claude, and synthesis with
read-only GitHub access. This base-owned workflow treats that result as
untrusted, validates it, and owns the only GitHub mutation.

## Write boundary

- no checkout, PR code execution, dependency installation, Actions
secrets, or shell interpolation
- globally empty permissions; the job has only OIDC and pull-request
read
- exact repository, event, author association, PR state, base SHA, and
head SHA validation
- final read-only PR revalidation immediately before publishing
- HTML comments stripped, mentions neutralized, token patterns redacted,
and output capped at 48 KB
- a write token is minted only after validation
- exactly one top-level comment `POST` or `PATCH`
- existing comments are eligible only when attributed to one of gh-sts's
immutable `general` GitHub App IDs and begin with the fixed marker
- both actions are pinned to immutable commit SHAs

The workflow intentionally runs once on `opened` or `ready_for_review`;
it does not run on `synchronize`.

## Validation

- `actionlint`
- Prettier
- syntax validation of all three embedded `github-script` programs
- upstream commit verification for both pinned actions
- independent Codex and Claude autoreview

The workflow remains inert until the matching gh-sts policy is approved.
2026-07-31 17:32:32 -04:00
Sam Poder fd6f11baf3 [turbopack] Introduce documentation on experimental.turbopackChunking (#96437)
Pulled out of https://github.com/vercel/next.js/pull/96398, wanted to
edit this a bit before pushing.
2026-07-31 14:21:34 -07:00
Sebastian "Sebbie" Silbermann e89118a0ab [react-sync] Enable auto-merge on PRs (#96442)
Saves a click. These PRs still require approval as per repo settings.

The commit description is empty so that the React PRs aren't mentioned
again in commits. That'd be pretty noisy for the React PRs.
2026-07-31 21:03:23 +00:00
Sebastian "Sebbie" Silbermann dc358f450c [ci] Run new/changed deploy tests asap (#96438)
These are equally important if not more important (since they test build
adapters) than next-start tests so we now run them immediately instead
of waiting for test-prod.

They job is now skipped entirely for docs changes. Which saves a few
seconds for docs-only changes.
2026-07-31 20:12:30 +00:00
Vercel Release Bot f5c81a82c1 Upgrade React from 0f42eac2-20260730 to cbb046ab-20260731 (#96434)
Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-31 15:27:34 -04:00
Sam Poder a2d558629b [turbopack] Fix component chunks for workers (#96432)
#95261 began to set `module_chunks` on browser chunks so that we can
track components this meant that chunks stopped always being plain path
strings:

```rust
if included.is_empty() && excluded.is_empty() && module_chunks.is_empty() {
    return EcmascriptChunkData::Simple(path);   // bare string
}
EcmascriptChunkData::WithRuntimeInfo { .. }     // object
```

This broke workers when I was testing on `vercel/front`.
2026-07-31 11:12:22 -07:00
Tobias Koppers 6523a33f78 Enable turbopackFileSystemCacheForBuild by default (#96395)
### What?

Makes `experimental.turbopackFileSystemCacheForBuild` (Turbopack's
on-disk
filesystem cache for `next build`) enabled by default, matching the
dev-mode
flag. It stays disabled by default in non-Vercel CI environments, and
can
always be turned off explicitly with
`experimental.turbopackFileSystemCacheForBuild: false`.

### Why?

The build filesystem cache greatly speeds up warm builds, but was
previously
opt-in (only auto-enabled for canary builds on the Vercel builder).
Defaulting
it on gives everyone faster subsequent builds, while keeping it off in
non-Vercel CI where the cache is unlikely to persist between builds.

### How?

- `turbopackFileSystemCacheForBuildDefault()` now returns `true` except
when
  `isCI && !NOW_BUILDER` (removed the `isStableBuild()` gate).
- The explicit `false` opt-out already works via the existing
  `config.experimental?.turbopackFileSystemCacheForBuild || false` read.
- Adds an e2e test (`test/e2e/app-dir/turbopack-fs-cache-build-default`)
asserting `.next/cache/turbopack` is written by default, empty when the
flag
  is `false`, and empty in non-Vercel CI.
- Updates the `turbopackFileSystemCache` / Turbopack docs.

<!-- NEXT_JS_LLM -->

---------

Co-authored-by: vercel-fleet[bot] <308483924+vercel-fleet[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
2026-07-31 13:24:40 -04:00
Sebastian "Sebbie" Silbermann 7612eaeda1 Consolidate unhandled rejection logging into a single listener (#95999)
An unhandled rejection was previously logged by up to three independent
process listeners at once: the render runtime's crash-prevention handler
in `process-error-handlers.ts` (a bare `console.error`), the router
server's `Log.error('unhandledRejection: ', err)`, and the dev server's
`logErrorWithOriginalStack`. The runtime handler must exist on every
deployment target (#77997), but on self-hosted `next start`/`next dev`
it shares a process with the router server's and dev server's listeners,
so a single rejection was logged multiple times in different formats.

THe first commits adds a test showing the current behavior where we log
multiple times.

The second commit introduces `registerUnhandledRejectionListener` and
`isUnhandledRejectionListenerRegistered` in `process-error-handlers.ts`,
and converts the router server and dev server to check-then-register
instead of installing their own rejection loggers:

- The listener function is shared via a `Symbol.for` key on
`globalThis`, so multiple copies of the module (e.g. in the pre-compiled
server bundle and in a route module bundle) register and detect a single
listener instance.
- The registration check queries
`process.listeners('unhandledRejection')` instead of a module-global
flag, so it stays accurate even after external code calls
`process.removeAllListeners`. `installProcessErrorHandlers` therefore
calls the register function unconditionally.

The `uncaughtException` handlers are left as they are; they have the
same duplication and could be consolidated the same way in a follow-up.
2026-07-31 11:36:40 -04:00
Zack Tanner 9bfaf63edb Fix adapter outputs for not-found routes when used with cache components (#96390)
## Summary

Fix the build output for App Router `not-found` routes that get
partially prerendered when cacheComponents is enabled.

Previously, Next.js treated any statically generated `/_not-found` route
as a complete static 404, even when it contained postponed state. It
copied the partial HTML shell to `server/pages/404.html` and omitted the
corresponding `/_not-found` prerender from adapter outputs.

This change distinguishes fully static not-found routes from partially
prerendered ones. Fully static routes retain the existing `404.html`
behavior, while PPR routes remain resumable prerender outputs.

This allows a `not-found.tsx` that suspends under Cache Components to
render its dynamic content when deployed.

Closes https://github.com/vercel/next.js/pull/96399

## Testing

Expanded `not-found-non-document-dynamic` coverage to verify that:

- dynamic not-found content renders for ordinary missing paths
- dynamic not-found content renders when `/_not-found` is selected by a
rewrite
- a PPR not-found does not emit `server/pages/404.html`
- its adapter output includes `PARTIALLY_STATIC` metadata, postponed
state, and a resume chain

Also verified that fully static App Router not-found routes continue to
emit and serve `pages/404.html`.

- `__NEXT_CACHE_COMPONENTS=true pnpm test-start-turbo
test/e2e/app-dir/not-found-non-document-dynamic/not-found-non-document-dynamic.test.ts`
- `pnpm test-start-turbo test/e2e/app-dir/not-found/basic/index.test.ts`
2026-07-31 08:30:57 -07:00
Sebastian "Sebbie" Silbermann be7048ef91 Update @types/react and @types/react-dom to latest (#96419) 2026-07-31 11:29:57 -04:00
Joseph 6f7ed2ecb9 docs: document the App Shell stale time threshold for cached content (#96312)
Closes:
https://linear.app/vercel/issue/DOC-6480/app-shells-exclude-stale-5-minutes-caches
2026-07-31 10:15:09 -04:00
Sam Poder b4e3fecc79 [turbopack] add experimental.turbopackChunking config (#96398)
Built using @sokra's Fleet! This re-arranges all of our chunking
experimental features under `experimental.turbopackChunking` and adds
the following options:

```javascript
/**
 * Avoid creating more than one chunk smaller than this size, in bytes. Smaller
 * chunks are merged into bigger ones to avoid that. Defaults to `50000` (50 KB).
 */
minChunkSize?: number
/**
 * Avoid creating more than this number of chunks per chunk group. Chunks are
 * merged into bigger ones to avoid that. Defaults to `40`.
 */
maxChunkCountPerGroup?: number
/**
 * Never merge chunks bigger than this size, in bytes, with other chunks. This keeps code
 * in big chunks from being duplicated across multiple chunks. Defaults to `200000` (200 KB).
 */
maxMergeChunkSize?: number
/**
 * Minimum size, in bytes, for a component chunk to be emitted on its own when
 * `generateComponentChunks` is enabled. Component chunks smaller than this are folded into a
 * single remainder chunk. Defaults to `20000` (20 KB).
 */
minComponentChunkSize?: number
```
2026-07-30 23:37:37 -07:00
Andrew Clark e3d634e0bc Fix isHeadPartial when hydrating from a static fallback shell (#96400)
When a static fallback shell is served as-is — e.g. from a CDN in a
deployed environment — the client can't hydrate from inline Flight data;
it fetches the full RSC payload separately and reconstructs the initial
payload on the client. During that reconstruction, the head's partiality
flag was accidentally set to the head itself. Since the head is always
truthy, the head was unconditionally treated as partial.

This happens to be unobservable today: the only flows that reach the
reconstruction are fallback-shell prerenders, where the server
pessimistically marks the head partial anyway, and when Cache Components
is enabled the client ignores the per-payload flag entirely in favor of
response-level partiality. But we're about to rework the RSC response
format so that head partiality has a single, load-bearing source of
truth, so the flag needs to survive the reconstruction correctly rather
than by coincidence.

While auditing the payload consumers, I also fixed the payload shape
check in segment prefetch generation (it used `&&` where `||` was
intended, so it accepted any shape) and deleted
`should-hard-navigate.ts`, which no longer has any callers on the
client.

Adds e2e coverage asserting that metadata survives hydrating a fallback
shell page: the title is correct after hydration, the head is included
in prefetched data, and a return navigation is served entirely from the
cache that was populated during initial hydration. In deployed
environments this exercises the client resume path, which is where the
reconstruction runs.
2026-07-31 00:37:15 -04:00
next-js-bot[bot] 38f0cdee46 v16.3.0-canary.104 v16.3.0-canary.104 2026-07-30 23:34:58 +00:00
Sam Poder f84102b831 [turbopack] Respect sideEffects in a package.json file with optimizePackageImports (#96383)
Closes https://github.com/vercel/next.js/issues/96333 by re-ordering the
statements in `get_side_effect_free_declaration`. The rest of this PR is
then a test + adding to a test fixture. This seems like a reasonable
change to me as we'd match Webpack's behaviour.

---------

Co-authored-by: Luke Sandberg <lukesandberg@users.noreply.github.com>
2026-07-30 16:25:08 -07:00
Sam Poder f389fc4d74 [turbopack] Keep track of components of the remainder chunk (#96409)
At the time we had assumed that these components would not be helpful,
however, things can get put in the remainder that can be used on other
routes so it is worthwhile to keep track of them.
2026-07-30 15:50:45 -07:00
Will Binns-Smith 1c39fcafdb Update Rust toolchain to nightly-2026-07-29 (#96365)
This updates to nightly-2026-07-29

---------

Co-authored-by: vercel-fleet[bot] <308483924+vercel-fleet[bot]@users.noreply.github.com>
Co-authored-by: Will Binns-Smith <755844+wbinnssmith@users.noreply.github.com>
2026-07-30 15:11:40 -07:00
Zack Tanner bfb0d3c1b9 Remove obsolete shouldWaitOnAllReady render option (#96401)
## Summary

`shouldWaitOnAllReady` previously allowed an otherwise dynamic App
Router render to wait for every Suspense boundary before sending the
response. After [#96367](https://github.com/vercel/next.js/pull/96367),
no caller enables this behavior anymore.

This removes the unused option and makes `supportsDynamicResponse` the
sole signal for whether App Router generates static HTML. Static
generation still waits for `allReady`, while dynamic responses continue
streaming.

<!-- NEXT_JS_LLM -->
2026-07-30 14:52:48 -07:00
Vercel Release Bot a49f1c97e6 Upgrade React from 6cb4322d-20260729 to 0f42eac2-20260730 (#96402)
Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-30 17:21:07 -04:00
Zack Tanner 0b3ce7b8fe fix: respect htmlLimitedBots in cache components without buffering the full response (#96367)
## Summary

DOM-capable crawlers can consume streamed metadata, but with
cacheComponents enabled, it treated them like HTML-limited bots and
forced a full dynamic render. This meant capable crawlers could not use
the prerendered shell even when they were not matched by
`htmlLimitedBots`.

This change lets DOM-capable crawlers follow the normal PPR shell and
streaming-metadata path. `htmlLimitedBots` remains the source of truth
for requests that need blocking metadata, including when a custom
pattern explicitly matches a DOM-capable crawler.

## Test Plan
Tests were added that contained a Suspense boundary that intentionally
never resolves. The test reads the response stream until it receives the
fallback, then verifies that blocking metadata has already been emitted
while the unresolved page content has not. A fully buffered response
would never return, so this avoids relying on timing or arbitrary
delays.

This PR is stacked on #96366.
2026-07-30 13:30:41 -07:00
Zack Tanner 4cf9c9e68e test: expand Cache Components metadata streaming coverage (#96366)
## Summary

Expand Cache Components metadata streaming coverage across the default,
custom, and wildcard `htmlLimitedBots` configurations.

The active matrix now covers regular user agents, configured
HTML-limited bots, built-in bot classifications, metadata placement for
static and dynamic routes, PPR shell behavior, streaming versus buffered
responses, and hydration after revalidation. It replaces the skipped
legacy PPR metadata suite with active Cache Components coverage.
2026-07-30 13:30:41 -07:00
Steven 8ca5321d08 fix(create-next-app): make AGENTS.md blue (#95432)
I noticed that this last question for AGENTS.md doesn't have any blue
highlighted word.

So I made AGENTS.md blue to follow the convention of the others.

<img width="865" height="163" alt="image"
src="https://github.com/user-attachments/assets/d10f74e1-f5ec-4c8a-9c6d-8d01b9c1abf3"
/>

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-07-30 15:54:22 -04:00
dan c53c0a5dd8 [bench skill] Bench Edge builds of React too (#96234)
Extends the bench to run the edge versions of React SSR fixture.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 19:55:25 +01:00
Vercel Release Bot 5f5e4773bb Upgrade React from 1724e9ce-20260729 to 6cb4322d-20260729 (#96389) 2026-07-30 17:49:17 +00:00
David Alexandru Ilie e689163afb Fix empty Fragment scroll ownership (#96342)
## Summary

- treat Fragment instances without client rects as unavailable route
scroll targets
- leave the shared scroll signal unconsumed so another changed segment
can handle an empty route Fragment
- avoid focus and scroll side effects when an empty segment cannot claim
ownership
- consume and clear an explicit hash intent when no matching target
exists, without falling back to route content
- cover empty and visible intercepted routes across both scroll
handlers, including focus preservation and real hash scrolling

This PR is stacked on #96323, which provides the minimal reproduction.

## Verification

- `HEADLESS=true pnpm test-dev-turbo
test/e2e/app-dir/parallel-routes-scroll-owner/parallel-routes-scroll-owner.test.ts`
(8/8)
- `HEADLESS=true pnpm test-dev-webpack
test/e2e/app-dir/parallel-routes-scroll-owner/parallel-routes-scroll-owner.test.ts`
(8/8)
- `HEADLESS=true pnpm test-dev-turbo
test/e2e/app-dir/navigation-focus/navigation-focus.test.ts` (5/5)

<!-- NEXT_JS_LLM -->
2026-07-30 18:37:14 +01:00
Marcos Hernanz 7e01f56f5b Skip reader task locking for immutable Turbo Tasks reads (#96179)
## What changed

Tracked output and cell reads now acquire the target task first. If the
target is already immutable, the read skips locking the reader task
because no dependency edge can be added and the target cannot be
invalidated. Mutable targets drop the speculative target lock and
reacquire the target/reader pair together, preserving the existing
invalidation-race guarantee.

`verify_immutable` deliberately retains the pair-lock path. Listener
diagnostics also preserve the tracked reader ID when the fast path skips
its guard.

The separate current-task ID cache is in #96180. This PR is now
backend-only so the lock-ordering change can receive focused backend
review.

## Why

The previous path locked both the target and reader task for every
tracked read. That synchronization is necessary for mutable targets but
redundant once the target is immutable. Instrumentation found that
1,541,880 of 4,501,364 sampled tracked reads (34.254%) could use the
bypass.

## Performance evidence

Measured at `0950e8ae05db20c33302f02257114f5b857edabc` on a dedicated
8-vCPU/16-GiB Vercel Sandbox with frozen side-by-side binaries.

These measurements are directional evidence, not precise estimates.
Small percentage changes are difficult to resolve reliably. This
campaign and #96180's incremental campaign used separate run sets: the
absolute endpoint here does not match #96180's starting point, which
demonstrates cross-campaign noise. The values must not be compared
across PRs, and their percentages must not be added.

### Browser-driven HMR, 30-second B/C/C/B

- Evaluation: 20.771360 → 19.176645 ms (**-7.677%**)
- Commit: 21.714832 → 20.371425 ms (**-6.187%**)

### Production builds

- First 12-campaign matrix: **-1.931%**
- Complementary 12-campaign matrix: **-1.990%**
- Combined 24-campaign aggregate: **-1.959%**

Five of six balanced blocks favored the candidate. The conservative
six-block 95% interval was -4.042% to +0.248%, so the production
estimate is supporting evidence rather than a precise claim.

### Causal profiles

- HMR `Storage::access_pair_mut` self time fell from 3.19%/3.19% to
1.21%/1.18%.
- HMR voluntary context switches fell 32.898%.
- Production pair-access self time and voluntary context switches also
fell; production voluntary switches changed -14.552%.
- All accepted perf captures reported zero lost samples.

## Validation

On the exact backend-only head
(`9ccfd6753526f716466a9584fba8c8753b7d83bf`):

- Complete `turbo-tasks-backend` package tests, integrations, and
doctests
- Complete backend package matrix with `--features verify_immutable`
- `cargo fmt --check -p turbo-tasks-backend`
- `cargo clippy -p turbo-tasks-backend --all-targets -- -D warnings`
- `git diff --check`
- Conflict-free merge-tree check against current `canary` (`5cdcbbb05b`)
2026-07-30 10:02:16 -04:00
Vercel Release Bot 769d9e6e03 Upgrade React from 96fcba90-20260728 to 1724e9ce-20260729 (#96355)
Co-authored-by: next-js-bot[bot] <279046576+next-js-bot[bot]@users.noreply.github.com>
2026-07-30 13:51:10 +00:00