17115 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann 766148f9cd v16.2.5 2026-05-06 19:06:11 +02:00
Zack Tanner 0dd94836a8 fix: add explicit checks for RSC header (#83) (#98)
(cherry picked from commit 807e363b13cc9395aa74f75122d1d16b4a46dc1a)
2026-05-06 18:02:07 +02:00
Zack Tanner d166096c39 fix proxy matching for segment prefetch URLs (#89) (#96)
* fix: proxy should match segment prefetches for canonical urls

* include .rsc handling
2026-05-06 18:02:06 +02:00
Josh Story 9d50c0b719 Strip next-resume header from incoming requests (#92)
This header is used by proxies to perform a concatenating resume render for partial prerendering. It is never sent from the client so we can filter it out when running in a mode that does not have an intermediate proxy.
2026-05-06 18:02:06 +02:00
Zack Tanner df7ab5ad72 fix: skip internal param normalization in unsupported environments 2026-05-06 18:02:06 +02:00
Josh Story ed41d1d454 Move htmlescape to shared/lib (#91)
we have auditing that server files aren't included in client chunks but the new htmlescape usage in next/script is causing that validation to fail. This refactors the utility into lib/shared
2026-05-06 18:02:06 +02:00
JJ Kasper b4c6705c70 Ignore malformed CSP nonce headers 2026-05-06 18:02:06 +02:00
JJ Kasper 5b194ee2d4 router-server: guard upgrade proxy against absolute-url SSRF (#77)
* test: add rewrite request smuggling coverage

* router-server: guard upgrade proxy against absolute-url SSRF

* test: relax rewrite smuggling socket timeout

* router-server: preserve local websocket upgrades
2026-05-06 18:02:02 +02:00
JJ Kasper cb171d7494 Fix i18n middleware matching for default-locale data routes (#82)
* Fix i18n middleware matching for default-locale data routes

* unskip node middleware on deploy
2026-05-06 17:59:10 +02:00
Sebastian "Sebbie" Silbermann 89e995431a [16.x] Type hardening and performance improvements (#80) 2026-05-06 17:59:10 +02:00
Josh Story 66f6017f15 Escape properties for beforeInteractive scripts (#86)
props set on a next/script with beforeInteractive are serialized as JSON into an inline script to be exectuted prior to hydration by Next.js. The props were not additionally escaped and if user input was rendered as through a script it could allow fro XSS. This has alwways been true if you pass user input into the script body or via dangerouslySetInnHTML however and it is always the developers responsibility to sanitize user input before rendering. However wherever React has some automatic escaping to act as an additional defense against common mistakes leading to vulnerabilities like XSS Next.js should mirror that becasue from the user's perspective it is not clear that React is not directly rendering the script props and content.

This change adds additional escaping so that serialized properties cannot break out of the script scope and execute unexpected payloads.
2026-05-06 17:59:10 +02:00
Hendrik Liebau 3d98505a24 [backport] fix: preserve HTTP access fallbacks during prerender recovery (#93470)
Backports:

- #92231

---------

Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Co-authored-by: Andrew Clark <git@andrewclark.io>
2026-05-06 14:49:29 +02:00
Hendrik Liebau f1c11203d5 [backport] Fix double-encoding of URL pathname parts in client param parsing (#93506)
Backports:

- #93491
2026-05-06 11:51:44 +02:00
Josh Story 75d19ecbb3 [backport] Include deployment id in cacheHandlers keys (#93471)
Backport #93453 to 16.2

How was this ever working for dev? In that case, `buildId =
"development"` and so it always uses the same cache key

Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
2026-05-05 14:54:04 -07:00
JJ Kasper f6bda26ef9 Fix fallback route params case in app-page handler (#93109)
## Summary
- backport the fallback route params fix from #91737 onto `next-16-2`
- preserve intermediate shells that suspend only for unresolved fallback
params during staged rendering
- add the missing `resolvedRouteParamKeys` request metadata needed by
this branch
2026-04-27 12:28:09 -07:00
Zack Tanner af0e96ba23 Fix invalid HTML response for route-level RSC requests in deployment adapter (#91541)
In a deployed environment, `onCacheEntryV2` determines whether a
postponed response is HTML-origin or RSC-origin by checking whether
meta.url ends with `.rsc`.

For some dynamic full-route RSC requests, Next was passing a URL with
query params into onCacheEntry, for example:
`/[tenant]/samples.rsc?nxtPtenant=tenant-x`

Because that string does not end with .rsc, `onCacheEntryV2`
misclassified the request as HTML and treated it as text/html instead of
an RSC response.

This PR normalizes the URL before passing it to `onCacheEntry`, so the
callback receives the pathname rather than the full URL-with-query.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-04-24 06:18:16 -07:00
JJ Kasper 6fd09bf8ab Patch setHeader for direct route handlers (#93101)
## Summary
- apply the `setHeader` cookie-support patch to direct route module
handlers in `prepare()`
- make `patchSetHeaderWithCookieSupport()` idempotent so both entry
paths can call it safely
- add an adapter-like direct RSC regression test that fails without the
patch

Closes: NEXT-4919

## Testing
- `NEXT_SKIP_ISOLATE=1 NEXT_TEST_MODE=start pnpm testheadless
test/e2e/app-dir/cache-components/cache-components.test.ts -t "should
ignore late setHeader calls for direct RSC handlers after headers are
sent"`

<!-- NEXT_JS_LLM_PR -->
2026-04-21 16:46:27 -07:00
Zack Tanner 688ed31e21 Strengthen _rsc cache-busting param (#92755)
This updates `_rsc` cache-busting param generation to use a stronger
digest so different RSC request variants are much less likely to produce
the same value.

It also updates the related request-validation and injected
resume/instant-test paths so they continue to generate and validate the
same `_rsc` values across client, server, and edge-reachable codepaths.
2026-04-21 16:46:26 -07:00
Steven 62ef305096 fix(next/image): ensure images.maximumResponseBody applies to local images too (#92920)
In a previous PR https://github.com/vercel/next.js/pull/88183, we added
`images.maximumResponseBody` but in only applied to external images.

This PR ensures the same config also applies to internal images.
2026-04-21 16:46:21 -07:00
JJ Kasper 15341fdf49 Ensure x-nextjs-data header is only set during resolve (#92752)
Makes sure we set this header during route resolving so user request
doesn't need to.
2026-04-21 13:53:59 -07:00
nextjs-bot 2275bd8598 v16.2.4 2026-04-15 22:17:07 +00:00
Andrew Imm 6f3808e204 Compiler: Support boolean and number primtives in next.config defines (#92731)
Expand `config.compiler.define` to support number and boolean primitives
as well.

The support is already in Turbopack's rewrite engine, as well as
Webpack's DefinePlugin. We just need to modify the zod schema to
actually support passing numbers and bools.

Added an E2E test that should check all supported types.
2026-04-14 17:32:17 -07:00
Luke Sandberg fbc7684ecb Scope Safari ?ts= cache-buster to CSS/font assets only (Pages Router) (#92580)
### What?

Refactors the Safari `?ts=` cache-busting workaround in the Pages Router so it **only appears on CSS and font URLs**, not on script tags or script preload links.

### Why?

The `?ts=` timestamp was originally added to all preloaded assets as a workaround for a [Safari caching bug](https://bugs.webkit.org/show_bug.cgi?id=187726) (see [#5860](https://github.com/vercel/next.js/issues/5860)). When it appears on `<script>` tags, the Turbopack runtime's `getAssetSuffixFromScriptSrc()` reads the executing script's query string and infers it as the `ASSET_SUFFIX`, which then leaks onto all static asset URLs — including images. This causes `next/image` validation errors because the image URL gets an unexpected `?ts=` parameter.

Fixes #92118

### How?

Instead of maintaining parallel `assetQueryString` (with `?ts=`) and `scriptAssetQueryString` (without `?ts=`) paths, this PR:

1. **`assetQueryString`** carries only the deployment token (`?dpl=...`) and is used for all script-related URLs (script tags, script preloads)
2. **`safariCacheBuster`** is a new, separate field (`?ts=<timestamp>` or `""`) that is only combined with `assetQueryString` at the 3 CSS/font URL sites via a `joinQueryStrings()` helper
3. Removes the `scriptAssetQueryString` / `scriptMutableAssetQueryString` / `cssAssetQueryString` fields entirely

The Safari cache-buster is computed the same way as before (dev server only, Safari user-agent check) — it just no longer contaminates the base query string.

### Test plan

- [x] Updated existing test in `test/e2e/app-document/rendering.test.ts` to assert `?ts=` appears only on `<link rel="preload" as="style">` and `<link rel="preload" as="font">`, and does NOT appear on `<script>` or `<link rel="preload" as="script">`
- [x] `pnpm --filter=next types` passes

<!-- NEXT_JS_LLM_PR -->
2026-04-14 16:55:19 -07:00
nextjs-bot d5f649b2f4 v16.2.3 2026-04-08 18:24:27 +00:00
Sebastian "Sebbie" Silbermann 28739286a8 [16.x] Avoid consuming cyclic models multiple times (#75)
* Avoid consuming cyclic models multiple times

* make types-and-precompiled work
2026-04-08 11:18:58 -07:00
Zack Tanner d7c7765360 [backport]: Ensure app-page reports stale ISR revalidation errors via onRequestError (#92282) (#92519)
Backports:
- #92282
2026-04-08 08:08:57 -07:00
Will Binns-Smith c573e8c4f3 fix(server-hmr): metadata routes overwrite page runtime HMR handler (#92273)
### What?

Fix server HMR becoming unresponsive after a metadata route is loaded in
the same Node.js process as an app page.

### Why?

Turbopack loads separate runtime chunks for app pages and metadata
routes (`robots.ts`, `sitemap.ts`, `manifest.ts`, `icon.tsx`, etc.) in
the same Node.js process. Each runtime chunk embeds `dev-nodejs.ts` and
produces a distinct `__turbopack_server_hmr_apply__` closure bound to
its own `moduleFactories` and `devModuleCache`.

Previously each runtime simply overwrote
`globalThis.__turbopack_server_hmr_apply__`, so the last chunk to load
silently won. Navigating to `/robots.txt` before an HMR update caused
the metadata route runtime to overwrite the page runtime's handler.
Subsequent HMR updates were dispatched only to the metadata route
runtime, which has no knowledge of the page module — the page appeared
frozen and stopped reflecting file changes.

### How?

Replace the bare assignment with a multicast registry:

1. Each runtime appends its own `__turbopack_server_hmr_apply__` handler
to `globalThis.__turbopack_server_hmr_handlers__[]`.
2. The first runtime to register installs a shared dispatcher as
`globalThis.__turbopack_server_hmr_apply__` that iterates all registered
handlers at call time (not install time), so newly loaded runtimes are
always included.
3. On full cache reset, `hot-reloader-turbopack.ts` resets
`__turbopack_server_hmr_handlers__` to `[]` so stale handlers from
evicted chunks don't accumulate into the next generation.

Because `dev-nodejs.ts` is embedded into the Turbopack binary via
`include_dir!`, this fix requires rebuilding the native binary.

### Tests

`test/development/app-dir/server-hmr/server-hmr.test.ts` — extended with
`metadata route hmr` tests that load a metadata route before patching a
page file, verifying HMR updates still reach the page runtime after a
second runtime chunk is loaded.

---------

Co-authored-by: Will Binns-Smith <wbinnssmith@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-07 16:34:28 -07:00
Tobias Koppers f158df18bd Fix styled-jsx race condition: styles lost due to concurrent rendering (#92459)
### What?

Fix a race condition in the Pages Router SSR path where styled-jsx
styles were dropped from the rendered HTML.

### Why?

`styledJsxInsertedHTML()` reads and flushes the styled-jsx style
registry. Previously it was called concurrently with the page render via
`Promise.all`:

```js
const [rawStyledJsxInsertedHTML, content] = await Promise.all([
  renderToString(styledJsxInsertedHTML()),
  (async () => { /* render the page */ })(),
])
```

Because both ran at the same time, `styledJsxInsertedHTML()` could (and
in practice did) execute and flush the registry **before** the page
render had finished populating it. The result was that dynamic
styled-jsx styles — those with interpolated expressions that compute
their class names at runtime via DJB2 hashing — were silently dropped
from the SSR output, causing a flash of unstyled content on first load.

This is particularly visible in production deployments where all
components use dynamic styled-jsx (numeric `jsx-*` class names), since
those styles only exist in the registry after rendering completes.

### How?

Serialize the two operations: render the page first, then call
`styledJsxInsertedHTML()`. Since the registry is fully populated by the
time it is read, all styles are captured correctly.

A new e2e test (`test/e2e/styled-jsx-dynamic`) exercises this scenario
with multiple nested components that all use dynamic styled-jsx with
interpolated props, covering the exact FOUC pattern seen in production.

<!-- NEXT_JS_LLM_PR -->

Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-07 12:07:04 -07:00
nextjs-bot 52faae3d94 v16.2.2 2026-03-31 23:39:18 +00:00
Will Binns-Smith c0edad2762 Turbopack: exclude metadata routes from server HMR (#92034)
### What?

Metadata routes (`manifest.ts`, `robots.ts`, `sitemap.ts`, `icon.tsx`,
`apple-icon.tsx`, etc.) were not being hot-reloaded in Turbopack dev
mode — changes to those files would not be reflected on subsequent
requests until a full server restart.

### Why?

PR #91466 extended `usesServerHmr = true` in `clearRequireCache()` (in
`hot-reloader-turbopack.ts`) from `app-page` entries only to **all**
`app`-type entries (pages + route handlers). The motivation was correct:
regular route handlers like `app/api/hello/route.ts` use Turbopack's
in-place module update model and benefit from server HMR.

However, metadata routes (`/manifest.webmanifest/route`,
`/robots.txt/route`, etc.) are also `app`-type entries but they are
**not** suitable for in-place server HMR. When `usesServerHmr = true`
for a metadata route, `clearRequireCache()` skips two critical
invalidation steps:

1. Deleting the compiled chunk from `require.cache`
2. Calling `__next__clear_chunk_cache__()`

Without those steps, the old module stays in-memory and all subsequent
requests to `/manifest.webmanifest` (etc.) return the stale content.

### How?

Added an `!isMetadataRoute(entryPage)` guard to the `usesServerHmr`
expression in `clearRequireCache()`. This restores full cache
invalidation for metadata routes on every rebuild while leaving regular
route handler server HMR (added in #91466) intact.

```ts
// Before
const usesServerHmr =
  serverFastRefresh &&
  entryType === 'app' &&
  writtenEndpoint.type !== 'edge'

// After
const usesServerHmr =
  serverFastRefresh &&
  entryType === 'app' &&
  writtenEndpoint.type !== 'edge' &&
  !isMetadataRoute(entryPage)   // ← metadata routes always clear the cache
```

`isMetadataRoute('/manifest.webmanifest/route')` → `true` (excluded from
server HMR)
`isMetadataRoute('/api/hello/route')` → `false` (keeps server HMR, no
regression)

Also added a regression test: `metadata route hmr > reflects manifest.ts
changes on fetch/refresh` in the `server-hmr` test suite, with a
`manifest.ts` fixture that starts at `name: 'Version 0'`. The test
patches the file and asserts the updated JSON is returned on the next
fetch.

Fixes #91981

---------

Co-authored-by: Will Binns-Smith <wbinnssmith@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-31 15:03:31 -07:00
Will Binns-Smith d6446990d9 Turbopack: enable server HMR for app route handlers (#91466)
App router handlers are already built with the Turbopack runtime, so
they can use server HMR. **We also already get subscription events for
their chunks.** However, unlike app pages which use
`__next_app__.require()` for dynamic devModuleCache lookup, route
handlers capture userland exports statically in AppRouteRouteModule at
construction time. This change makes routes behave a lot like pages,
dynamically loading the user's code when requests are made. This way, we
can freely invalidate and reload it when changes are made without
evicting the entire require cache.

Only `next dev` uses this lazy evaluation, as `next start` continues to
eagerly import route handlers.

This change removes the `isAppPage` restriction from `usesServerHmr`,
extending server HMR coverage to all App Router entries (pages and route
handlers) built with the Node.js runtime.

For route handlers, we also clear the entry chunk from Node.js
`require.cache` on each rebuild so the next `requirePage()` call
re-executes the entry and obtains fresh module exports from
`devModuleCache` (which HMR updates in-place).

Test Plan: Added an additional e2e test, `with-dep`
2026-03-31 15:03:19 -07:00
Will Binns-Smith 34de2cac29 next.config.js: Accept an option for serverFastRefresh (#91968)
### What?

Adds `experimental.serverFastRefresh` to `next.config.js` so users (and
Next.js plugins) can opt out of server-side Fast Refresh without needing
to pass a CLI flag.

Also adds a `--server-fast-refresh` positive CLI flag (hidden) alongside
the existing `--no-server-fast-refresh`, and emits a warning when the
CLI flag and config value conflict. This is a necessary implementation
detail for `commander` to detect when no option is provided.

### Why?

Certain Next.js plugins have encountered issues with server Fast Refresh
and need a way to disable it programmatically via config rather than
requiring users to modify their start scripts. The CLI-only opt-out
(`--no-server-fast-refresh`) was insufficient for this use case.

### How?

- **`config-shared.ts` / `config-schema.ts`**: Added
`experimental.serverFastRefresh?: boolean` to the `ExperimentalConfig`
type and Zod schema.
- **`router-server.ts`**: Resolves the effective `serverFastRefresh`
value at startup by combining the CLI flag (`opts.serverFastRefresh`)
and `nextConfig.experimental.serverFastRefresh`, with CLI taking
precedence. Emits a `Log.warn` when both are set to conflicting values.
Defaults to `true` when neither is specified.
- **`bin/next.ts`**: Fixed the Commander option definition for
`--no-server-fast-refresh`. Commander's `--no-X` pattern implicitly
creates a positive `--server-fast-refresh` option defaulting to `true`,
which meant `opts.serverFastRefresh` was never `undefined` and the
config value could never take effect. Fixed by explicitly registering a
hidden `--server-fast-refresh` option with `.default(undefined)`.
- **Tests**: Added two new test suites in
`test/development/app-dir/server-hmr/server-hmr.test.ts`:
- `server-hmr config opt-out` — verifies that setting
`experimental.serverFastRefresh: false` in config causes unmodified
dependencies to be re-evaluated (i.e., server HMR is disabled).
- `server-hmr CLI/config conflict warning` — verifies that passing
`--no-server-fast-refresh` when config has `serverFastRefresh: true`
logs the conflict warning.

### Test Plan

- [x] Added e2e development tests
(`test/development/app-dir/server-hmr/server-hmr.test.ts`) — all 8 tests
pass

---------

Co-authored-by: Will Binns-Smith <wbinnssmith@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-31 15:00:21 -07:00
Jude Gao c4779d1b08 [create-next-app] Skip interactive prompts when CLI flags are provided (#91840)
When AI agents run `create-next-app` with explicit flags like
`--typescript --tailwind --eslint --app --src-dir`, the CLI still enters
interactive mode and prompts for any unspecified options:

```
➜ npx create-next-app my-app --typescript --tailwind --eslint --app --src-dir --use-pnpm
✔ Would you like to use React Compiler? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
? Would you like to include AGENTS.md to guide coding agents to write up-to-date Next.js code? › No / Yes
```

Agents can sometimes answer these interactive prompts correctly, but
often they can't. When they fail to navigate the prompts, they fall back
to scaffolding the project themselves from scratch — generating files
based on stale training data. This means they might initialize an app
using deprecated patterns or pin to an older version of Next.js (e.g.
15) instead of the latest. Using `create-next-app` non-interactively is
the best way to ensure agents always produce up-to-date scaffolding.

Previously, `hasProvidedOptions` only skipped the initial "use
recommended defaults?" meta-prompt but still showed individual prompts
for each missing option. Now when any config flags are provided, all
remaining options use the recommended defaults without prompting.

The resolved defaults are printed to stdout so the caller knows exactly
what was assumed and which flags to pass to override:

```
Using defaults for unprovided options:

  --eslint                ESLint (use --biome for Biome, --no-eslint for None)
  --no-react-compiler     No React Compiler (use --react-compiler for React Compiler)
  --agents-md             AGENTS.md (use --no-agents-md for No AGENTS.md)
  --import-alias          "@/*"

To customize, re-run with explicit flags.
```

The `displayConfig` array is extended with a `flags` field so this
output is auto-generated from the same source of truth used for the
interactive prompts. Existing behavior for `--yes`, CI mode, and fully
interactive mode (no flags) is unchanged.
2026-03-31 14:53:34 -07:00
JJ Kasper edcf19ae13 Backport: TypeScript v6 deprecations for baseUrl and moduleResolution (#92130)
backports: https://github.com/vercel/next.js/pull/91855
backports: https://github.com/vercel/next.js/pull/91847
2026-03-31 09:38:57 -07:00
nextjs-bot ed7d2cef24 v16.2.1 2026-03-20 23:23:58 +00:00
JJ Kasper 600cd2fedb Fix adapter outputs for dynamic metadata routes (#91680)
## Summary

This fixes adapter `onBuildComplete` outputs for dynamic metadata
routes.

## Bug

`handleBuildComplete` skipped metadata routes too aggressively via
`isStaticMetadataFile(...)`, so dynamic metadata routes (for example
`robots.txt` / `sitemap.xml` using `connection()`) were omitted from
`outputs.appRoutes`.

## Fix

Only skip metadata routes when they are actually prerendered/static
(present in prerender manifests). Dynamic metadata routes are now
included in adapter `outputs.appRoutes` as expected.

## Tests

Added e2e coverage in `test/e2e/app-dir/adapter-dynamic-metadata`:
- verifies dynamic `robots.txt`, `sitemap.xml`, and `favicon.ico`
functionality
- verifies adapter output classification for non-deploy runs
- skips output-shape verification in deploy mode
- skips the suite in dev mode
2026-03-20 14:30:40 -07:00
Hendrik Liebau 88fc4308e2 Fix server actions in standalone mode with cacheComponents (#91711)
The `staticPathKey` condition added in #91231 inadvertently applies to
server action requests on dynamic SSG routes when `cacheComponents` is
enabled.

Server action fetch requests from the client do not send the `RSC`
header (`rsc: 1`). They only send `Accept: text/x-component` and the
`Next-Action` header. This means `isRSCRequest` and
`isDynamicRSCRequest` are both `false` for action requests. The new
`staticPathKey` condition (`isSSG && pageIsDynamic &&
prerenderInfo?.fallbackRouteParams`) evaluates to `true` for dynamic PPR
routes, setting `staticPathKey` even though `ssgCacheKey` is `null` for
actions.

With `staticPathKey` set, the request enters the fallback rendering
block, which serves the cached fallback HTML shell with the action
result appended to it, instead of responding with just the RSC action
result.

The fix excludes server action requests from the `staticPathKey`
computation by adding `!isPossibleServerAction` to the condition,
restoring the pre-#91231 behavior where `staticPathKey` was always
`null` for server actions in production.

fixes #91662
closes #91677
closes #91669
2026-03-20 14:30:40 -07:00
Tobias Koppers d6195eca8c Fix layout segment optimization: move app-page imports to server-utility transition (#91701)
## Summary

- Add `'turbopack-transition': 'next-server-utility'` to all server-side imports in the `app-page.ts` template so they are properly placed in the server utility layer, rather than relying on `SharedMerged` chunk groups to handle them
- Remove the now-unnecessary `next-server-utility` transition from `fillMetadataSegment` import in `app_page_loader_tree.rs`
- Add `SharedMultiple` chunk group variant to support multiple shared entries without a merge tag
  - This avoid passing the `parent` into `SharedMerged`, which did break the layout segment optimization.
- Refactor `app_module_graphs` to combine `client_shared_entries` + `has_layout_segments` into a single `Option` parameter, simplifying the API and removing the dead code path for non-page endpoints

## Test plan

- [ ] Verify dev and production builds work with app pages that have layout segments
- [ ] Verify route handlers still build correctly (no client runtime entries passed)
- [ ] Run existing app-dir e2e tests
2026-03-20 14:30:00 -07:00
Niklas Mischkulnig 6cb97d6d75 Turbopack: lazy require metadata and handle TLA (#91705)
A regression from #88487

1. Make metadata import lazy with `() => require()`, just like for the layout segments
2. Properly await the return value to better handle TLA modules

This align with Webpack which does this:

<img width="1535" height="509" alt="Bildschirmfoto 2026-03-20 um 11 58 00" src="https://github.com/user-attachments/assets/f2864c86-ccce-4884-8417-c8ae06c05f78" />


Closes PACK-6927
Closes #91700
Closes https://github.com/vercel/next.js/issues/91676
2026-03-20 14:28:49 -07:00
nextjs-bot c5c94dffbf v16.2.0 2026-03-18 17:10:38 +00:00
nextjs-bot 3683192a6b v16.2.0-canary.104 2026-03-18 13:29:38 +00:00
Josh Story 0ca967b863 Add group depth tracking to instant validation boundary discovery (#91208)
The depth-based instant validation previously only iterated
URL-consuming segments as potential shared/new boundaries. Route groups
between URL segments were invisible — when a route group layout with
Suspense was shared in a client navigation, its Suspense appeared to
cover blocking code in the validation render even though it wouldn't in
reality.

This adds a second dimension to the validation iteration: group depth.
At each URL depth, we now also step through route group boundaries. A
new `discoverValidationDepths` function walks the LoaderTree and returns
an array where each entry represents the max group depth at that URL
depth. The validation loop iterates from deepest group depth to
shallowest within each URL depth, stopping on the first error.

Key design decisions:
- URL depth and group depth counters are advanced before the boundary
check, making the boundary condition a simple `nextUrlDepth > depth &&
currentGroupDepth >= groupDepth`
- The synthetic `(slot)` segment that Next.js inserts for parallel slots
is excluded from group depth counting since it doesn't represent a real
navigation boundary
- Group depths are discovered from the LoaderTree rather than the URL
pathname, making the tree the source of truth for validation bounds
2026-03-17 22:14:19 -07:00
Zack Tanner a41bef94c5 improve allowedDevOrigins error (#91521)
This improves the blocked-request warning so it names the actual dev
resource being requested and gives clearer guidance on how to allow it.
When the source host is known, the message includes an inline
`allowedDevOrigins` config snippet; when the source is missing or
opaque, it explains why Next.js cannot infer a host to allow.
2026-03-17 17:35:29 -07:00
Benjamin Woodruff 39e705ca9f Turbopack: Merge release-with-assertions-no-lto profile into release-with-assertions (#91530)
- More profiles means more bloat to the `target` directory and more cold builds.
- There's no practical use case where we'd be okay with the performance hit of `debug-assertions` and not okay with the performance hit of `lto = false`. Neither profile was suitable for benchmarking.
- `release-with-assertions-no-lto` is too long to type and was giving me carpal tunnel.
2026-03-17 16:36:59 -07:00
nextjs-bot 668981482a v16.2.0-canary.103 2026-03-17 23:26:26 +00:00
Zack Tanner b2b802c043 block disallowed dev origins by default (#91507)
This removes the warn-only default behavior and enforces the dev-origin guard by default. Cross-origin requests to internal dev resources now block unless they match the built-in local allowlist or an explicit `allowedDevOrigins` entry. The tests are expanded to cover default blocking, configured-but-not-allowlisted hosts, missing Referer in the no-cors path, and same-site requests without an Origin, and the docs are updated to match the new behavior.
2026-03-17 16:02:33 -07:00
Tim Neutkens 97f420911d Move adapterPath from experimental to stable top-level config (#91535)
## Move `adapterPath` from experimental to stable

Graduates `adapterPath` from `experimental.adapterPath` to a top-level
`NextConfig` option, following the same pattern used for
`cacheHandlers`, `cacheComponents`, `typedRoutes`, and other options
that moved out of experimental.

### Changes

- **Type definition** (`config-shared.ts`): Added `adapterPath` to
`NextConfig` interface, marked `ExperimentalConfig.adapterPath` as
`@deprecated`, moved default value to top-level in `defaultConfig`,
updated `NextConfigRuntime` and `getNextConfigRuntime`
- **Zod schema** (`config-schema.ts`): Added `adapterPath` to top-level
`configSchema`
- **Backward compat** (`config.ts`): Added
`warnOptionHasBeenMovedOutOfExperimental` call so existing
`experimental.adapterPath` configs still work with a deprecation
warning, updated `applyModifyConfig` to read from `config.adapterPath`
- **Runtime references**: Updated `build/index.ts`, `app-page.ts`,
`app-route.ts`, `pages-handler.ts` to use `config.adapterPath` /
`nextConfig.adapterPath`
- **Tests**: Updated 4 test fixture `next.config` files
- **Docs**: Updated app router doc (removed `version: experimental`
frontmatter, top-level config example), pages router doc title, and v16
upgrade guide
2026-03-17 23:28:08 +01:00
nextjs-bot 668f8e3a60 Upgrade React from c80a0750-20260312 to 3f0b9e61-20260317 (#91522) 2026-03-17 22:37:18 +01:00
Tobias Koppers ee1f9d79ad Remove webpack stats generation from Turbopack (#91515)
### What?

Remove the `TURBOPACK_STATS` feature that generated webpack-compatible
`webpack-stats.json` files from Turbopack's output.

**Deleted:**
- `crates/next-api/src/webpack_stats.rs` — the entire 305-line Rust
implementation that built webpack-format stats (assets, chunks, modules,
entrypoints) from Turbopack's module graph

**Rust changes:**
- `crates/next-api/src/lib.rs` — removed `mod webpack_stats;`
- `crates/next-api/src/project.rs` — removed
`should_create_webpack_stats()` which read the `TURBOPACK_STATS` env var
- `crates/next-api/src/pages.rs` — removed `generate_webpack_stats`
import and stats output emission
- `crates/next-api/src/app.rs` — same

**TypeScript changes:**
- `packages/next/src/shared/lib/constants.ts` — removed `WEBPACK_STATS =
'webpack-stats.json'` constant
- `packages/next/src/shared/lib/turbopack/manifest-loader.ts` — removed
`loadWebpackStats()`, `writeWebpackStats()`, `mergeWebpackStats()`, the
`webpackStats` field, webpack type imports, and the `TURBOPACK_STATS`
env guard in `writeManifests()`
- `packages/next/src/server/dev/turbopack-utils.ts` — removed
`shouldCreateWebpackStats` flag and two `loadWebpackStats()` call sites
- `packages/next/src/build/handle-entrypoints.ts` — same

### Why?

This feature is no longer needed and adds dead complexity. It was opt-in
via `TURBOPACK_STATS=1` but nothing in the current codebase or tooling
depends on it.

### How?

Pure deletion — no behavior change for any existing user, as the feature
was opt-in via an environment variable that is no longer checked.

**Intentionally left untouched:**
- Webpack's own `stats.json` generation (non-Turbopack path)
- The Turbopack bundle analyzer / `analyze` feature
- `route-bundle-stats.json` in `.next/diagnostics/`

Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-17 13:58:51 -07:00
Zack Tanner d0a0474d3d fix allowedDevOrigins for no-cors requests (#91506)
This PR makes configured `allowedDevOrigins` apply to cross-site no-cors dev asset requests. When browsers omit Origin for subresource loads, the dev guard now falls back to `Referer` so explicit allowlisted hosts can load `/_next/*` resources in development.

Previously, when `allowedDevOrigins` was configured, cross-site no-cors requests to internal Next.js dev resources were still blocked even for allowlisted hosts, because that code path never consulted the allowlist.
2026-03-17 13:57:40 -07:00