Commit Graph

3804 Commits

Author SHA1 Message Date
Zana Abdi 92210e34b8 Update 05-server-and-client-components.mdx (#93374)
Added an important exception (for when client components wrap server
components) under an original line that seems to claim a universal law.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

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

### Fixing a bug

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

### Adding a feature

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

### Signed commits

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


## For Maintainers

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

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

---------

Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-30 13:41:33 +02:00
Tim Neutkens 84f1e44d4d Deprecate edge runtime (#93369)
Note: re-apply of #92817

### What?

Deprecates the Edge Runtime and the `preferredRegion` route segment
config that only applied to edge runtime with build-time warnings,
TypeScript IDE hints, error documentation pages, and documentation
updates.

### Why?

Edge Runtime in Next.js is being deprecated in favor of the Node.js
runtime (the default). The `preferredRegion` route segment config is
tightly coupled to Edge Runtime and is also being deprecated.

### How?

**Edge Runtime deprecation:**
- Added `warnAboutEdgeRuntime()` helper using `Log.warnOnce` in
`packages/next/src/build/warn-about-edge-runtime.ts`
- Warning fires in `get-page-static-info.ts` (Webpack dev/build +
Turbopack build) and `turbopack-utils.ts` (Turbopack dev) when `runtime
= 'edge'` is detected
- Marked `'edge'` as `@deprecated` in the TypeScript language service
plugin (`rules/config.ts`)
- Created `errors/edge-runtime-deprecated.mdx` with migration guidance
- Updated documentation across 11 files to add deprecation notices or
simplify/remove outdated Edge Runtime references

**`preferredRegion` deprecation:**
- Added `warnAboutPreferredRegion()` helper in the same file
- Warning fires in `get-page-static-info.ts` for both App Router
(`config.preferredRegion`) and Pages Router (`config.config?.regions`)
- Marked `preferredRegion` as `@deprecated` in the TypeScript language
service plugin and the generated types (`next-types-plugin`)
- Created `errors/preferred-region-deprecated.mdx` with migration
guidance (remove the export)
- Updated documentation across 4 files to add deprecation notices

**Tests:**
- Added `test/e2e/edge-runtime-deprecated/` with fixture and assertions
for the edge runtime warning (dev + production)
- Added `test/production/preferred-region-deprecated/` with fixture and
assertions for the preferredRegion warning (production only -- Turbopack
dev does not surface `preferredRegion` from the Rust layer to JS)

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-04-30 10:01:06 +02:00
Zack Tanner 4ba05cc300 enable validateRSCRequestHeaders by default (#93367)
This flag has been enabled by default on canary for some time. This
turns it on by default to ensure that CDNs that don't respect `Vary`
properly distinguish between different response types.
2026-04-29 12:44:32 -07:00
张昊 668094edce Turbopack: add experimental.turbopackWorkerAssetPrefix to keep Workers same-origin when assetPrefix is a CDN (#93271)
### What?

Adds `experimental.turbopackWorkerAssetPrefix` — a Turbopack counterpart
to webpack's
[`output.workerPublicPath`](https://webpack.js.org/configuration/output/#outputworkerpublicpath).
Opt-in, off by default, fully backward compatible.

```js
// next.config.js
module.exports = {
  assetPrefix: 'https://cdn.example.com',
  experimental: {
    // Same shape as `assetPrefix`: bare prefix, no trailing slash, no `/_next`.
    // `/_next/` is appended automatically. `''` → same-origin `/_next/...`.
    turbopackWorkerAssetPrefix: '',
  },
}
```

### Why?

When `assetPrefix` points to a cross-origin CDN (common production
setup), Turbopack emits Worker URLs under that CDN origin. Browsers
reject cross-origin `new Worker(url)` with `SecurityError`, breaking
every feature that uses `new Worker(new URL('./worker.ts',
import.meta.url))` — image decoders, WebP/GIF renderers, compression,
OffscreenCanvas, etc.

webpack solved this with `output.workerPublicPath`. Turbopack ignores
the `webpack()` callback in `next.config.js`, so the existing
same-origin workaround silently breaks when projects switch to
Turbopack.

Full design doc, alternatives considered, related issues (#88602,
#92676, #74621, #29468): **#93044**

Repro repo (`pnpm dev` reproduces, `pnpm dev:webpack` works):
https://github.com/GuinsooRocky/next-turbopack-worker-cdn-repro

### How?

Threads a new optional `turbopack_worker_asset_prefix: Option<RcStr>`
from `ExperimentalConfig` → `BrowserChunkingContext` → the JS runtime,
where `createWorker` reads it via a new `WORKER_BASE_PATH` global
emitted alongside the existing `CHUNK_BASE_PATH`. When unset, behavior
is identical to today.

Semantics, modeled on `assetPrefix`:

- **Bare prefix.** `/_next/` is appended automatically (same as
`computed_asset_prefix`); the user supplies just the origin (or empty
string for same-origin).
- **`undefined` vs `''`.** `undefined` falls back to the regular chunk
base path; `''` is a literal empty prefix that resolves to same-origin
`/_next/...`. The runtime distinguishes the two by injecting a JS `null`
literal vs a quoted string, and uses `WORKER_BASE_PATH ??
CHUNK_BASE_PATH` (not `||`).
- **Applies to entrypoint and module chunks.** The Turbopack worker
bootstrap rejects cross-origin module chunks (`Refusing to load script
from foreign origin`), so the override has to cover both — overriding
only the entrypoint would leave the worker unable to load any chunks
under a cross-origin `assetPrefix`.

Touchpoints:

- `packages/next/src/server/config-{shared,schema}.ts` — public option +
zod under `experimental`
- `crates/next-{api,core}/...` — wiring through to
`ClientChunkingContextOptions`;
`NextConfig::turbopack_worker_asset_prefix()` resolves to
`Some("<prefix>/_next/")` or `None`
- `turbopack/crates/turbopack-browser/src/chunking_context.rs` — new
field + builder + getter
- `turbopack/crates/turbopack-ecmascript-runtime/src/browser_runtime.rs`
— emit `WORKER_BASE_PATH` declaration as `null` or a quoted string
- `turbopack/.../runtime-base.ts` — `createWorker` resolves
`workerBasePath` and uses it for both the entrypoint URL and
module-chunk URLs delivered via params
- `test/e2e/turbopack-worker-asset-prefix/` — e2e fixture using real
cross-origin (`localhost` page, `127.0.0.1` `assetPrefix`); intercepts
`new Worker()` to assert on the URL the runtime helper resolved. Three
cases: no override (cross-origin URL → `SecurityError`), explicit
override origin, and `''` (relative `/_next/...`).
- `docs/01-app/03-api-reference/08-turbopack.mdx` — option reference
- `telemetry/events/version.ts` — `useTurbopackWorkerAssetPrefix:
boolean` (set on any explicit value, including empty string)

### Notes

- Opening as **Draft** to invite API-shape feedback before going to
review. Per the contributing guide, the design discussion is at #93044.
- All checklist items the PR template requires for a feature are
covered: e2e tests, docs, telemetry, no error-link path applies.

cc @sokra

Closes #93044

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
2026-04-29 11:05:11 +02:00
Sebastian "Sebbie" Silbermann 59c73aecc9 Apply sourcemaps by default during prerender in next build (#93280) 2026-04-28 11:00:13 +02:00
christopherkindl a6782fa620 docs: remove broken error-handling overlay screenshot (#93279)
The Cloudinary URL for the overlay screenshot

(`assets.vercel.com/image/upload/v1645118290/docs-assets/static/docs/error-handling/overlay.png`)
404s. The line above it had a `{/* TODO UPDATE SCREENSHOT */}` comment,
so this was already flagged as known-stale.

Removes the broken image and its `"Here is an example of an overlay:"`
intro line. The paragraph above still explains what the overlay is, so
the page reads cleanly without the screenshot. If someone produces a
fresh screenshot later, restoring the markdown with an updated URL is a
one-line change.

### Affects

-
`nextjs.org/docs/pages/building-your-application/configuring/error-handling`
(stable, on next stable cut)
-
`nextjs.org/docs/canary/pages/building-your-application/configuring/error-handling`
(canary)

### Older versions

The same broken URL is present in v13/v14/v15 of the docs (synced from
the corresponding release tags). Backport is a separate call for
maintainers.
2026-04-27 14:29:50 +02:00
Tobias Koppers 44722b808c Turbopack: import.meta.glob docs + edge case support (#92729)
## What?

Adds documentation and TypeScript types for `import.meta.glob` in
Turbopack, and implements additional edge cases for Vite compatibility.

### Documentation
- New `## import.meta.glob` section in the [Turbopack reference
page](/docs/app/api-reference/turbopack) covering: lazy/eager loading,
named imports, query strings (including the object form), multiple
patterns, negation, TypeScript types, and a full options table.
- `import.meta.glob` row added to the Module Resolution feature table.
- Migration note added to the [from-Vite
guide](/docs/app/guides/migrating/from-vite) explaining that
`import.meta.glob` works out of the box with Turbopack, with
before/after for the deprecated `as` → `query` migration.

### TypeScript types
- Added `ImportMetaGlobOptions` interface and overloaded `glob()`
signatures to `ImportMeta` in `packages/next/types/global.d.ts`.
- The overloads return `Record<string, unknown>` when `eager: true` is
passed and `Record<string, () => Promise<unknown>>` otherwise.

### Implementation (edge cases)
- **`import: '*'`** (namespace import): Treated the same as omitting the
`import` option (returns the whole module namespace), matching Vite
semantics. Previously would have generated broken `module["*"]` access.
- **`query` as object literal**: `{ query: { bar: 'foo', raw: true } }`
is now supported. Keys and values are URL-encoded and joined into a
query string (`?bar=foo&raw=true`).
- **Stricter option validation**: A non-object-literal second argument
(e.g. `import.meta.glob('./*.js', 'eager')`) is now a compile-time error
instead of a warning, since the options cannot be safely defaulted.

### Tests
- Execution tests for new features: namespace `import: '*'`, query
object, combining query with negation, explicit dotfile patterns.
- New `import-meta-glob-errors` execution test with issue snapshots
covering: too many arguments, non-string pattern, and non-object options
argument.

## Why?

1. The feature shipped in #92640 but had no user-facing documentation
and no TypeScript types.
2. Several Vite-compatible edge cases were not handled: namespace
imports (`import: '*'`) and query objects. These gaps would cause subtle
behavioral differences for users migrating from Vite.
3. Option validation was too lenient — invalid second arguments fell
through to defaults silently.

## How?

### Docs & types
- `docs/01-app/03-api-reference/08-turbopack.mdx` — new section, table
row, TypeScript subsection
- `docs/01-app/02-guides/migrating/from-vite.mdx` — migration note
- `packages/next/types/global.d.ts` — `ImportMetaGlobOptions` +
`ImportMeta.glob()` overloads

### Implementation
-
`turbopack/crates/turbopack-ecmascript/src/references/import_meta_glob.rs`:
- `parse_import_meta_glob()`: `import: '*'` normalized to `None`; query
object parsing via `urlencoding::encode()`; non-object options argument
now emits an error and returns `None`.
- `turbopack/crates/turbopack-ecmascript/Cargo.toml`: added
`urlencoding` workspace dep.

Note: dotfile/dot-directory filtering is not needed in
`import.meta.glob` itself — the underlying `Glob` pattern engine and
`read_glob_internal` already handle dotfile semantics correctly
(explicit `./.foo/*.js` matches, wildcards include them).

### Tests
-
`turbopack-tests/tests/execution/turbopack/resolving/import-meta-glob/`
— new cases for `import: '*'`, query object, query + negation, explicit
dotfile pattern, wildcard including dotfiles
-
`turbopack-tests/tests/execution/turbopack/resolving/import-meta-glob-errors/`
— new test suite for fatal parse errors with issue snapshots

### Checklist
- [x] `pnpm prettier-fix` / `cargo fmt` run
- [x] Documentation follows the [docs contribution
guide](https://nextjs.org/docs/community/contribution-guide)
- [x] Execution tests pass (`cargo test -p turbopack-tests --test
execution -- "import_meta_glob"`)
- [x] `cargo clippy` clean
- [x] `pnpm --filter=next types` passes

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-27 07:37:53 +00:00
Jude Gao bd070d06f8 Auto-generate AGENTS.md / CLAUDE.md in next dev (#92910) 2026-04-22 00:33:50 +08:00
Jimmy Lai 931868b86c docs: add guide for displaying dates without hydration flash (#92786)
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
### What?

Adds a new documentation guide at
`docs/01-app/02-guides/displaying-dates.mdx` that documents how to
display locale-aware dates and times on prerendered/static pages without
a visible flash when the page loads.

### Why?

Dates and times formatted with `toLocaleDateString()` or
`Intl.DateTimeFormat` produce different output on the server (build-time
locale/timezone) vs the browser (user's locale/timezone). On prerendered
pages this causes a visible text change ("snap") when React hydrates and
re-renders with the correct locale.

There was no existing documentation for this common pattern. The inline
script approach (running a small `<script>` synchronously before browser
paint to correct the DOM) is the recommended technique for static/cached
pages.

### How?

**New guide** (`displaying-dates.mdx`) follows the progressive example
style from `public-static-pages.mdx`:

1. **Step 1**: Shows the problem — a static page with a server-formatted
date
2. **Step 2**: Fixes it with an inline `<script>` +
`suppressHydrationWarning`
3. **Step 3**: Extracts a reusable `<LocalDate>` component with `<time>`
element for accessibility/SEO

Also includes a comparison table for when to use alternative approaches
(`connection()`, Client Components with `useEffect`, fully dynamic
pages).

**Cross-references added:**
- `public-static-pages.mdx` — callout in the "Static components" section
where "the current time" is mentioned
- `connection.mdx` — callout noting the inline script alternative for
prerendered pages

### Improving Documentation

- Ran `prettier` to fix formatting
- Follows doc conventions (frontmatter, `switcher` pattern, `filename`
attributes, callout format)

<!-- NEXT_JS_LLM_PR -->
<!-- CURSOR_AGENT_PR_BODY_END -->

[Slack
Thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1776095579605699?thread_ts=1776095579.605699&cid=C03S8ED1DKM)

<div><a
href="https://cursor.com/agents/bc-e7710133-5c01-4a8a-9147-1ccbc9b6dd89"><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>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-e7710133-5c01-4a8a-9147-1ccbc9b6dd89"><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;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Joseph Chamochumbi <joseph.chamochumbi@vercel.com>
2026-04-20 14:54:37 +02:00
Aurora Scharff a03b8eeef7 docs: link Activity guide from Cache Components migration guide (#92571)
## Summary

- Add a "UI state preservation" section to the Cache Components
migration guide explaining that pages are now preserved via React's
`<Activity>` instead of unmounting on navigation
- Add `related` links pointing to the preserving UI state guide and
`cacheComponents` config reference
- Cross-link the migration guide from the preserving UI state guide for
bidirectional discovery

The migration guide previously only covered route segment config
replacements (`dynamic`, `revalidate`, `fetchCache`, `runtime`) but
didn't mention the fundamental navigation behavior change. Users
migrating to Cache Components need to know that cleanup logic, analytics
events, and state resets may behave differently.

---------

Co-authored-by: Joseph Chamochumbi <joseph.chamochumbi@vercel.com>
2026-04-20 10:52:18 +00:00
Joseph 8292880874 docs: amends to preserving-ui-state guide (#92270)
Still drafting this one. We want to show good patterns, and effects are
often a last resource. We favor here resetting in an event handler.
2026-04-18 00:35:37 +02:00
Josh Story a7d1573391 Support more prefetch configuration options (#92859)
"auto" mode is the default. It does not need to be explicitly exported
"force-" modes suggest overriding framework heuristics "force-disabled"
disables prefetching for this segment "force-static" forces any
prefetching of this segment to be static "force-runtime" forces any
prefetching of this segment to do runtime prefetching

It's worth noting that when runtime prefetching we fetch the necessary
segment and all child segments in a single request. This means that a
deeper segment might specify disabled or static and still get
conditionally rendered as a runtime prefetch. This was already the
behavior of runtime prefetching and not changing in this PR just
something to call out since it may be confusing to folks trying to
understand how the implementation of prefetching actually work
2026-04-17 09:28:54 -07:00
Josh Story 9f2779ec57 remove flag guarding unstable_io (#92923)
removes the flag guarding `unstable_io`.

The API isn't likely to change semantic meaning but could still be
removed. Do not rely on it extensively yet
2026-04-17 07:54:58 -07:00
Joseph 845485a986 docs: restructure instant nav guide for clarity (#92684)
Reordered DevTools section, improved code examples and db queries, added
component breakdowns in the fix section, editorial improvements
throughout.
2026-04-16 00:26:26 +02:00
Joseph ab4ec43a7b docs: draftMode alignment (#92794)
Closes:
https://linear.app/vercel/issue/DOC-6291/draftmode-disables-cached-scopes-etc
2026-04-15 11:06:06 +02:00
Aurora Scharff 901cb556c3 docs: add migration note for experimental cache flags to cacheComponents (#92318)
### What?

Add a "Migrating from experimental flags" section to the
`cacheComponents` config reference page, documenting that
`experimental.useCache` and `experimental.cacheComponents` are
deprecated in favor of top-level `cacheComponents: true`.

### Why?

Three config paths exist with overlapping semantics
(`experimental.useCache`, `experimental.cacheComponents`,
`cacheComponents`), but no documentation explains their relationship or
how to migrate. The build output shows different labels for each
("Experiments: ✓ useCache" vs "Cache Components enabled"), making them
look like different features. Both human developers and AI agents
encounter this ambiguity and may use the wrong flag.

### How?

Added a before/after code example to
`docs/01-app/03-api-reference/05-config/01-next-config-js/cacheComponents.mdx`
showing the migration from either experimental flag to the top-level
config, with a note that both experimental flags are deprecated.

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-14 16:05:16 +02:00
Hamed 82829bc558 docs: fix broken bun.sh Nextjs documentation link (#92698)
### What?
Update outdated bun.sh Next.js documentation link.

### Why?
The previous link returned a 404.

### How?
Replaced:
https://bun.sh/docs/frameworks/nextjs

With:
https://bun.com/docs/guides/ecosystem/nextjs

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-13 14:21:32 +02:00
Joseph db0fdc30f6 docs(cli): clarify that --debug-build-paths requires route group folders in paths (#92618)
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
### What?

Adds a note to the `--debug-build-paths` section of the CLI docs
clarifying that [route
groups](https://nextjs.org/docs/app/building-your-application/routing/route-groups)
must be included in file paths.

### Why?

When using `--debug-build-paths`, users need to include route group
folders (e.g., `(marketing)`) in the file paths they pass. This isn't
obvious from the existing documentation — route groups are stripped from
URLs at runtime but must be present in file paths for this CLI option to
work correctly.

Addresses feedback from a docs comment noting that "Route groups are
also necessary, should be inferred from file paths, but it is not
straightforward from reading this."

### How?

Added a "Good to know" callout with an example showing how to reference
a page inside a route group:

```bash
next build --debug-build-paths="app/(marketing)/about/page.tsx"
```

<!-- NEXT_JS_LLM_PR -->
<!-- CURSOR_AGENT_PR_BODY_END -->

[Slack
Thread](https://vercel.slack.com/archives/C07ND110MMF/p1775828588791049?thread_ts=1775828588.791049&cid=C07ND110MMF)

<div><a
href="https://cursor.com/agents/bc-3a58eac7-35a3-56ab-aff2-f4cf2dd1ca9b"><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>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-3a58eac7-35a3-56ab-aff2-f4cf2dd1ca9b"><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;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Joseph <icyJoseph@users.noreply.github.com>
2026-04-12 14:13:46 +02:00
Tobias Koppers 74cdcde87e feat(turbopack): add LocalPathOrProjectPath PostCSS config resolution (#91338)
### What?

Adds a new `experimental.turbopackLocalPostcssConfig` option and
corresponding `PostCssConfigLocation::LocalPathOrProjectPath` variant so
Turbopack can resolve `postcss.config.js` starting from the CSS file's
directory first, falling back to the project root.

Also fixes an issue that surfaces when multiple per-directory
`postcss.config.js` files are used:

**Evaluate pool asset name collisions** — output file names for the
Node.js evaluate pool are now derived from an xxh3 hash of the full
module ident rather than the bare file name, so multiple
`postcss.config.js` files in different directories no longer collide.

### Why?

Currently Turbopack uses `ProjectPathOrLocalPath` which checks the
project root first, then falls back to the local directory. This means
per-directory `postcss.config.js` files cannot override the root config
— the root config always wins. For projects that need different PostCSS
transforms in different directories (e.g. a monorepo with multiple apps
or style directories), the more specific config should take precedence.

### How?

**Turbopack PostCSS resolution**
(`turbopack/crates/turbopack-node/src/transforms/postcss.rs`):
- Added `PostCssConfigLocation::LocalPathOrProjectPath` enum variant
with doc comments on all variants
- Refactored `find_config_in_location()` to express the search order as
a `Vec<FileSystemPath>` built from a single `match`, making each
variant's strategy immediately clear

**Evaluate pool asset file naming**
(`turbopack/crates/turbopack-node/src/evaluate.rs`):
- Replaced file-name-based output path derivation with a deterministic
xxh3 hash of the full module ident
- Adds `turbo-tasks-hash` dependency to `turbopack-node`
- Eliminates name collisions when multiple entries share the same file
name (e.g. per-directory `postcss.config.js` files)

**Next.js config flag** (`packages/next/src/server/config-shared.ts`,
`config-schema.ts`):
- Added `experimental.turbopackLocalPostcssConfig: boolean` option
(opt-in, default `false`)
- Wired through `crates/next-core/src/next_config.rs` → both client and
server contexts (`next_client/context.rs`, `next_server/context.rs`)
- When `true`, uses `LocalPathOrProjectPath`; when `false`/unset, uses
the existing `ProjectPathOrLocalPath` (no behavior change by default)

**E2E test** (`test/e2e/app-dir/turbopack-postcss-multiple-configs/`):
- Runs in both **Turbopack dev and production modes** — skips webpack
only (webpack does not support function-valued PostCSS plugins and the
`turbopackLocalPostcssConfig` flag is Turbopack-specific)
- 5 style directories, each with its own `postcss.config.js` passing a
**unique color option** (`blue`, `purple`, `orange`, `cyan`, `magenta`)
to a shared PostCSS plugin, proving that per-directory config resolution
produces distinct results rather than all sharing the same transform
- Root `postcss.config.js` is a no-op — if only the root config were
used, CSS would remain unmodified
- Test validates all 15 elements (5 dirs × 3 files) render with CSS
module classes
- Test collects all CSS (inline `<style>` tags for dev, linked `.css`
files for production) and asserts each directory's expected color is
present and `color: red` is absent

**Documentation**
(`docs/01-app/03-api-reference/05-config/01-next-config-js/turbopackLocalPostcssConfig.mdx`,
`docs/01-app/03-api-reference/08-turbopack.mdx`):
- New dedicated reference page for
`experimental.turbopackLocalPostcssConfig` covering usage, behavior
table, and a directory-tree example
- Added to the experimental options table in the Turbopack API reference

## Test plan

- [x] `cargo check -p turbo-tasks-backend` passes
- [x] `cargo check -p turbopack-node` and `cargo check -p next-core`
pass
- [x] E2E test `turbopack-postcss-multiple-configs` validates
per-directory PostCSS config resolution across 5 directories with
distinct per-directory colors (Turbopack dev and production modes)
- [x] Test correctly skips in webpack mode and deployment
- [x] Documentation page and experimental options table updated

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
2026-04-11 07:55:10 +02:00
Aurora Scharff 3c1ab72ae6 docs: add Link transitionTypes version history (#92624)
## Summary
- add the missing `transitionTypes` entry to the `next/link` version
history table
- document that the prop was added in `v16.2.0`

## Testing
- not run (docs-only change)

<!-- NEXT_JS_LLM_PR -->
2026-04-10 18:50:47 +02:00
Joseph c249ea94b0 docs: native db drivers with sync queries (#92572)
Closes: https://github.com/vercel/next.js/issues/86379

A native db driver, or sync db driver, won't be detected as external
data, rather, as sync I/O.

Main motivation is that better-sqlit3 is popular, and Node.js has
introduced a native sql driver module.

Given no other uncached data, or runtime data access, these queries
would be included in the static shell. Wrapping with Suspense is not
sufficient.
2026-04-09 18:51:10 +02:00
Tim Neutkens ccc8c06266 Docs: Instant docs updates (#92515)
## What?

Tweaks in the explanation of instant.

---------

Co-authored-by: Joseph Chamochumbi <joseph.chamochumbi@vercel.com>
2026-04-09 15:40:28 +02:00
Aurora Scharff 766467e054 docs: link updateTag from cacheTag reference (#92379)
### What?
Add [`updateTag`](/docs/app/api-reference/functions/updateTag) to the
`cacheTag` API page: a **Related** link and a **Good to know** bullet
that explains when to use it (read-your-own-writes / immediate expiry)
and points to [Differences from
`revalidateTag`](https://nextjs.org/docs/app/api-reference/functions/updateTag#differences-from-revalidatetag).

### Why?
The bundled `cacheTag` doc only walked through `revalidateTag`, so the
two-API invalidation model was easy to miss. This keeps existing
`revalidateTag` wording and examples unchanged and adds a minimal
pointer to `updateTag` without duplicating its full reference.

### How?
- `related.links`: include `app/api-reference/functions/updateTag`.
- `## Good to know`: one imperative bullet + deep link to the comparison
section on the `updateTag` page.

## PR checklist (Improving Documentation)
- Prettier/ESLint ran via lint-staged on commit; run `pnpm prettier-fix`
if needed.
- Follow the docs contribution guide:
https://nextjs.org/docs/community/contribution-guide

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-09 13:33:57 +02:00
Jiwon Choi 4e3f35b3f1 docs: update details about unstable_retry() behavior (#91827)
## Summary
- Updated the "Built-in error recovery" bullet in `catchError` docs to
say "retries rendering the error boundary's children with fresh data in
Server Components" instead of "re-fetches and re-renders the error
boundary's children, including Server Components"
2026-04-09 12:59:35 +02:00
Abhishek Mardiya 1d8e326d1b docs: add note on installing server-only in data security guide (#92445)
## What?

Improve alignment between the following documentation sections to ensure
clearer and more consistent guidance:

- Data Security:
https://nextjs.org/docs/app/guides/data-security#preventing-client-side-execution-of-server-only-code
- Preventing Environment Poisoning:
https://nextjs.org/docs/app/getting-started/server-and-client-components#preventing-environment-poisoning

**Related**: https://github.com/vercel/next.js/discussions/91180

## Why?

The current documentation presents overlapping concepts with slight
inconsistencies, which can lead to confusion for readers.

## Changes

- Align explanations across both sections  
- Improve overall consistency in guidance  

Docs only change.

@icyJoseph

---------

Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-08 17:29:57 +02:00
Tim Neutkens c5596dd4e0 Turbopack: Write trace file to .next-profiles (#92189)
## What?

Builds on #92078. Also writes the Turbopack trace to the same
.next-profiles directory.
2026-04-08 16:50:17 +02:00
Tim Neutkens cf328d3afe CPU prof: Write profiles to .next-profiles instead of .next/cpu-profiles (#92078)
## What?

Writes the CPU profiles to .next-profiles. This makes sure it's not tied
to `.next` / `.next/dev`. It's one consistent place for the file.
2026-04-08 16:08:41 +02:00
Aurora Scharff 743615ba32 docs: clarify cacheLife() cannot be called at module scope (#92326)
### What?

Update the "Good to know" callout in the `cacheLife` docs to explicitly
state that `cacheLife()` must be called inside a function body, not at
module scope, and that doing so throws an error.

### Why?

Calling `cacheLife('days')` at module scope in a file with `'use cache'`
at the top throws: `` `cacheLife()` can only be called inside a "use
cache" function ``. This is technically correct (module scope is not
inside a function), but the previous docs only said `cacheLife` "should
be placed within the function" without mentioning it errors. Both
developers and AI agents hit this when they place `cacheLife()` next to
the file-level `'use cache'` directive at the top of the module.

### How?

Replaced the soft "should be placed within the function" language with
explicit "must be called inside a function body, not at module scope"
and noted that it throws an error otherwise.

## PR checklist (Improving Documentation)

- [x] Run `pnpm prettier-fix` to fix formatting issues before opening
the PR
- [x] Follow the docs contribution guide:
https://nextjs.org/docs/community/contribution-guide

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-08 16:06:07 +02:00
Aurora Scharff aced0cfbf8 docs: add middleware.mdx deprecation stub for discoverability (#92281)
### What?

Add a `middleware.mdx` deprecation stub to the app-router file
conventions docs so that searching for `*middleware*` in the bundled
docs returns a result.

- `docs/01-app/03-api-reference/03-file-conventions/middleware.mdx` —
explains the v16 rename and links to the `proxy.js` API reference,
including the codemod command.

### Why?

The `middleware.ts` convention was renamed to `proxy.ts` in v16, but
"middleware" remains the widely understood term. Searching
`node_modules/next/dist/docs/01-app` for any file named `*middleware*`
currently returns zero results, which is confusing for both human
developers and AI coding agents that look up documentation by concept
name. This stub ensures the term "middleware" is discoverable and
immediately points users to the correct `proxy` docs.

### How?

One new `.mdx` file — no changes to existing files. The `copy_docs`
build task already globs `**/*` and renames `.mdx` → `.md`, so it will
automatically appear as `middleware.md` in `dist/docs/` on the next
build.

## PR checklist (Fixing a bug)

- This is a docs-only change, no code or tests affected.
- See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors should have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
2026-04-08 15:08:35 +02:00
Joseph 9f8d671bc4 docs: instant-navs draft, samples for build validation (#91850)
Build validation requires samples. In this case, specifically for when
params are used.
2026-04-08 12:11:47 +02:00
Aurora Scharff 9f5d93643d docs: note PPR default in cacheComponents reference (#92378)
### What?
Add a **Good to know** callout on the
[`cacheComponents`](https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheComponents)
API reference, placed after the Usage list and before **Navigation with
Activity**.

### Why?
Developers enabling `cacheComponents: true` may see routes built as
partial prerenders (`◐ (Partial Prerender)`) without ever turning on a
separate PPR flag. The Caching getting-started guide already explains
PPR as the default with Cache Components; this surfaces the same idea on
the config page people often open first, and points to migration context
for Next.js 15 experimental PPR.

### How?
Single callout: PPR is used with the flag, legacy `experimental.ppr` /
`experimental_ppr` are superseded, `◐` in `next build` is expected, with
links to [How rendering
works](https://nextjs.org/docs/app/getting-started/caching#how-rendering-works)
and [Partial Prerendering
(PPR)](https://nextjs.org/docs/app/guides/upgrading/version-16#partial-prerendering-ppr)
in the Version 16 upgrade guide.

## PR checklist (Improving Documentation)
- Ran Prettier via lint-staged on commit; run `pnpm prettier-fix`
locally if CI flags anything.
- Follow the docs contribution guide:
https://nextjs.org/docs/community/contribution-guide

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-04-08 12:09:44 +02:00
Aurora Scharff 15215a3a10 docs: add note on React canary version to View transitions guide (#92315)
## Summary

Addresses a DX friction log finding and two minor clarifications in the
view transitions guide.

### Changes

- Add note explaining that `import { ViewTransition } from 'react'`
works because Next.js rewrites it to its internal React canary build via
bundler aliases (friction log finding)
- Clarify that shared element morph works without any CSS; `share` is
only needed to customize the animation
- Minor formatting fix in Next steps links

## Test plan

- [ ] Verify guide renders correctly in docs preview

---------

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-04-08 11:19:13 +02:00
MK e513488d0d docs: clarify serverless runtime behavior for use cache (#92232)
## Summary
- add a prominent note in the App Router Caching guide about runtime
behavior on serverless deployments
- clarify that `use cache` runtime entries are in-memory and may not
persist across requests when requests hit different instances
- link directly to `use cache: remote` as the durable/shared runtime
caching option

Closes #91959

## Verification
- **Manual/source verification**
- Confirmed before change there was no mention of serverless runtime
cache persistence in `docs/app/getting-started/caching`.
- Confirmed after change the new callout appears immediately under the
existing “Good to know” note in
`docs/01-app/01-getting-started/08-caching.mdx`.
- **Evidence screenshots (before/after + verification)**
- Before:
https://raw.githubusercontent.com/wwenrr/pr-evidence-images/main/next.js/issue-91959/2026-04-01/before.png
- After:
https://raw.githubusercontent.com/wwenrr/pr-evidence-images/main/next.js/issue-91959/2026-04-01/after.png
- Verification keyword check:
https://raw.githubusercontent.com/wwenrr/pr-evidence-images/main/next.js/issue-91959/2026-04-01/verification.png

## Notes
- Formatting toolchain was not run in this environment because `pnpm` is
unavailable on host (`pnpm: not found`).
- Change is a minimal docs-only edit (single file, two inserted lines in
a callout block).

---------

Co-authored-by: wwenrr <wwenrr@users.noreply.github.com>
Co-authored-by: Joseph Chamochumbi <joseph.chamochumbi@vercel.com>
Co-authored-by: Joseph <sephxd1234@gmail.com>
2026-04-08 00:13:30 +02:00
Joseph b9a14768a2 docs: clarify that proxy/middleware matches static assets by default (#92441)
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
### What?

Adds an explicit note about Proxy's default matching behavior at the top
of the **Matcher** section in the Proxy API reference — the first place
users look when configuring which paths Proxy runs on.

### Why?

Users have reported issues where Tailwind styles and other static assets
fail to load because their Proxy auth logic intercepts `_next/static`
requests and redirects them (see #92435). The existing docs mention that
Proxy runs on "every route" but don't explicitly call out static assets,
image optimizations, or public folder files — making this a common
pitfall that gets misdiagnosed as a CSS/PostCSS problem.

### How?

Added an inline paragraph at the top of the **Matcher** subsection
explaining that without a `matcher`, Proxy matches every request —
including `_next/static`, `_next/image`, and `public/` files — and that
this can break asset loading. Links to the existing Negative matching
section.

Fixes #92435

<!-- NEXT_JS_LLM_PR -->
<!-- CURSOR_AGENT_PR_BODY_END -->

[Slack
Thread](https://vercel.slack.com/archives/C0AA1U29GQ0/p1775539745696779?thread_ts=1775539745.696779&cid=C0AA1U29GQ0)

<div><a
href="https://cursor.com/agents/bc-263e5d8f-e356-5e3a-a247-856d00a78af4"><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>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-263e5d8f-e356-5e3a-a247-856d00a78af4"><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;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Joseph <icyJoseph@users.noreply.github.com>
2026-04-07 12:07:26 +02:00
Joseph 2622a53942 docs: vt demo guide (#92249) 2026-04-02 17:19:49 +02:00
Joseph 0167a02695 Docs/adapters review (#92223)
Some corrections to the adapters docs.

- The example deploy script ran `cat .next/BUILD_ID` before `pnpm
build`. Under `set -euo pipefail` that kills the script immediately
since the file doesn't exist yet. Moved the build step first.

- `resolveRoutes` requires `URL` and `Headers` objects, not strings. The
example would cause TypeScript/runtime errors.

- Also documented the 6 return fields ~ other adapters might need to use
all of them for redirects, external rewrites, and middleware
short-circuiting.
2026-04-02 00:31:08 +02:00
Tobias Koppers 3e0158846e feat: add NEXT_HASH_SALT env var for content-hash filename salting (#91871)
### What?

Adds a `NEXT_HASH_SALT` environment variable **and** a
`experimental.outputHashSalt` config option that mix a user-supplied
string into every content-addressed hash used to generate chunk
filenames and static asset filenames. This works for both Webpack and
Turbopack.

When both are set, the values are concatenated (`outputHashSalt +
NEXT_HASH_SALT`), so a per-project salt can be baked into
`next.config.js` while a per-deployment salt is injected at build time
via the environment variable.

### Why?

Content-addressed filenames (e.g. `chunk.abc123.js`) are derived from
file content, so they only change when the content changes. There are
deployment scenarios where you need to force all filenames to rotate —
for example after a CDN misconfiguration has poisoned caches for a
particular hash space — without actually changing source code. A stable,
opt-in salt lets operators do this without touching application code.

Some customers prefer the config-file approach
(`turbopack.outputHashSalt`) over environment variables, so both are
supported.

### How?

**Webpack** already has `output.hashSalt` in its config. We simply
forward `NEXT_HASH_SALT` to that option.

**Turbopack** required threading the value through several layers:

1. The effective hash salt is computed once in
`assignDefaultsAndValidate` as `config.turbopackHashSalt =
(turbopack.outputHashSalt ?? '') + (NEXT_HASH_SALT ?? '')` and stored on
`NextConfigComplete`. Both `turbopackBuild` (production) and
`createHotReloaderTurbopack` (dev) read from this single field.
2. `ProjectOptions.hash_salt` receives the pre-computed salt.
3. `Project` stores the salt and passes it into the three chunking
context option structs (`ClientChunkingContextOptions`,
`ServerChunkingContextOptions`, `EdgeChunkingContextOptions`).
4. Both `BrowserChunkingContext` and `NodeJsChunkingContext` gain a
`hash_salt: RcStr` field.
5. A new `deterministic_hash_with_salt(salt, input, algorithm)` function
in `turbo-tasks-hash` writes the salt bytes first, then the content
bytes, into a single hasher — one pass, no hash-of-hash composition.
6. A matching `content_hash_with_salt` method is added to `FileContent`
and `AssetContent`.
7. `ChunkingContext::asset_path` is changed to accept `Vc<AssetContent>`
(instead of a pre-computed `Vc<RcStr>`) so the chunking context can
choose the correct hash path itself. `StaticOutputAsset::path`
simplifies accordingly.

Without `NEXT_HASH_SALT` and without `turbopack.outputHashSalt` set,
behaviour is identical to before — no hash change, no performance
impact.

**e2e test** (`test/production/app-dir/hash-salt/`) verifies:
- Two builds with the same salt produce identical chunk and static asset
filenames.
- A build with a different salt produces different filenames.
- `turbopack.outputHashSalt` (config) changes filenames vs no salt.
- Combined config + env salt differs from either alone.
- Runs for both Turbopack and Webpack.

---------

Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Luke Sandberg <lukesandberg@users.noreply.github.com>
2026-04-01 22:03:50 +02:00
JJ Kasper cc710321a0 docs: clarify id, filePath, and pathname in STATIC_FILE adapter output (#92227)
## What

Adds documentation for the `id`, `filePath`, and `pathname` properties
in the `STATIC_FILE` adapter output type.

## Why

These three string properties were previously undocumented or had
ambiguous descriptions. Based on feedback from the team:
- `id` is a unique identifier for the static file output
- `filePath` is the absolute filesystem path to the built file
- `pathname` is the routable URL pathname

## Changes

- Added JSDoc comments to the `STATIC_FILE` type definition in
`build-complete.ts`
- Updated the MDX documentation in `output-types.mdx` with clearer
inline comments
2026-04-01 11:06:09 -07:00
Joseph faa4b99296 docs: local images referenced by remote source (#92178)
It was discovered that one could let a remote source, safely-ish, load
local images, which has the benefit of providing, width, height, src,
and blur-* props which we could pass to next/image.

Closes:
https://linear.app/vercel/issue/DOC-6288/local-images-referenced-by-a-remote-source
2026-04-01 18:38:39 +02:00
Aurora Scharff 495d50f187 docs: document revalidateTag's required second argument in upgrade guide (#92134)
### What?

Add a before/after migration snippet to the version 16 upgrade guide
showing the old single-argument `revalidateTag('posts')` and the new
required two-argument `revalidateTag('posts', 'max')` signature. Also
mention the TypeScript error users will see and the `updateTag`
alternative for immediate expiration.

### Why?

Users upgrading from Next.js 15 to 16 encounter `Expected 2 arguments,
but got 1` when using the old single-argument syntax. The upgrade guide
previously only showed the new code without showing the old pattern,
requiring users to search externally to understand what changed.

### How?

- Added a concise `// Before` / `// After` code block showing the
migration, matching the convention used elsewhere in the upgrade guide
(e.g. `next/legacy/image`)
- Added a note that the single-argument form produces a TypeScript error
- Added a note pointing to `updateTag` as the alternative for immediate
expiration
- Kept the original full example with stale-while-revalidate behavior
explanation

## PR checklist (Improving Documentation)

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR
- Follow the docs contribution guide:
https://nextjs.org/docs/community/contribution-guide
2026-03-31 20:34:23 +02:00
JJ Kasper 6a2045936f docs: add middleware bypass note to CDN caching guide (#92132)
## Summary
- add a Good to know note in the CDN Caching guide
- clarify that if Proxy/Middleware runs behind the CDN cache,
middleware-dependent requests should bypass cache so Proxy/Middleware
remains the source of truth

---------

Co-authored-by: Joseph <sephxd1234@gmail.com>
2026-03-31 09:34:04 -07:00
JJ Kasper 0cb1547d59 Move expanded adapters docs to API reference (#92115)
## Summary
- move adapter implementation docs from
`app/api-reference/config/next-config-js/adapters` to
`app/api-reference/adapters`
- keep `adapterPath` as an entry page that points to the new adapters
section
- add matching Pages Router pointer docs under
`pages/api-reference/adapters`
- update existing docs links that referenced old `adapterPath#...`
anchors to the new adapters routes
2026-03-30 12:54:56 -07:00
Aurora Scharff 039c56f707 docs: clarify that use cache requires async functions (#92101)
### What?

Update the "Good to know" note in the `use cache` directive docs to
clarify that functions and components using `use cache` must be `async`
at all levels — not just at file level.

### Why?

Users get the build error `"use cache" functions must be async
functions` when applying the directive to a synchronous component. The
existing note only mentions the file-level case ("When used at file
level, all function exports must be async functions"), which implies the
async requirement doesn't apply at component or function level.

### How?

Updated the "Good to know" callout to state the requirement applies to
all functions and components using `use cache`, with the file-level case
as additional context.

## PR checklist (Improving Documentation)

- Run `pnpm prettier-fix` to fix formatting issues before opening the PR
- Follow the docs contribution guide:
https://nextjs.org/docs/community/contribution-guide

---------

Co-authored-by: Joseph Chamochumbi <joseph.chamochumbi@vercel.com>
2026-03-30 16:13:03 +02:00
Aurora Scharff e586cda317 Update revalidateTag examples to use the new two-argument signature (#92065)
### What?

Updated all documentation examples of `revalidateTag` to use the new
two-argument signature (`revalidateTag(tag, 'max')`) instead of the
deprecated single-argument form (`revalidateTag(tag)`).

### Why?

The `revalidateTag` API now requires a second `profile` argument. Using
the old single-argument form causes a TypeScript build error: "Expected
2 arguments, but got 1". Several documentation pages still showed the
old signature, which would lead developers to write code that fails to
compile.

### How?

Updated 14 call sites across 6 documentation files to pass `'max'` as
the second argument, which is the recommended default for
stale-while-revalidate semantics:

- `docs/01-app/02-guides/incremental-static-regeneration.mdx`
- `docs/01-app/02-guides/redirecting.mdx`
- `docs/01-app/02-guides/caching-without-cache-components.mdx`
- `docs/01-app/02-guides/backend-for-frontend.mdx`
- `docs/01-app/02-guides/how-revalidation-works.mdx`
- `docs/01-app/03-api-reference/04-functions/cacheTag.mdx`

The `revalidateTag.mdx` API reference page and `09-revalidating.mdx`
getting started page were already updated. The `self-hosting.mdx` cache
handler method signature (`async revalidateTag(tags)`) is unrelated and
left unchanged.
2026-03-28 21:09:24 -07:00
Joseph 4ceb770531 docs: opengraph-image papercuts (#92018)
Follow up to https://github.com/vercel/next.js/pull/91893
2026-03-28 19:09:53 -07:00
Remco Haszing 820578db40 Narrow the opengraph-image function return type (#91893)
### What?

Change the `opengraph-image` return type to only `Response`.

### Why?

This function must return a `Response` object. The other documented
types cause Next.js builds to fail. I found this out the hard way by
following the documentation.

### How?

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-03-27 13:43:41 -07:00
Jude Gao 3cee3a375b [Docs] Rewrite agent rules to match bundled doc wording (#91995)
Updates the AGENTS.md snippet in the AI agents guide to match the wording shipped in the bundled docs. The previous version used softer language ("ALWAYS read docs before coding") that diverged from what `node_modules/next/dist/docs/` actually ships. This aligns the two so agents see consistent instructions regardless of where they read them.
2026-03-27 12:34:07 -07:00
Tim Neutkens 2ea43d64c9 docs: document CSS decimal precision difference between Turbopack and webpack (#91909)
## Description

Documents the CSS decimal precision difference between Turbopack and
webpack in the Turbopack docs page under "Known gaps with webpack".

Turbopack uses Lightning CSS which outputs 5 digits of decimal precision
for numeric CSS values, while webpack uses 10 digits. This applies to
both plain CSS and Sass/SCSS output.

Closes https://github.com/vercel/next.js/issues/91862
2026-03-25 11:48:52 -07:00
Jimmy Lai cc62489bbd docs: add verified adapters section (#91849)
## Summary

- Introduces the **verified adapter** concept to deployment docs: open
source adapters that run the Next.js compatibility test suite, hosted
under the Next.js GitHub org
- Splits the adapter list on the deploying page into **Verified
Adapters** (Vercel, Bun) and **Other Platforms** (unverified
integrations)
- Documents the Next.js team's commitments for verified adapters and
Ecosystem Working Group participants (coordinated testing, early access,
direct support)
- Notes that Cloudflare and Netlify are working on verified adapters
built on the Adapter API

## Test plan

- [ ] Verify links resolve correctly (adapter API reference, test suite
anchor, ecosystem working group page)
- [ ] Confirm markdown table renders properly with the longer "Varies"
cell
- [ ] Review wording with stakeholders (Cloudflare, Netlify, Bun)

---------

Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
2026-03-25 00:56:37 +01:00
Jam Balaya 7dd1fcfc92 chore(examples): remove with-styletron example (#81842)
## Summary

Remove
[with-styletron](https://github.com/vercel/next.js/tree/canary/examples/with-styletron)
example and its references from the repository.

Documentation:
- Remove the Styletron link from the CSS-in-JS examples list in the docs

Tests:
- Remove the Styletron entry from the
turbopack-dev-examples-manifest.json

Chores:
- Delete the examples/with-styletron directory and its contents

## Why?

[styletron](https://github.com/styletron/styletron) package hasn't been
maintained in 2 years.

## Adding or Updating Examples

- [x] The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- [x] Make sure the linting passes by running `pnpm build && pnpm lint`.
See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

cc: @samcx

Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
2026-03-24 02:25:32 +01:00