3403 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann 672b02b270 [next-playwright] Use unique cookie values for instant navigation testing lock (#91250)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-16 21:07:56 +00:00
Tobias Koppers e22988e5ee Turbopack: switch chunk/asset hashes from hex to base40 encoding (#91137)
### What?

Switch Turbopack's hash encoding for chunk and asset output filenames
from hexadecimal (base16) to base40, using the alphabet \`0-9 a-z _ - ~
.\`. Version hashes (used for HMR update comparison, not filenames) use
base64 instead.

### Why?

Base40 encodes the same number of bits in fewer characters than hex,
producing shorter output filenames. All 40 characters are RFC 3986
unreserved (URL-safe) and safe on case-insensitive filesystems (macOS
HFS+/APFS, Windows NTFS).

Hash truncation lengths are reduced proportionally to maintain
equivalent collision resistance:

| Context | Before (hex) | After (base40) | Entropy |
|---|---|---|---|
| Content hash in chunk filenames | 16 chars | 13 chars | ~69 bits |
| Content hash in asset filenames | 8 chars | 13 chars | ~69 bits |
| Ident disambiguator hash | 8 chars | 7 chars | ~37 bits |
| Long-path prefix hash | 5 chars | 4 chars | ~21 bits |

### How?

**New encoding module** (\`turbo-tasks-hash/src/base40.rs\`):
- Defines the base40 alphabet and length constants (\`BASE40_LEN_64 =
13\`, \`BASE40_LEN_128 = 25\`)
- Implements a generic \`encode_base40_fixed<N>\` helper to avoid
duplication
- Public API: \`encode_base40(u64) -> String\` and
\`encode_base40_128(u128) -> String\`

**New base64 encoding** (\`turbo-tasks-hash/src/base64.rs\`):
- \`encode_base64(u64) -> String\` — 11-char base64 (no padding) for
version hashes
- Version hashes don't appear in URLs or filenames, so base64 is safe
and shorter

**New \`HashAlgorithm\` variants** (\`turbo-tasks-hash/src/lib.rs\`):
- \`Xxh3Hash64Base40\` and \`Xxh3Hash128Base40\` added alongside
existing hex variants
- Existing hex variants kept for internal manifests and identifiers

**\`ContentHashing\` moved to \`turbopack-core\`**:
- Moved from \`turbopack-browser\` to
\`turbopack-core/src/chunk/mod.rs\` so both \`BrowserChunkingContext\`
and \`NodeJsChunkingContext\` can use it

**Separate chunk vs asset content hashing**:
- \`BrowserChunkingContext\`: \`content_hashing\` renamed to
\`chunk_content_hashing\` (optional), new \`asset_content_hashing:
ContentHashing\` field (non-optional, defaults to 13 chars)
- \`NodeJsChunkingContext\`: new \`asset_content_hashing:
ContentHashing\` field (non-optional, defaults to 13 chars)
- Builder methods: \`use_content_hashing()\` renamed to
\`chunk_content_hashing()\`, new \`asset_content_hashing()\`

**Version hashes switched to base64**:
- \`turbopack-nodejs/src/ecmascript/node/version.rs\`
- \`turbopack-dev-server/src/html.rs\`
- \`turbopack-browser/src/ecmascript/version.rs\`,
\`merged/version.rs\`, \`list/version.rs\`

**Other callers updated** (15 files across turbopack and next-core):
- All chunk/asset content hashing switched from \`Xxh3Hash128Hex\` →
\`Xxh3Hash128Base40\`
- \`ContentHashing::Direct { length }\` reduced from 16 → 13
- Asset path truncations use full 13-char base40 hash (matching chunk
filenames)

**Exception — \`wasm_edge_var_name\`** (\`turbopack-wasm/src/lib.rs\`):
- Kept as \`Xxh3Hash128Hex\` because the hash is used as part of a
JavaScript variable name (\`wasm_{hash}\`), and base40 characters \`-\`,
\`~\`, \`.\` are not valid JS identifier characters.

**Scope — NOT changed:**
- Webpack configuration (unchanged)
- Internal manifests (\`routes_hashes_manifest\`,
\`project_asset_hashes_manifest\`)
- Internal identifiers (font naming, external module hashing, data URI
sources, debug IDs)
- SRI hashes (SHA-based Base64, different purpose)

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 20:38:02 +00:00
Hendrik Liebau c2bba0ea26 Revert legacy PPR removal (#90948)
This caused regressions. Apparently it was not a clean removal.
2026-03-05 23:15:44 +01:00
Jiwon Choi d52d9336d5 Clean up legacy PPR references in test fixtures (#90725)
Stacked on https://github.com/vercel/next.js/pull/90726

Migrate legacy PPR tests to Cache Components
2026-03-04 17:28:15 +00:00
Niklas Mischkulnig 1c1550ca7b tests: Assert dpl query string in all tests for Turbopack (#90592)
Enable skew protection for all start-mode tests when Turbopack is enabled (i.e. not dev). This works by setting `NEXT_DEPLOYMENT_ID` in the test infra

- When running the tests, `packages/next/src/server/lib/router-utils/resolve-routes.ts` now validates that all static asset requests have the correct `?dpl=...` query param value, and returns a 404 if missing.
- It can be disabled with `disableAutoSkewProtection: true` in the test options
- There were various tests that were asserting URLs and were missing the optional `?dpl` at the end.
   - `next.getDeploymentIdQuery()` can be used to get the `?dpl=dpl_123912js` string (or an empty string)
   - `next.getAssetQuery()` currently behaves like `getDeploymentIdQuery`, but will switch to prefer the immutable static token in #88607
2026-02-27 10:06:14 +01:00
Niklas Mischkulnig d1601a14c1 Turbopack: use xxhash3_128 for content hashes (#90583)
Move to 128 bit hashes, so that we can include the untruncated hashes in the manifest in #88607

If anything, this is faster, surprisingly:

```
upgrade twox-hash 448a36b449
    pnpm next build --experimental-build-mode=compile  430.13s user, 73.72s system, 724% cpu, 1:09.53 total
    pnpm next build --experimental-build-mode=compile  430.05s user, 82.51s system, 736% cpu, 1:09.56 total
    pnpm next build --experimental-build-mode=compile  419.95s user, 89.50s system, 697% cpu, 1:13.03 total
    pnpm next build --experimental-build-mode=compile  425.95s user, 75.87s system, 748% cpu, 1:07.00 total

use Xxh3Hash128Hex for content hashes ffd6a87f09
    pnpm next build --experimental-build-mode=compile  397.42s user, 53.18s system, 670% cpu, 1:07.25 total
    pnpm next build --experimental-build-mode=compile  416.68s user, 66.32s system, 762% cpu, 1:03.32 total
    pnpm next build --experimental-build-mode=compile  412.63s user, 68.30s system, 774% cpu, 1:02.12 total
    pnpm next build --experimental-build-mode=compile  419.09s user, 68.57s system, 756% cpu, 1:04.50 total
```


https://github.com/Cyan4973/xxHash says:
| Hash Name     | Width | Bandwidth (GB/s) | Small Data Velocity | Quality | Comment |
| ---------     | ----- | ---------------- | ----- | --- | --- |
| __XXH3__ (SSE2) |  64 | 31.5 GB/s        | 133.1 | 10
| __XXH128__ (SSE2) | 128 | 29.6 GB/s      | 118.1 | 10
| __XXH64__     |    64 | 19.4 GB/s        |  71.0 | 10
| __XXH32__     |    32 |  9.7 GB/s        |  71.9 | 10
2026-02-26 16:40:13 +01:00
Sebastian "Sebbie" Silbermann 7d98e0b534 [test] Include error code in Redbox snapshot (#90497) 2026-02-26 11:01:25 +00:00
Niklas Mischkulnig 02af7ed3a4 test: Improve test assertions to prepare for dpl query string (#90463)
*This doesn't enable skew protection for any new tests, only preparation*

Prepare a lot of test assertions so that they work correctly when a `?dpl=123` query param is present:
- some regexes should accept the query
- some places assumed that the `<script>`'s `src` is a valid pathname, whereas it might have a query param that has to be stripped before removing the path
- some hardcoded build ids instead of `next.buildId`
2026-02-25 12:16:10 +01:00
Niklas Mischkulnig b2f193b096 test: Cleanup and refactoring (#90454)
- `expect(hasImageMatchingUrl(browser, "...")).toBe(true)` has very bad error messages if the assertion fails
- there was a `(process.env.TURBOPACK_DEV ? describe.skip : describe)('production mode',` around a dev test
2026-02-24 20:03:44 +01:00
Niklas Mischkulnig 5c425fe2ce next-image: fix deployment id handling for unoptimized (#90416)
Previously

```jsx
import img from "./x.png";

// x is "/_next/static/media/test.abc123.png?dpl=foo"

<Image id="static-unoptimized" src={x} unoptimized />
```

would lead to `/_next/static/media/test.abc123.png?dpl=foo&dpl=foo`

#90420 adds some related tests for the legacy loader as well
2026-02-24 16:53:03 +01:00
Niklas Mischkulnig 7fc89cc0f4 Fix config.reactProductionProfiling for Webpack (#90430)
Absolutely no idea how this was passing in the integration test setup

For Webpack, setting it via the config was previously completely ignored and only the `--profile` flag was respected
Turbopack was already working correctly: https://github.com/vercel/next.js/pull/84920
2026-02-24 16:11:41 +01:00
Sebastian "Sebbie" Silbermann 212ced6fb0 Revert "keep next-env.d.s unchanged between dev and build" (#90384) 2026-02-23 23:32:06 +01:00
Niklas Mischkulnig 9404b901ab Turbopack: add Rope.content_hash and SHA hashing (#90235)
We want `FileContent.content_hash()` to only hash the content bytes. This is also needed to produce the correct hashes [for SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity)

However, the default `DeterministicHash` and `Hash` impls are ill-suited for that because they're a generic hashing infrastructure.
Hashing only the content bytes isn't what you want actually, otherwise `hash(("a", "b", "c"))`  would be the same as `hash("abc")`
https://doc.rust-lang.org/std/hash/trait.Hasher.html#method.write_str describes this problem as well

This is exactly what we want for Rope though, so this adds a `Rope.content_hash() -> impl DeterministicHash`.

Additionally, this changes `content_hash` to accept a HashAlgorithm to prepare for sha SRI hashes. This required changing the return type to `RcStr`, because of the variable hash lengths. But the return value was always `encode_hex`d everywhere anyway.
2026-02-20 22:25:22 +01:00
Steven 39eb8e0ac4 feat(next/image): add lru disk cache and images.maximumDiskCacheSize (#89963)
This PR adds an LRU disk cache so that reads and writes from the Image
Optimization API will evict old entries based on the value of
`images.maximumDiskCacheSize` configuration.

The LRU ensures that cache reads bump the entry to the top so that they
don't get evicted - only the least recently used entries get evicted.

When `next start` is run, if there is an existing disk cache the we will
replay the files in order to populate the LRU and respect
`images.maximumDiskCacheSize` if it was changed.

If no configuration is provided, default to 50% available disk space.
2026-02-20 20:12:26 +00:00
Niklas Mischkulnig 445d880ef9 test: Don't run integration tests twice for Turbopack (#83335)
This should reduce some duplicate CI jobs.
This split existed to support separate dev/prod manifests for skipping tests. That's not needed anymore, so we can just switch to the Webpack setup. This manual partitioning of `integration` tests into dev vs prod was brittle anyway
We still need this setup for rspack though
2026-02-18 18:57:16 +01:00
Niklas Mischkulnig 0382ecc296 Upgrade Lightning CSS (#88789)
Changelog: https://github.com/parcel-bundler/lightningcss/releases/tag/v1.31.0

- [x] Blocked by https://github.com/parcel-bundler/lightningcss/issues/1137
- [ ] Found https://github.com/parcel-bundler/lightningcss/issues/1151
2026-02-16 09:21:54 +01:00
Jiwon Choi ee76e305cc dx: Include path count in export error message (#89333)
Supersedes https://github.com/vercel/next.js/pull/88910

---
<a
href="https://cursor.com/background-agent?bcId=bc-a05c69b9-7049-4095-8985-761868c63e1c"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-a05c69b9-7049-4095-8985-761868c63e1c"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Sebastian "Sebbie" Silbermann <sebastian.silbermann@vercel.com>
2026-02-14 20:28:28 +00:00
Niklas Mischkulnig f63be5da42 test: Isolate read-only-source-hmr test (#86721)
This was flakey with Turbopack:
```
Error: TIMED OUT: /New page/

404
This page could not be found.

undefined
    at check (/root/actions-runner/_work/next.js/next.js/test/lib/next-test-utils.ts:726:9)
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/integration/read-only-source-hmr/test/index.test.ts:124:7)
```

But somehow Webpack doesn't automatically refresh the page here?



https://github.com/user-attachments/assets/b363dbff-60d1-4813-bb1c-e5a64f0312d3
2026-02-14 11:08:12 +01:00
Niklas Mischkulnig 9e4e6d6f20 Turbopack: fix CSS dependency locations (#89761)
For some locations LightningCSS is 1-indexed (but not all of them, the rustdoc describes it though)
IssueSource is always 0-indexed

Previously, it looked like this
```
Error: Turbopack build failed with 1 errors:
./bench/basic-app/app/[variants]/styles.css:7:12
Module not found: Can't resolve './test1.png'
  5 | .style {
  6 |   cursor: url(./test1.png);
> 7 | }
    |  ^
  8 |
```
2026-02-13 12:01:32 +01:00
Jude Gao b9ec2e4f8d [AI] Ship bundled docs in next and generate AGENTS.md in create-next-app (#89850)
AI coding agents often rely on outdated training data when working with
Next.js projects, leading to hallucinated APIs and deprecated patterns.
This PR addresses that by shipping version-matched documentation inside
the `next` npm package and generating agent instruction files during
`create-next-app`.

During `next` build, a new `copy_docs` task copies `docs/` from the repo
root into `dist/docs/`. Since `"dist"` is already in the package's
`files` array, the docs are automatically published at
`node_modules/next/dist/docs/`.

`create-next-app` gains a new `--agents-md` / `--no-agents-md` flag
(defaults to `true`). When enabled it writes two files:

- `AGENTS.md` — instructs agents to read `node_modules/next/dist/docs/`
instead of relying on training data
- `CLAUDE.md` — uses `@AGENTS.md` import syntax for Claude Code

The option appears in the recommended defaults display and is prompted
during the customize flow. Existing tests are updated with
`--no-agents-md` to avoid the new prompt.
2026-02-11 21:50:12 +01:00
Tim Neutkens 0b32ddc6ab Remove --turbopack and --webpack flags from create-next-app (#89706)
## What?

Remove the `--turbopack` and `--webpack` CLI flags from
`create-next-app`.

## Why?

Turbopack is now the default bundler in Next.js. The `--turbopack` flag
is redundant since it's already the default, and the `--webpack` flag is
no longer needed as a `create-next-app` option. The only alternative
bundler flag retained is `--rspack`.

## How?

- Removed `--turbopack` and `--webpack` option definitions from the CLI
in `packages/create-next-app/index.ts`
- Simplified bundler selection logic: defaults to Turbopack, with
`--rspack` as the only override
- Removed `--turbopack` documentation from
`packages/create-next-app/README.md`
- Removed all `--no-turbopack` flags from test invocations across all
create-next-app test files
- Removed `--webpack` test cases from app, pages, and app-api template
tests
2026-02-11 11:19:39 +01:00
Niklas Mischkulnig 522de8c34f Fix deployment id header when proxying (#89593)
When proxying through multiple projects, this header would get overwritten by the proxy project:
- the header would be the proxy's deployment id
- `process.env.NEXT_DEPLOYMENT_ID` would be the origin's deployment id

Needs https://github.com/vercel/vercel/pull/14903
2026-02-06 20:34:25 +01:00
Niklas Mischkulnig 5c1b54115b Clarify type checking error message (#89525)
Previously:
```
pnpm next build
▲ Next.js 16.2.0-canary.28 (Turbopack)

  Creating an optimized production build ...
✓ Compiled successfully in 5.7s
  Running TypeScript  ...
Failed to compile.

./app/page.tsx:3:5
Type error: Type 'string' is not assignable to type 'number'.

  1 | import Nav from "../components/Nav";
  2 |
> 3 | let x: number = 'abc'
    |     ^
  4 |
  5 |
  6 | const IndexPage = () => (
Next.js build worker exited with code: 1 and signal: null
```

Now:
```
pnpm next build
▲ Next.js 16.2.0-canary.28 (Turbopack)

  Creating an optimized production build ...
✓ Compiled successfully in 5.7s
  Running TypeScript  ...
Failed to type check.

./app/page.tsx:3:5
Type error: Type 'string' is not assignable to type 'number'.

  1 | import Nav from "../components/Nav";
  2 |
> 3 | let x: number = 'abc'
    |     ^
  4 |
  5 |
  6 | const IndexPage = () => (
Next.js build worker exited with code: 1 and signal: null
```
2026-02-05 14:21:06 +01:00
Niklas Mischkulnig 49e0a8a8c0 Handle Pages data route skew with deployment id header, take 2 (#89325)
Reapply https://github.com/vercel/next.js/pull/88959
Revert https://github.com/vercel/next.js/pull/89323


Closes PACK-6537
Closes PACK-6756

- Deployment skew (forcing a MPA nav instead of a SPA nav if a deployment happened inbetween) is handled by comparing a header on the client side.
    - The other case that used build ids was app router, which was changed to the same approach in https://github.com/vercel/next.js/pull/88855
- Then, when a deployment id is available, make the build id a constant
	- Particularly, this makes the rollout of this much easier as the data route paths stay the same (both in Next.js itself as well as in the builder)


If you use `output:export` and set `config.deploymentId` (i.e. enable skew protection) you are still expected to set these headers.
2026-02-04 18:07:39 +01:00
Tim Neutkens 178a4c719f fix: use signal-based exit codes to prevent inspector blocking exit (#89351)
## What?

Use signal-based exit codes when shutting down the Next.js server to
prevent the process from waiting for the debugger to disconnect.

## Why?

When Node.js devtools are attached (via `--inspect` flag or the Next.js
DevTools "Attach debugger" feature), pressing Ctrl+C causes the dev
server to hang instead of exiting immediately. This happens because
calling `process.exit(0)` makes Node.js treat it as a normal exit, which
waits for all debuggers to disconnect before terminating.

In contrast, plain Node.js terminates immediately on SIGINT even with a
debugger attached, because signal-based termination doesn't wait for
debuggers.

## How?

Instead of calling `process.exit(0)` after cleanup, use signal-based
exit codes:

- SIGINT (signal 2) → `process.exit(130)` (128 + 2)
- SIGTERM (signal 15) → `process.exit(143)` (128 + 15)

This tells Node.js the process was terminated by a signal, which avoids
the debugger wait behavior.

Changes:
- Modified the cleanup function to accept the signal that triggered it
- Use `process.exit(signal === 'SIGINT' ? 130 : 143)` instead of
`process.exit(0)`
- Removed the previous `inspector.close()` workaround as it's no longer
needed

---------

Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2026-02-04 12:07:41 +01:00
Niklas Mischkulnig 303e38ecf3 Revert "Replace build id in Pages data routes with deployment id (#88959)" (#89323)
`test/e2e/middleware-redirects` has 404s on the data route
2026-01-30 14:51:52 -08:00
Niklas Mischkulnig 6766a270c4 Replace build id in Pages data routes with deployment id (#88959)
Closes PACK-6537

When a deployment id is available, don't put the data routes at `_next/data/<BUILDID>/page.json`, but at `_next/data/page.json`.
Deployment skew (forcing a MPA nav instead of a SPA nav if a deployment happened inbetween) is handled by comparing a header on the client side.


If you use `output:export` and set `config.deploymentId` (i.e. enable skew protection) you are still expected to set these headers.

---

- [x] Find the right place where the header should be added for prerendered static RSC responses (route manifest)
2026-01-30 18:22:08 +01:00
Niklas Mischkulnig 0e457e95a9 Keep pages/404.js to be able to dynamically render it anyway (#89263)
Needed for https://github.com/vercel/vercel/pull/14795

Keep the file so that we can instead dynamically render it as opposed to having to bundle the prerender into the function
2026-01-29 23:25:17 +01:00
Jiachi Liu f1a047fd80 IsolatedDevBuild flag removal (#89167)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: jiachi <jiachi@vercel.com>
2026-01-29 15:00:12 +01:00
Niklas Mischkulnig b3f776364d Fix chunk loading when using __turbopack_load_by_url__ with query (#88899)
- if you `await __turbopack_load_by_url__ `, it waits for the exact chunk url you passed in to load
- but when that chunk actually loads, it registers itself with `stripQuery(chunkurl)+CHUNK_SUFFIX`

so there was mismatch if you load a chunk from a different deployment and thus `await __turbopack_load_by_url__` never resolves



----

Very confused about what's going on here:

```
 FAIL   Turbopack  test/e2e/app-dir/segment-cache/deployment-skew/deployment-skew.test.ts (61.629 s)
  segment cache (deployment skew)
    with BUILD_ID
      ✓ does not crash when prefetching a dynamic, non-PPR page on a different deployment (11673 ms)
      ✓ does not crash when prefetching a static page on a different deployment (10744 ms)
    with NEXT_DEPLOYMENT_ID
      ✓ does not crash when prefetching a dynamic, non-PPR page on a different deployment (10924 ms)
      ✕ does not crash when prefetching a static page on a different deployment (15756 ms)

  ● segment cache (deployment skew) › with NEXT_DEPLOYMENT_ID › does not crash when prefetching a static page on a different deployment

    page.waitForSelector: Timeout 5000ms exceeded.
    Call log:
      - waiting for locator('#build-id') to be visible

      519 |
      520 |     return this.startChain(async () => {
    > 521 |       const el = await page.waitForSelector(selector, {
          |                             ^
      522 |         timeout,
      523 |         state,
      524 |       })

      at waitForSelector (lib/browsers/playwright.ts:521:29)
      at Playwright._chain (lib/browsers/playwright.ts:651:23)
      at Playwright._chain [as startChain] (lib/browsers/playwright.ts:632:17)
      at Playwright.startChain [as waitForElementByCss] (lib/browsers/playwright.ts:520:17)
      at Playwright.waitForElementByCss [as elementByCss] (lib/browsers/playwright.ts:405:17)
      at Playwright.elementByCss [as elementById] (lib/browsers/playwright.ts:425:17)
      at Object.elementById (e2e/app-dir/segment-cache/deployment-skew/deployment-skew.test.ts:122:37)

```

In the browser debugger, this line here in `fetchServerResponse` never returns, so there is actually no navigation at all (neither SPA nor MPA) when clicking the link, should be doing an MPA nav

https://github.com/vercel/next.js/blob/d4e64f52bb9aeb5dbcf6bb484f204742b2e3d743/packages/next/src/client/components/router-reducer/fetch-server-response.ts#L242
2026-01-26 15:30:56 +01:00
Niklas Mischkulnig b9ee1db283 [test] Improve deployment skew test for Pages Router data routes (#89038)
Actually test the behavior by switching between two builds, as opposed
to selectively blocking some routes.
2026-01-26 13:15:10 +01:00
Sebastian "Sebbie" Silbermann b08e16b21a Revert "[prebuilt-skew-protection] feat: adding in automatic deploymentId" (#88942) 2026-01-23 12:22:37 +01:00
Brooke 7282ce6759 [prebuilt-skew-protection] feat: adding in automatic deploymentId (#88496)
Original [PR](https://github.com/vercel/next.js/pull/88012/) has a bug
that attempted to validate on environment variables. Edited function to
not run validations on environment variables, only on the user provided
deployment id.

<!-- 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


## 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 #

-->

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2026-01-22 21:07:34 +00:00
Sebastian "Sebbie" Silbermann d56ed7bbca Allow inspecting server with next start --inspect (#88744) 2026-01-19 17:13:29 +01:00
Sebastian "Sebbie" Silbermann 2bf8a24481 [cna] Ensure created app is not considered the workspace root in pnpm (#88647) 2026-01-17 08:06:35 +01:00
Neha Prasad 5ad737c9c5 fix: make RedirectType constant properties literal types (#88653)
### What?

Fixed TypeScript error where `RedirectType.replace` and
`RedirectType.push` were typed as `string` instead of literal types,
causing compilation errors when used with `redirect()`.

### Why?

`RedirectType` constant properties weren't properly typed as literal
types, causing TypeScript to see them as generic `string` values instead
of the expected `'push' | 'replace'` union.

### How?

- Added `as const` to `RedirectType` properties in
`packages/next/src/client/components/navigation.react-server.ts`.

Fixes #88627

---------

Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
2026-01-16 19:53:41 +00:00
Steven 54476c9c64 fetch(next/image): reduce maximumResponseBody from 300MB to 50MB (#88588)
Based on our metrics, the P99.9 for a source image is 47 MB so we can
adjust the default setting to be much lower (by changing from from 300
MB to 50 MB) in favor of reducing memory.
2026-01-15 14:34:13 -05:00
Jiachi Liu 0df959c1ab keep next-env.d.s unchanged between dev and build (#88428) 2026-01-14 13:51:22 +01:00
Zack Tanner c1a752bcca Revert "prevent browser cache from using stale RSC responses from pre… (#88457)
…vious builds (#86554)"

This reverts commit 3bbb2e61d5.

Need to investigate some upstream constraints before we land this in a
stable release.
2026-01-12 17:54:57 -08:00
Sebastian "Sebbie" Silbermann f814b8b51a [test] Deflake test/integration/invalid-custom-routes/test/index.test.ts (#88416) 2026-01-12 13:16:37 +01:00
Zack Tanner 0d4649989d next/image: support custom cache handlers (#88248)
When self-hosting Next.js, it's possible to customize a cache handler
for ISR. Self-hosted Next.js also makes use of a similar cache interface
for `next/image`, but there's no way to customize this cache handler.

This plugs into the [existing
ability](https://nextjs.org/docs/app/api-reference/config/next-config-js/incrementalCacheHandlerPath)
to customize a `cacheHandler` to support the `IMAGE` type. This lets you
implement whatever constraints you might have on your self-hosted
environment, eg the need for an LRU cache, or storing optimized images
outside of disk.

This is currently opt-in because it's a breaking change for cache
handlers to start receiving `IMAGE` cache types, which we'll make
default in the next major.
2026-01-08 10:58:49 -08:00
Tim Neutkens fd2bd2952e Move Ready in time before handler initialization (#88235)
## Move "Ready in X" log before config loading and eliminate duplicate
`loadConfig` calls

### What?

Reorder the dev server startup flow so the "Ready in X" log appears
before loading the user's `next.config.js`, and eliminate duplicate
`loadConfig` calls in both dev and build paths.

### Why?

Previously, the "Ready in X" time included the time spent loading and
evaluating the user's `next.config.js` file. This made the framework
appear slower than it actually is, especially for projects with complex
config files or slow config evaluation.

Additionally, config was being loaded twice:
- **Dev server**: Once in `getStartServerInfo()` just for logging, then
again in `getRequestHandlers()`
- **Build**: Once for the main build, then again in
`getStartServerInfo()` just for logging

### How?

**Before:**
```
1. getStartServerInfo() → loadConfig #1 (slow - blocks on next.config.js)
2. logStartInfo() → logs version, URLs, experimental features
3. "Ready in X" ← time includes config loading
4. getRequestHandlers() → loadConfig #2
```

**After:**
```
1. logStartInfo() → logs version, URLs, envInfo (no config needed)
2. "Ready in X" ← reflects actual framework startup time
3. getRequestHandlers() → loadConfig (once)
4. logExperimentalInfo() → logs experimental features
```

**Changes:**

- Split `logStartInfo` into two functions:
- `logStartInfo()` - basic info (version, URLs, env) - no config needed
  - `logExperimentalInfo()` - experimental features and cacheComponents
- Removed `getStartServerInfo()` which was loading config unnecessarily
- Added `experimentalFeatures` and `cacheComponents` to
`ServerInitResult` so they can be passed back after config loads
- In build, added `reportExperimentalFeatures` callback to the existing
`loadConfig` call instead of loading config twice

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-01-08 19:09:50 +01:00
Steven 3b5a210f3d fix(next/image): bump sharp@0.34.5 (#88238)
Release notes: https://github.com/lovell/sharp/releases/tag/v0.34.5

- Upgrade to libvips v8.17.3 for upstream bug fixes.
- Add experimental support for prebuilt Linux RISC-V 64-bit binaries.
- Support building from source with npm v12+
- Add support for BigTIFF output.
- Improve error messaging when only warnings issued.
- Simplify ICC processing when retaining input profiles.
2026-01-07 17:38:38 +00:00
Jimmy Lai fd5817d004 feat: add --experimental-cpu-prof flag for dev, build, and start (#87946)
## What

Adds a `--experimental-cpu-prof` flag to `next dev`, `next build`, and
`next start` commands to capture V8 CPU profiles for debugging
performance bottlenecks.

## Why

When investigating slow builds, slow dev server startups, or production
server performance issues, having access to CPU profiles is invaluable.
This provides a first-party way to capture these profiles without
needing to manually set up the V8 inspector.

## How

- Adds `--experimental-cpu-prof` flag to CLI commands
- Uses V8's built-in CPU profiler via Node.js inspector module
- Profiles are saved to `.next/cpu-profiles/` with descriptive filenames
- Profiles are saved on process exit (Ctrl+C, SIGTERM, or normal exit)

### Profile files generated

**`next dev`:**
- `dev-main-*` - Parent process (dev server orchestration)
- `dev-server-*` - Child server process (request handling and rendering)

**`next build` (Turbopack):**
- `build-main-*` - Main build orchestration process
- `build-turbopack-*` - Turbopack compilation worker

**`next build` (Webpack):**
- `build-main-*` - Main build orchestration process
- `build-webpack-client-*` - Client bundle compilation worker
- `build-webpack-server-*` - Server bundle compilation worker
- `build-webpack-edge-server-*` - Edge runtime compilation worker

**`next start`:**
- `start-main-*` - Production server process

## Changes addressing PR review comments

- Removed signal handlers from `cpu-profile.ts` to prevent conflicts
with CLI cleanup logic (telemetry, traces, etc.)
- Added synchronous exit handler for non-signal process exits (errors,
`process.exit()` calls)
- CLI commands now explicitly call `saveCpuProfile()` as part of their
cleanup before exiting
- Replaced raw ANSI escape codes with `picocolors` library
- Added comprehensive documentation about profile file naming for each
command
- Added build profiling test that verifies correct profile generation
for both Turbopack and Webpack modes

---------

Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
2026-01-07 11:24:41 +01:00
Steven 00e92280d2 feat(next/image)!: add images.maximumResponseBody config (#88183)
Add `images.maximumResponseBody` configuration to exit early when
attempting to optimize large source images.
2026-01-06 14:49:45 -08:00
Sebastian "Sebbie" Silbermann 35a566b383 [strict-route-types] Ensure cache profiles and routes are type-checked even if .next is excluded (#87768)
Flagged behind `experimental.strictRouteTypes`

This fixes issues where cache profiles where not included or routes not validated if `.next` was excluded to squeeze out every bit of TypeScript performance.

It also fixes a redundant type-check since we have separate dev and prod dist folders.  If you run `next dev` and (`next build` or `next typegen`), you'd type-check routes and links twice. Now `next-env.d.ts` only exists once where we decide which dist folder to type-check.

Going forward, new Next.js type-checking should be added to `next-env.d.ts`. That file is fully controlled by Next.js and churning it, does not churn users since it's not in version control.

`next-env.d.ts` will be moved into `.next` in a follow-up. Ideally independent of the dist folder i.e.  independent of `next dev` vs `next build`.

Closes https://linear.app/vercel/issue/NXT-124/

https://github.com/vercel/next.js/pull/87319 but flagged.
2026-01-06 16:21:25 +01:00
Sebastian "Sebbie" Silbermann b821f423a6 Revert "dx: avoid next-env.d.ts change in dev" (#88153)
Reverting since it produced merge conflicts with in-progress
[strict-route-types
project](https://linear.app/vercel/project/nextjs-strict-route-types-2f0a70110d5d/overview):

The lesson learned from the earlier PR was that this is a risky change.
We'll land a similar change flagged in
https://github.com/vercel/next.js/pull/87768
2026-01-06 14:44:14 +01:00
Zack Tanner 3bbb2e61d5 prevent browser cache from using stale RSC responses from previous builds (#86554)
When we landed #76207 we started propagating the
`stale-while-revalidate` value to RSC responses. We wanted a way to
express to CDNs that it can keep serving the cached content for some
time while a revalidation runs in the background, but we specifically
don't want that for private caches.

As a result of this header, when re-building your application locally
(or doing something on the server that would have expired the cache),
the browser's disk cache would serve a stale RSC response. We currently
encode a buildId in RSC payloads, so the client router will discard RSC
responses that don't match what it is expecting.

Unfortunately there isn't a `s-stale-while-revalidate` header to express
the intended semantics. This moves the `stale-while-revalidate`
configuration into the `CDN-Cache-Control` header, which is becoming
standardized and is supported by a wide variety of CDNs. This allows us
to specify the SWR behavior more explicitly to CDNs while not impacting
private caches like the browser. It restores the previous behavior of
only setting `s-maxage` on the `cache-control` itself to avoid
influencing browser cache.

If Next.js is deployed to a CDN that doesn't support this header, it can
be customized via `nextConfig.experimental.cdnCacheControlHeader`. Eg,
if deployed to Fastly, you'd configure this to `cdnCacheControlHeader:
'Surrogate-Control'`.

Closes NAR-525

Reference docs:


[Vercel](https://vercel.com/docs/headers/cache-control-headers#cdn-cache-control-header)

[Cloudflare](https://developers.cloudflare.com/cache/concepts/cdn-cache-control/)

[Fastly](https://www.fastly.com/documentation/reference/http/http-headers/Surrogate-Control/)

[RFC 9213](https://httpwg.org/specs/rfc9213.html)
2026-01-05 12:17:57 -08:00
Jiachi Liu 42493fb3a4 dx: avoid next-env.d.ts change in dev (#88103) 2026-01-05 14:35:33 +01:00
Sebastian "Sebbie" Silbermann 85861db787 [strict-route-types] Add experimental.strictRouteTypes config (#87378) 2025-12-28 17:14:45 +01:00