Commit Graph
677 Commits
Author SHA1 Message Date
Ayodele Samuel AdebayoandGitHub 22fc63da72 docs: fix typos and links (#92541)
This PR cleans up small documentation and error-page issues: correct
TypeScript spelling where it was written as “Typescript”, use the proper
GitHub label in links, fix the MDN URL for `Map.prototype.values` in the
middleware upgrade guide.

No runtime or API behavior changes.
2026-05-13 10:25:23 +02:00
Sam SelikoffandGitHub 215a08e2da Disable instant validations in draft mode (#93472)
This PR makes dev-mode cache bypass behavior consistent when `draftMode`
is enabled. Draft mode now skips Instant Insights validation the same
way a hard refresh or DevTools “Disable Cache” request does, and the
Next.js devtools badge shows the existing “Cache disabled” state for
draft-mode previews.

It also adds coverage for draft-mode cache bypass behavior in dev and
start modes, plus a devtools badge test, and updates the
`cache-bypass-in-dev` docs to explain why draft mode triggers this
state.
2026-05-06 20:59:04 +00:00
Josh StoryandGitHub d86e197728 Support configuring a default instant validation level (#93301)
Adds `experimental.instantInsights.validationLevel` so an app can opt
into instant validation for all routes by default.

There are two public levels
* `manual-warning`: currently the default. this mode won't enable
instant validation except where you add `export const unstable_instant =
true` into your Layouts, Pages, and Default files
* `warning`: This mode will enable instant validation for all Page and
Default files. You can override this with `export const unstable_instant
= false` in Layouts, Pages, and Default files to tune what navigations
are validated.

In addition this change disables build time validation.

There is a now undocumented way to get back to running build validation
with
* `experimental-error`
* `experimental-manual-error`

The build validation isn't ready for users because we need to overhaul
the setup where you provide cookies and other sample values so we can
run validation without a live session like we do in dev.

To further support this the two remaining object properties that are
also not ready for active use, `samples` and `from` are being updated to
`unstable_samples` and `unstable_from` respectively.

We will continue to iterate on build time validation but may remove
these APIs or alter their semantics as we figure out a more ergonomic
way to support this setup.

In anticipation of multiple levels the object form of `instant` can be
provided a level value `warning` or `experimental-error`. this latter
option is similarly undocumented so documented behavior will only cover
`warning` which is generally a synonym of true unless you are activating
error by default
2026-05-06 10:37:50 -07:00
Tim NeutkensGitHubVercel <vercel[bot]@users.noreply.github.com>
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
241ac2d62b New ESLint rule: no-location-assign-relative-destination (#92900)
## For Contributors

### Adding a feature

Adding a new ESLint rule to `eslint-plugin-next` reporting
`location.href = [relative URL]` or `location.assign([relative URL])`
usage.

For some reason, some LLM models prefer this incorrect pattern, and
avoid `redirect()` or `useRouter().push()` at all costs. But at least
many of them do respect ESLint, by adding a new rule we can enforce
correct behavior.

The error documentation and unit test cases are also added.

---------

Co-authored-by: Joseph <[email protected]>
Co-authored-by: Benjamin Woodruff <[email protected]>
2026-04-19 23:25:35 +00:00
Mukunda Rao KattaandGitHub 219c0bcee9 docs: add documentation for no-typos ESLint rule (#92809)
## Summary

The `@next/next/no-typos` rule ships in `@next/eslint-plugin-next` but has no corresponding page under `errors/`, so users who click through from ESLint config inspectors (or from other rule-docs links) hit a 404.

This adds `errors/no-typos.mdx` describing:
- What the rule catches (`getStaticProps` / `getStaticPaths` / `getServerSideProps`)
- A standard before/after example
- A **casing** example (since the rule uses a 1-char edit-distance threshold — casing typos like `getServerSideprops` also trip it)

## Context

This re-attempts #89436 (closed, not merged) with @lukesandberg's two review comments applied:

1. **Title** shortened from *"No typos in Next.js data fetching functions"* → **"No Typos"**, matching other sibling rule docs in `errors/`.
2. **Casing example** now actually contains a casing error (`getServerSideprops`); the previous version listed `getServerSideProps` as "incorrect casing", which had no casing error.

Fixes #67342

## Test plan

- [x] File lives under `errors/` alongside sibling rule docs (`no-document-import-in-page.mdx`, `no-unwanted-polyfillio.mdx`, etc.)
- [x] Frontmatter + heading structure matches sibling docs
- [x] Code fences use the same `filename=...` convention as sibling docs
- [x] No manifest file under `errors/` — sibling additions (e.g. `no-unwanted-polyfillio.mdx`) did not touch an index
2026-04-15 15:31:12 -07:00
Aurora ScharffandGitHub 053300c1fb docs: improve blocking-route error page for params discoverability (#92359)
### What?

Improves the `blocking-route` error doc (`errors/blocking-route.mdx`) to
make it easier to connect the "Uncached data was accessed outside of
`<Suspense>`" error to `await params` in a Page component.

### Why?

When a build fails with this error and the only callsite is `const { id
} = await params`, there's no indication that awaiting `params` directly
in a Page triggers it. The fix pattern (pass the `params` Promise to a
Suspense-wrapped child) exists in the doc under "Params and
SearchParams" but developers and AI agents won't find it without
`--debug-prerender` stack traces.

### How?

- Added a "common triggers" list to the "Why This Error Occurred"
section so developers can quickly pattern-match their code
- Added a `--debug-prerender` tip for getting detailed stack traces
- Added a concrete `params` before/after example showing the exact fix
pattern
- Listed all three fix options upfront: `<Suspense>` wrapping,
`loading.js`, or `generateStaticParams`

## 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)
2026-04-08 15:13:36 +02:00
Hendrik LiebauandGitHub 4f69336336 Support accessing root params in generateStaticParams (#91189)
A new `GenerateStaticParamsStore` work unit store type is now provided during `generateStaticParams` execution. This enables root param getters (`import { lang } from 'next/root-params'`) to be called inside `generateStaticParams`, allowing shared helpers that internally access root params via the special import to be used in both Server Components and `generateStaticParams` without manually threading params.

Each `generateStaticParams` call now runs within a `workUnitAsyncStorage.run()` context carrying a `GenerateStaticParamsStore` with the correct `rootParams` (extracted from `parentParams` using the already-available `rootParamKeys`). The store extends `CommonWorkUnitStore`, providing `phase` and `implicitTags` which are not strictly necessary but convenient to keep call sites simple.

Request-time APIs (`headers()`, `cookies()`, `connection()`, `draftMode()`) now throw specific errors when called inside `generateStaticParams` instead of the previous generic "called outside a request scope" message. Framework-internal functions like `createSearchParamsFromClient` and `createParamsFromClient` throw `InvariantError` since they should never be reached in this context.

This change also unblocks a follow-up PR that removes `| undefined` from `PublicCacheContext.outerWorkUnitStore` in the use cache wrapper, since `"use cache"` is already supported inside `generateStaticParams` today but previously ran without a `WorkUnitStore`. With this store in place, requiring a `WorkUnitStore` in `"use cache"` won't break that existing usage.
2026-03-16 15:44:53 +01:00
6155ca1722 docs: large page data error (#90920)
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
<!-- 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?
Improve the `errors/large-page-data.mdx` error page.

### Why?
The existing error page lacked clarity on the `__NEXT_DATA__` mechanism,
performance impacts, configuration options, and its applicability solely
to the Pages Router. This led to confusion, as highlighted in community
discussions:
-
https://github.com/vercel/next.js/discussions/38364#discussioncomment-3090327
-
https://github.com/vercel/next.js/discussions/60193#discussioncomment-8010640

### How?
- Added a note clarifying this warning applies only to the Pages Router.
- Explained the `__NEXT_DATA__` mechanism, why the threshold exists, and
its performance implications (page weight, hydration, memory).
- Provided actionable suggestions to reduce data size (filter, paginate,
client-side fetching).
- Documented the `experimental.largePageDataBytes` configuration option
with a `next.config.js` example.
- Included relevant external links for further reading.

Closes NEXT-
Fixes #
-->

---
[Slack
Thread](https://vercel.slack.com/archives/C08N392Q9EV/p1772698459867909?thread_ts=1772698459.867909&cid=C08N392Q9EV)

<p><a
href="https://cursor.com/agents/bc-f75e35d4-cde9-5300-8c76-b4a67c24d55f"><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-f75e35d4-cde9-5300-8c76-b4a67c24d55f"><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;</p>


<!-- CURSOR_AGENT_PR_BODY_END -->

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Joseph <[email protected]>
2026-03-07 01:53:53 +01:00
Delba de OliveiraGitHubVercel <vercel[bot]@users.noreply.github.com>Joseph
c2b4c0815c Unify caching story across the docs (#90149)
This PRs unifies the caching story across the docs, making Cache
Components the happy path, while still providing guidance to users in
the old model. However, instead of explaining the old model and its
caching layers, we've created a new guide focusing on what APIs to use
and when.

This follow-up PR aligns terminology across the docs:
https://github.com/vercel/next.js/pull/90589

## IA updates

Getting Started section: 

- Improves Getting Started progression:
- **Before:** CC → Fetching Data → Updating Data → Caching and
Revalidating (old and new model mixed)
- **After:** Fetching Data (Dynamic) → Mutating Data (Dynamic) → Caching
with CC (Prerendering) → Revalidating with CC.
- New: `caching.mdx` (CC-first)
   - Structure: 
      - Enabling Cache Components
      - Data vs UI-level caching
      - Working with request time APIs
      - Passing request values to cached functions
      - Working with non-deterministic operations
      - Working with synchronous operations
      - How rendering works (PPR and static shell story)
- New: `revalidating.mdx` (CC-first)
   - Explains how to use `cacheLife` and `cacheTag`

Guides Section: 

- New: `caching-and-revalidating.mdx` (Previous Model)
- For users who are not using CC, includes `fetch` options and route
segment config
- Moves route segment config options that don't apply to CC from API
reference to this guide (for easy archiving in the future).
- New: `migrating-to-cache-components.mdx` (WIP)
- Del: `caching.mdx` 😌 

## Terminology

We should remove caching layers from the docs. Users only needed to be
exposed to them when they were configured independently, but the new CC
APIs work across layers.

To make it easier to review this PR, I'm consolidating terminology and
fixing broken links in a new PR:
https://github.com/vercel/next.js/pull/90589

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Joseph <[email protected]>
2026-03-03 13:14:24 +00:00
JosephandGitHub 5f26a684e6 docs: rework version staleness (#90192)
Closes:
https://linear.app/vercel/issue/DOC-6144/error-page-version-staleness
2026-02-24 15:38:49 +01:00
JosephandGitHub 43c9a4915a docs: improve next/image localPatterns error page (#89914)
Align with https://nextjs.org/docs/messages/next-image-unconfigured-host

Closes:
https://linear.app/vercel/issue/DOC-5850/feedback-image-configuration-it-doesn-t-work-my-pattern-is-defined-as
2026-02-13 11:18:04 +01:00
6627734522 docs: add deploymentId config and clarify encryption key for self-hosting (#89795)
Closes:
https://linear.app/vercel/issue/DOC-3953/encryption-keys-in-server-actions,
https://linear.app/vercel/issue/DOC-4975/next-server-actions-encryption-key-and-deploymentid

Closes https://github.com/vercel/next.js/discussions/88327

---------

Co-authored-by: Allen Zhou <[email protected]>
2026-02-12 16:33:39 +01:00
be56ce3ae8 docs: correct use term (#89438)
### What?

`use` is not a hook. It's highlighted in the doc

> Unlike React Hooks, use can be called within loops and conditional
statements like if. Like React Hooks, the function that calls use must
be a Component or Hook.


### Why?

It confuses consumers of Next.js and adds field provide misleading
proofs

### How?

Closes NEXT-
Fixes #

-->

---------

Co-authored-by: Joseph <[email protected]>
Co-authored-by: Joseph <[email protected]>
2026-02-11 11:51:57 +01:00
Janka UrygaandGitHub 2521b8adc7 [Instant] Instant validation in Dev (#89077)
This PR implements the initial version of dev-time validation for
`export const instant = ...`

```tsx
export const instant = { prefetch: 'static' }
```
```tsx
export const instant = { prefetch: 'runtime', ... }
```
```tsx
export const instant = false
```
(the config is currently expected to be named `unstable_instant`, but
i'll be shortening it to `instant` below.)

When a segment specifies an instant config with `prefetch: 'static'` or
`prefetch: 'runtime'`, we'll validate that all (prefetched) navigations
into that segment will render instant UI, i.e. that the navigation won't
block. On the other hand, if a segment is allowed to block, it must be
marked with `export const instant = false`.

Note that our existing static shell validation is a special case of
this, but for now, we're keeping both. A future PR will reimplement
static shell validation as a special case of instant validation.

Like static shell validation, these validations currently run in dev
whenever we render the full page (i.e. no segments are omitted). This
means it'll happen on an initial load (or refresh) and HMR.

### Implementation notes

#### Validation approach

The goal is to simulate what the browser would display for a prefetched
client navigation. We do this by re-assembling the segments extracted
from the original stream for the page.
- The outer (shared) segments should already fully resolved (i.e. in the
Dynamic stage), to represent the fact that the browser loaded them
before
- The new segments are either in Static or Runtime stage, depending on
how each segment would have been prefetched.

Similar to static shell validation, we then perform a Fizz prerender on
the combined payload, abort it, and track the locations of `onError`
calls. The difference here is that unlike static shell validation, we
require a Suspense boundary *inside* the new subtree. This is detected
by adding a `InstantValidationBoundary` around the new subtree when we
construct the payload, and checking if there's a suspense below that in
the component stack.

Currently, for each `instant` config we find, we take each of its parent
layouts as a possible navigation parent (unless it's marked as
blocking). So if we have a page with parent layouts like this:
```
/layout.tsx
/foo/layout.tsx
/foo/bar/layout.tsx
/foo/bar/page.tsx <- `export const instant = { prefetch: 'static' }`
```
Then we'll check for navigations where each of `/layout.tsx`,
`/foo/layout.tsx` and `/foo/bar/layout.tsx` is a fully resolved shared
parent.

If a validation fails, we do a "discriminated error message" flow
analogous to static shell validation. Static segments are replaced with
Runtime segments to see if the error goes away, which lets us determine
if the hole is caused by runtime or dynamic data.

#### Building the combined payload

First, we need to separate the full stream into segments. The process is
similar to `collectSegmentData` -- we need to deserialize the payload
from the stream and then re-serialize each segment separately. The
complexity here comes from the fact that the full stream is separated
into stages, and we need each segment to be in staged form as well. This
lets us pick and choose which stage the segment is in to simulate what
we'd show for a static or runtime prefetch.

The other complex part is the "late release trick" (as implemented in
`createNodeStreamWithLateRelease`). This was already done for static
shell validation, but it's more complex here.

Debug info for dynamic holes is usually delayed until a further stage.
So, in the static stage we only see an unresolved promise (or lazy
reference), and then in the runtime stage we get the debugInfo telling
us that it was caused by `await cookies()`. To ensure that this debug
info is available for purposes on error reporting, we do a "late
release" -- before we abort, we advance the each segment to the dynamic
stage, which won't cause any new content to render, but will provide
Fizz with debug info and thus give us precise error locations in
`onError`. If you see `releaseSignal`, that's what it's for.

#### `instant` on layouts

We support specifying `instant` on layouts. The validation principle is
the same, but note that in the current mode (validating a single page in
dev) we can't enforce that *all* navigations into that layout satisfy
the constraint, we can only check if that's satisfied for the current
page.

#### Blocking segments

A segment can be marked as blocking with
```tsx
export const instant = false
```
This is meant to signal that this segment deliberately does not have
instant UI.

Currently, this is affects validation as follows:

If there's no `instant` config in parent segments, skip validating all
navigations where this layout would be new (because we know it'd block),
i.e. only validate navigations where it's a shared parent. Children of
this segment can still have `instant` configs of their own, and those
will be validated. This allows structures where a layout is blocking,
but once it's loaded, navigations within it should have instant UI.

If there is an `instant` config in a parent segment, the validation of
that parent is *not* skipped. The reasoning here is that if a layout
asserts that navigations into it should have static UI, then a child
with `instant = false` should not violate that. This essentially
requires that the child have a `loading.js` or that the layout has to
wrap the slot with Suspense.

Note that `instant = false` can also be used to opt segements out of
static shell validation without requiring a Suspense above body.

### Limitations and planned follow-ups

- `instant` configs in parallel routes (i.e. `@slot`) are not currently
validated.
- `expectUnableToVerify` is not implemented yet, i.e. there's no way to
say "this cannot be validated using SSR". The shared segments are not
expected to suspend. For now, `export const instant = { prefetch: ...,
unstable_disableValidation: true }` can be used to bypass a segment if
validating it causes problems.
- static shell validation is a special case of instant validation, but
is not currently implemented as such.
- we should be able to validate during client navigations, not just
full-page loads and HMR, but we currently can't because we don't have
all the segments when we do that, so we can't assemble a proper combined
payload.
2026-02-05 19:14:19 +01:00
Hendrik LiebauandGitHub 469e513c5f Require explicit cacheLife on outer "use cache" when nesting short-lived caches (#89481)
This PR adds error handling for nested `"use cache"` where the inner
cache has a very short lifetime (zero `revalidate` or `expire` under 5
minutes) but the outer cache doesn't have an explicit `cacheLife()`
call.

Short-lived caches become "dynamic holes" that are excluded from
prerenders. When such a cache is nested inside another `"use cache"`
without an explicit `cacheLife`, the outer cache's lifetime would
silently become short too via
[propagation](https://nextjs.org/docs/app/api-reference/functions/cacheLife#nested-caching-behavior),
which can lead to unexpected behavior. To prevent this accidental
misconfiguration, Next.js now throws an error during prerendering,
requiring developers to explicitly declare their intent by adding
`cacheLife()` to the outer cache.

The implementation tracks whether `revalidate` and `expire` were
explicitly set via `hasExplicitRevalidate` and `hasExplicitExpire` flags
on the collected cache result. Errors are wrapped with
`wrapAsInvalidDynamicUsageError` to capture proper stack traces and
prevent userland try/catch from suppressing the build error.

Documentation has been updated with a new "Prerendering behavior"
section in the `cacheLife` API reference explaining how short-lived
caches become dynamic holes, and a "Nested short-lived caches"
subsection with examples showing how to fix the error.

closes NAR-761
2026-02-05 15:39:08 +00:00
Janka UrygaandGitHub 812996cc60 [CC] Rename "unstable_prefetch" to "unstable_instant" (#89448)
Mostly mechanical rename.

Also changes the error page to `errors/invalid-instant-configuration`.
I'm not really worried about dangling links here because this is a new
API and we don't expect anyone to be using it yet.
2026-02-04 22:03:38 +01:00
BrookeandGitHub 82ad0dd23e [nextjs] feat: removing length requirement (#89173)
Not a hard requirement so removing in [response to
request](https://github.com/vercel/next.js/pull/88958#discussion_r2735487290)
2026-01-28 22:36:17 +00:00
BrookeandGitHub 1cbd83bff6 [prebuilt-skew-protection] feat: adding in automatic deploymentId (#88958) 2026-01-27 16:50:49 +01:00
Sebastian "Sebbie" SilbermannandGitHub b08e16b21a Revert "[prebuilt-skew-protection] feat: adding in automatic deploymentId" (#88942) 2026-01-23 12:22:37 +01:00
BrookeGitHubvercel[bot] <35613825+vercel[bot]@users.noreply.github.com>JJ Kasper
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 <[email protected]>
2026-01-22 21:07:34 +00:00
BrookeandGitHub 201c9604b6 Revert "[prebuilt-skew-protection] feat: adding in automatic deploymentId" (#88449)
Reverts vercel/next.js#88012
2026-01-12 14:14:22 -08:00
BrookeGitHubgraphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>JJ KasperSteven
0daf2b58b4 [prebuilt-skew-protection] feat: adding in automatic deploymentId (#88012)
<!-- 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?

https://linear.app/vercel/issue/FLOW-5530/nextjs-support-automatic-deploymentid-generation

### Why?
So users can configure a deploymentId, to be used for skew protection
with prebuilts

### How?

Closes NEXT-
Fixes #

-->


https://linear.app/vercel/issue/FLOW-5530/nextjs-support-automatic-deploymentid-generation

So users can configure a deploymentId, to be used for skew protection
with prebuilts

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: JJ Kasper <[email protected]>
Co-authored-by: Steven <[email protected]>
2026-01-12 13:27:26 -08:00
ac4f404c97 docs: generateMetadata and generateViewport w/ CC (#87218)
Co-authored-by: Rich Haines <[email protected]>
2025-12-19 18:05:06 +01:00
JosephandGitHub 6cc51a3b8a docs: dynamic routes w/ gsP (#86402) 2025-12-12 14:51:29 +01:00
7e093afb8c Eslint: Improve Google Tag manager third parties message (#51903)
Note: new PR description written by @timneutkens 

## What?

Improves the detection of Google Tag Manager vs Google Analytics.
As indicated by the author of this PR it was confusing that when you
have Google Tag Manager set up it gives you an error message saying
you're adding Google Analytics even though it's Tag Manager.

I've updated the PR to have a separate message for Google Tag Manager
and expanded the error message docs too.

It also mentioned `next/script` in a bunch of places even though the
error doc recommends `@next/third-parties`. I've updated all cases to
refer to `@next/third-parties` instead.

<details>
<summary>Previous PR description</summary>
Google has multiple products with similar names: the "Google Tag" and
"Google Tag Manager". Google Tag Manager uses `gtm.js` whereas the
"Google Tag" uses `gtag`. Google Analytics previously used
`analytics.js` (<2017) and is now delivered via the "Google Tag".

Google Tag: `www.googletagmanager.com/gtag/js`
Google Tag Manager: `www.googletagmanager.com/gtm.js`

The `next-script-for-ga.ts` rule's matching list
(`SUPPORTED_HTML_CONTENT_URLS`) includes `gtm.js` which means when a
developer adds Google Tag Manager to their NextJS website, they'll
receive the warning and be encouraged to swap from `gtm.js` to `gtag`. A
developer asleep at the wheel (...me) may think...

> I'm using Google Analytics via Google Tag Manager, and NextJS is
suggesting I swap `gtm.js` for `gtag` because it will improve
performance. `gtag` sounds like it is part of "Google Tag Manager" so I
am going to follow the instructions so that my website is faster.

However, `gtag` is **not** compatible with `gtm.js` (they're different
products with similar names and similar purposes) and so making this
change will cause very confusing Google Tag Manager behaviour. I am
suggesting that `gtm.js` is removed completely from the rule, because
anyone using `gtm.js` should not be following these instructions. A
separate rule could be added specifically for Google Tag Manager, that
does not refer to `gtag`.
</details>

---------

Co-authored-by: Tim Neutkens <[email protected]>
2025-11-24 14:29:52 +01:00
JosephandGitHub 897d021d96 docs: csr-bailout debugging (#86359)
I think maybe these others need a hint too, let's get started with,
`errors/missing-suspense-with-csr-bailout` and `errors/prerender-error`

- errors/blocking-route.mdx
- errors/deopted-into-client-rendering.mdx
- errors/dynamic-server-error.mdx
- errors/next-prerender-crypto.mdx
- errors/next-prerender-current-time.mdx
- errors/next-prerender-sync-headers.mdx
- errors/next-prerender-sync-params.mdx
- errors/sync-dynamic-apis.mdx
2025-11-21 11:11:12 +01:00
3f4db01dbc [Cache Components] Discriminate static shell validation errors by type (#85747)
Prior to this change any "hole" in a prerender that would block the
shell was considered an error and you would be presented with a very
generic message explaining all the different ways you could have failed
this validation check.

With this change we use a new technique to validate the static shell
which can now tell the difference between waiting on uncached data or
runtime data. It also improves the heuristics around generateMetadata
and generateViewport errors.

Added new error pages for runtime sync IO and ensure we only validate
sync IO after runtime data if the page will be validating runtime
prefetches.

Restored the validation on HMR update so you can get feedback after
saving a new file.

---

We've also discovered that hanging inputs are not handled correctly.
Fixing this is non-trivial and will be done in a follow-up, so for now,
we're disabling the failing tests.

---------

Co-authored-by: Josh Story <[email protected]>
Co-authored-by: Hendrik Liebau <[email protected]>
2025-11-20 17:13:37 +01:00
JosephandGitHub 4cae094393 docs: cache components - introduction (#85196) 2025-10-22 12:41:45 +02:00
Andrew ClarkandGitHub 0a3f1e45f4 Rename "blocking route" error docs page (#85189)
The content needs to be updated, too, but for now this just fixes the
link and title so it matches the updated error message in #85087.
2025-10-21 15:43:36 -04:00
Jiwon ChoiGitHubJosephgraphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2cc5f0227b Add Learn more docs to Middleware deprecation warning (#84711)
This PR adds an error doc for the Middleware deprecation warning that it
can refer to.

  - Explain why this error occurred
  - Provide migration guide
  - Explain the rationale for the renaming to Proxy

---------

Co-authored-by: Joseph <[email protected]>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-10-20 19:26:30 -07:00
Wyatt JohnsonandGitHub 3cd8a23446 feat(cache-components): require non-empty generateStaticParams for validation (#85135)
### What?

This PR adds build-time validation that requires `generateStaticParams`
to return at least one result when Cache Components (experimental
`cacheComponents` feature) is enabled.

### Why?

Previously, users could return an empty array (`[]`) from
`generateStaticParams` to indicate a route should be treated statically
without providing specific parameter values. This pattern has a critical
issue with Cache Components:

**The Problem:**
- With Cache Components enabled, accessing `params` is treated as a
dynamic API usage
- When `generateStaticParams` returns empty results, Next.js cannot
perform build-time validation to detect if the route accesses other
dynamic APIs (like `await cookies()`, `await headers()`, or `await
searchParams`)
- This means users could successfully build routes that would fail at
runtime with dynamic API errors

**The Solution:**
- By requiring at least one parameter value, we can execute the route
during build time with real params
- This allows us to validate that the route doesn't make additional
dynamic API calls that would cause runtime failures
- Build-time validation catches configuration errors early, before
deployment

### How?

- Modified `buildAppStaticPaths` in
`packages/next/src/build/static-paths/app.ts` to check if PPR is enabled
and throw error when `generateStaticParams` returns empty array with
Cache Components enabled
- Added comprehensive error documentation at
`errors/empty-generate-static-params.mdx` with migration options

Migration paths provided in error documentation:
1. Return at least one real param (recommended)
2. Use placeholder params (not recommended, bypasses validation)

The breaking change is acceptable because `cacheComponents` is still
experimental and only available in canary releases.

### Related

- Addresses discrepancy discovered with
https://github.com/vercel/next.js/discussions/84925.
- Fixes https://github.com/vercel/next.js/issues/84801
2025-10-20 18:22:42 -06:00
ca7f57ee2d Docs: Add version history for next lint deprecation and update error message (#85100)
Co-authored-by: Joseph <[email protected]>
2025-10-20 19:58:07 +00:00
Josh StoryandGitHub 49fcbd93f2 [Cache Components] When caches are disabled in dev skip the cache warmup (#85014)
In Dev, to ensure the component metadata that powers React DevTools
accurately reflects the cached, prerendered, or dynamic nature of Server
Components, Next.js ensures that any caches encountered during the
prerender are warm before streaming.

However when users have chrome devtools open with "disable caches" or
when a hard refresh is performed requests are made with a cache header
that instructs Next.js to bypass all server caches. In these cases every
request will always have empty caches and thus the entire request will
block on the time it takes to fill all caches. It isn't reccomended to
typically disable cache while developing with Next.js because it is even
more aggressive than the cold cache scenario real users would encounter
with a production deployment. But there are some reasons why it is
legitimate, for instance when you want to force any latent caches in
memory to by skipped. When this happens Next.js will now skip cache
warming to ensure the render is streamed quickly. We will also warn in
the console that the request did not have caches warmed up and Component
Metadata in React DevTools won't accurately reflect which components are
cacheable and prefetchable.

In the future we will also show this state in the Next.js devtools UI so
it is clearer you are operating in this mode without having to read a
warning log in the console
2025-10-18 16:03:42 -07:00
Zack TannerandGitHub 85c3d20a91 [cache components]: move flag out of experimental (#85035)
This moves `experimental.cacheComponents` to a top level config. As part
of this, I disabled some tests in `build-output-prerender` that assert
on `cacheComponents` appearing in the experimental list. In a separate
PR, I'm going to show that Cache Components is enabled next to the
bundler info.

This also updates some docs pages to remove "experimental" language.
2025-10-18 14:13:44 -07:00
bc59f210b0 docs: Deprecation of Middleware (#84710)
This PR removes middleware docs and adds a "Migration to Proxy" section
to the Proxy docs, which explains the rationale for the renaming to
Proxy and provides a migration guide.

Did not remove `middleware-upgrade-docs` as it's an upgrade doc from the
legacy middleware.

Below are untouched as they need codebase changes:

- `instrumentation` docs - `onRequestError` has `context.routeType` as
`'middleware'`
- `adapterPath` docs - has `MiddlewareMatcher` type example
- `ProxyConfig` - has a user-facing `MiddlewareMatcher` type

---------

Co-authored-by: Joseph Chamochumbi <[email protected]>
2025-10-17 20:03:13 +02:00
Jiwon ChoiandGitHub 71ce95dffa docs: Replace Middleware docs to Proxy (#84709)
> [!NOTE]
> Best reviewed by each commit for better diff view.

This PR clones the Middleware docs for Proxy and removes the Middleware docs.

Did not clone the list of docs:

- `errors/middleware-upgrade.mdx` - It's a middleware upgrade guide from v12.2
- `errors/beta-middleware.mdx` - It's an error when using middleware before v12.2
- `errors/returning-response-body.mdx` - Legacy behavior from versions < v12.2
2025-10-17 16:13:26 +02:00
Josh StoryandGitHub 76d2beaeb8 [Cache Components] Remove unstable prefix from unstable_cacheTag (#84880)
`cacheLife` is now stable and does not require an unstable prefix
2025-10-16 07:01:44 -07:00
Josh StoryandGitHub 8cab15c0c9 [Cache Components] Remove unstable prefix from unstable_cacheLife (#84877)
`cacheLife` is now stable and does not require an unstable prefix
2025-10-15 08:14:04 -07:00
Wyatt JohnsonandGitHub 3630146458 Add validation for missing default.js in parallel routes (#84702)
### What?

Adds build-time validation to require explicit `default.js` files for
all parallel route slots (except the implicit "children" slot). This
validation is implemented in both Webpack and Turbopack bundlers.

### Why?

Parallel routes without `default.js` files currently cause silent 404
errors when users navigate to those routes. This creates confusion and
hard-to-debug issues because the routes appear to be configured
correctly but fail at runtime without any indication of what went wrong.

By making this validation explicit at build time, developers get
immediate feedback about missing required files with clear error
messages and documentation links, catching configuration mistakes before
deployment.

### How?

**Rust/Turbopack** (`crates/next-core/src/app_structure.rs`): Added
`MissingDefaultParallelRouteIssue` that emits a build error when a
parallel route slot is missing its `default.js` file. The validation is
skipped for the "children" slot since it's implicit and doesn't require
a default file.

**Webpack**
(`packages/next/src/build/webpack/loaders/next-app-loader/index.ts`):
Added validation that throws `MissingDefaultParallelRouteError` when
`default.js` cannot be resolved. The "children" slot falls back to the
existing `PARALLEL_ROUTE_DEFAULT_PATH` behavior for backward
compatibility.

**Error Class**
(`packages/next/src/shared/lib/errors/missing-default-parallel-route-error.ts`):
New error type with helpful messaging that includes the slot path,
explanation of the requirement, and a link to documentation.

**Migration Path**: Users who want the previous 404 behavior can
explicitly create a `default.js` that calls `notFound()`, or return
`null` for empty slots:

```tsx
import { notFound } from 'next/navigation'

export default function Default() {
  notFound()
}
```

Users can also run the following Deno script to generate the default
files for them:
https://gist.github.com/wyattjoh/ba7263ecb637ef399d3e3e4db63ffbd6

**Breaking Change**: This is a breaking change timed for Next.js 16
beta. Builds will now fail if parallel route slots are missing required
`default.js` files.
2025-10-09 15:20:52 -06:00
JJ KasperandGitHub e598a4f976 Add new updateTag API and new signature for revalidateTag (#83822) 2025-10-09 14:03:01 -07:00
StevenandGitHub 600238f0b6 breaking(next/image)!: remove 16px from default images.imageSizes config (#84647)
We took a look at unique Next.js projects that have one or more requests
for a specific image size and here are the findings as seen from the
Image Optimization API:

- `w=16` 4.2%
- `w=32` 17.1%
- `w=48` 21.4%
- `w=64` 22.6%
- `w=96` 25.8%
- `w=128` 29.5%
- `w=256` 46.5%
- `w=384` 35.1%
- `w=640` 57.2%

Only 4.2% of Next.js projects ever made a request to a 16px width image.
This is low enough to remove from the default configuration so that all
other projects can benefit from reduced html
[srcset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset)
and fewer variations exposed from the backend API.

You might think that this means few developers are using `<Image
width={16} />` but it probably means that most displays nowadays use
devicePixelRatio 2 meaning that specifying a 16px image width will
actually fetch the 32px width to ensure it won't looking blurry on your
retina display.

BREAKING CHANGE: this is technically a breaking change but it won't
cause apps to stop working, its just 4% of them may have some requests
serve a 32px image instead of 16px. Those apps can of course opt in by
changing their `images.imageSizes` config back to allowing 16.
2025-10-09 14:31:58 +02:00
Zack TannerandGitHub 5080edb7dc [docs] fix missing-data-scroll-behavior doc (#84651)
Fixes the code snippets for this doc.
2025-10-08 13:37:53 -07:00
Tobias KoppersandGitHub f90a780d3e Turbopack: rename turbopackPersistentCachingForXXX to turbopackFileSystemCacheForXXX (#84632)
### What?

Improve naming of the feature: `Turbopack FileSystem Cache`
2025-10-08 16:32:05 +02:00
4c4a5bc83f Implement the updated prerender API shape (#84254)
This does not add any validation but it makes the interface for
prerender match out intended API shape when validation is landed

---------

Co-authored-by: Janka Uryga <[email protected]>
2025-10-06 10:32:02 -07:00
c4e1f61baf docs: Verbose troubleshooting for unconfigured hosts (#84271)
Closes: https://linear.app/vercel/issue/DOC-5151/unconfigured-image-host

---------

Co-authored-by: Rich Haines <[email protected]>
2025-10-02 14:40:14 +02:00
Jiwon ChoiandGitHub 2318b5e2c0 docs: Remove AMP docs (#84357)
Stacked on https://github.com/vercel/next.js/pull/84312

Removes the AMP docs, which is no longer supported.
2025-09-30 15:21:52 +02:00
1dda5b668b [Breaking] Remove deprecated sync access to Dynamic APIs (#84179)
This PR removes the deprecated sync access to Dynamic APIs.

- Removed UnsafeUnwrapped* types.
- Replaced `as unknown as UnsafeUnwrapped ` type casts to `as any` for
dev warning.
- Removed tests that expected sync access to not error.
- Removed `UntrackedExotic` functions.
- Modified tests that were accidentally doing sync access.
- Updated warnings to emphasize that it is a Promise and must be
awaited.
- Removed paragraph that states access is allowed from
`errors/sync-dynamic-apis.mdx`.

---------

Co-authored-by: Josh Story <[email protected]>
2025-09-27 22:44:45 +02:00
StevenandGitHub 0f14e5333f BREAKING CHANGE!: bump default images.minimumCacheTTL from 1 min to 4 hours (#84105)
We have found many Next.js users are confused why images keep
revalidating so frequently (increasing cpu and cost).

The reason is usually that their upstream source images are missing the
`cache-control` header and thus fallback to the 60 second revalidation
default. This its not a great default since most images don't change
frequently.

This PR is a breaking change to bump the `images.minimumCacheTTL` config
from 60 (1 min) to 14400 (4 hours).

Why 4 hours? Because its long enough to take advantage of the durable
cache, but short enough that changing or deleting the upstream src image
will take effect on the same day.

For advanced use cases where images are changing frequently, developers
can change this behavior back by reducing `images.minimumCacheTTL` to a
lower value.
2025-09-23 10:49:34 -04:00
JosephandGitHub 84b0e94586 docs: Cookies store access is async (#83987)
Noted through a feedback channel.
2025-09-23 15:31:35 +02:00