## What?
Fixes a broken link in the Preserving UI State guide:
https://nextjs.org/docs/app/guides/preserving-ui-state#examples
The "Activity Patterns demo" link currently points to a non-working URL.
## Why?
The demo link returns a 404 / invalid page, which makes the example
section confusing for readers.
## Changes
- Updated the Activity Patterns demo link to the correct URL.
## Notes
No functional changes, docs only.
@icyJoseph @delbaoliveira
## What
Rename the HMR WebSocket path from `/_next/webpack-hmr` to `/_next/hmr`.
## Why
The `webpack-hmr` name is a leftover from when webpack was the only
bundler. Now that Turbopack is the default bundler for both `next dev`
and `next build`, the path name is misleading. The generic `/_next/hmr`
better reflects that this endpoint is bundler-agnostic.
## Changes
- **Client source** (`page-bootstrap.ts`, `web-socket.ts`): updated the
WebSocket connection path
- **Server** (`router-server.ts`): updated the HMR request detection
path
- **Turbopack** (`turbopack-dev-server/src/lib.rs`): updated the
fallback WebSocket path check
- **Tests**: updated all test files referencing the old path
- **Docs** (`version-12.mdx`): added a note that the path was renamed to
`/_next/hmr` in Next.js 16, while keeping the original v12 examples
intact
This removes the warn-only default behavior and enforces the dev-origin guard by default. Cross-origin requests to internal dev resources now block unless they match the built-in local allowlist or an explicit `allowedDevOrigins` entry. The tests are expanded to cover default blocking, configured-but-not-allowlisted hosts, missing Referer in the no-cors path, and same-site requests without an Origin, and the docs are updated to match the new behavior.
## Move `adapterPath` from experimental to stable
Graduates `adapterPath` from `experimental.adapterPath` to a top-level
`NextConfig` option, following the same pattern used for
`cacheHandlers`, `cacheComponents`, `typedRoutes`, and other options
that moved out of experimental.
### Changes
- **Type definition** (`config-shared.ts`): Added `adapterPath` to
`NextConfig` interface, marked `ExperimentalConfig.adapterPath` as
`@deprecated`, moved default value to top-level in `defaultConfig`,
updated `NextConfigRuntime` and `getNextConfigRuntime`
- **Zod schema** (`config-schema.ts`): Added `adapterPath` to top-level
`configSchema`
- **Backward compat** (`config.ts`): Added
`warnOptionHasBeenMovedOutOfExperimental` call so existing
`experimental.adapterPath` configs still work with a deprecation
warning, updated `applyModifyConfig` to read from `config.adapterPath`
- **Runtime references**: Updated `build/index.ts`, `app-page.ts`,
`app-route.ts`, `pages-handler.ts` to use `config.adapterPath` /
`nextConfig.adapterPath`
- **Tests**: Updated 4 test fixture `next.config` files
- **Docs**: Updated app router doc (removed `version: experimental`
frontmatter, top-level config example), pages router doc title, and v16
upgrade guide
saw the issue about the _document.tsx example not working. next/font
cant be used in _document.tsx, it throws an error. removed that section
from the docs since _app.tsx already has the correct example.
fixes#88832
Co-authored-by: Kahfi Elhady <kahfie@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
### What?
- Add canonical edge entrypoint metadata to edge function definitions in
the middleware manifest.
- Surface that canonical entrypoint through `build-complete` as
`edgeRuntime` metadata in adapter outputs.
- Update middleware and adapter tests to assert the new metadata instead
of relying on bundler-specific emitted file names.
### Why?
Adapter consumers need a stable way to load and invoke edge outputs
without depending on `next-server`'s sandbox handling or guessing which
emitted file is the executable entrypoint. The existing checks were also
brittle across webpack and Turbopack because the emitted file lists can
differ.
### How?
- Add an optional `entrypoint` field to `EdgeFunctionDefinition` and
populate it in both the webpack middleware manifest generator and the
Turbopack manifest emitters for app, pages, and middleware edge
functions.
- In `packages/next/src/build/adapter/build-complete.ts`, use that
canonical entrypoint for `filePath` and expose `edgeRuntime.modulePath`,
`edgeRuntime.entryKey`, and `edgeRuntime.handlerExport` for edge
outputs.
- Adjust the middleware manifest tests to validate cross-bundler
invariants and add adapter-config coverage for the new `edgeRuntime`
fields.
### What?
This PR extends `@next/routing` so `resolveRoutes()` returns the
concrete route resolution data callers need after rewrites and dynamic
matches:
- rename `matchedPathname` to `resolvedPathname`
- add `resolvedQuery`
- add `invocationTarget` for the concrete pathname/query that should be
invoked
- export the new query/invocation target types from the package
entrypoint
It also removes the leftover `query` alias so the result shape
consistently uses `resolvedQuery`.
### Why?
`matchedPathname` only described part of the result, and it was
ambiguous for dynamic routes because the resolved route template and the
concrete invocation target are not always the same thing.
For example, a dynamic route can resolve to `/blog/[slug]` while the
actual invocation target is `/blog/post-1`, and rewrites can merge query
params that callers need to preserve. Exposing these values directly
makes the package easier to consume from adapters without each caller
reconstructing them manually.
### How?
- thread resolved query construction through the route resolution paths
- build `invocationTarget` alongside `resolvedPathname` wherever
rewrites, static matches, and dynamic matches resolve successfully
- preserve merged rewrite query params in `resolvedQuery`
- update the public types, README example, and existing tests to use
`resolvedPathname`
- add coverage for resolved query + invocation target behavior on
rewrite and dynamic route matches
Verified with:
- `pnpm --filter @next/routing test -- --runInBand`
- `pnpm --filter @next/routing build`
### What?
This PR exposes adapter-facing router helpers on `requestMeta` for
Node.js entrypoints and updates route modules to merge those
request-scoped values with the existing router server context fallback.
It also documents the new adapter contract in the `adapterPath` docs.
### Why?
When adapters invoke the Node.js handler directly, some router helpers
are needed by route handlers but currently only exist behind internal
globals. Passing them through `requestMeta` makes those helpers
available through the public handler options and still preserves the
existing fallback context for the current `relativeProjectDir`.
### How?
- add typed `requestMeta` fields for `hostname`, `revalidate`, and
`render404`
- add a `RouteModule` helper that reads the existing router server
context and overlays request-scoped values from `requestMeta`
- switch the route-module callsites that read router server context to
use the merged result
- document how adapters can pass these helpers when calling
`handler(req, res, { requestMeta })`
## Summary
- preserve Flight/RSC headers on the Proxy request instance when URL
normalization is skipped (`skipProxyUrlNormalize`)
- preserve the `_rsc` query on the request URL in that same mode so
custom proxy logic can access it
- document this behavior in the Proxy API docs, including guidance for
`NextResponse.rewrite()` vs custom `fetch` rewrites
- add an e2e regression in `skip-trailing-slash-redirect` to verify
middleware receives `_rsc` and all RSC headers on the request instance
## Testing
- `NEXT_SKIP_ISOLATE=1 NEXT_TEST_MODE=dev pnpm testheadless
test/e2e/skip-trailing-slash-redirect/index.test.ts`
### What?
Adds a new `experimental.lightningCssFeatures` config option that lets
users control which CSS features lightningcss should always transpile
(`include`) or never transpile (`exclude`), regardless of browserslist
targets.
```js
// next.config.js
module.exports = {
experimental: {
useLightningcss: true,
lightningCssFeatures: {
include: ['light-dark', 'oklab-colors'],
exclude: ['nesting'],
},
},
}
```
### Why?
Currently, lightningcss feature transpilation is determined solely by
browserslist targets. There's no way to force transpilation of a
specific feature (e.g., `light-dark()`) when targeting modern browsers
that already support it, or to skip transpilation of a feature that the
user wants to preserve as-is.
This is useful for:
- Forcing polyfill-style transpilation for features with incomplete
browser support
- Testing transpiled output for specific features
- Opting out of specific transforms that may interfere with CSS tooling
downstream
### How?
**TypeScript config & validation:**
- `config-shared.ts`: `LIGHTNINGCSS_FEATURE_NAMES` const array (single
source of truth) with `LightningCssFeature` type derived from it, and
`LightningCssFeatures` interface
- `config-schema.ts`: Zod validation using
`z.enum(LIGHTNINGCSS_FEATURE_NAMES)` for both include/exclude arrays
**Feature name → bitmask mapping (Rust, shared via NAPI):**
- `crates/next-core/src/next_config.rs`:
`lightningcss_feature_names_to_mask()` maps feature name strings to
`lightningcss::targets::Features` bitflag constants and returns a
`Result<u32>` bitmask. Unknown feature names produce an error via
`bail!`.
- Exposed to JS via NAPI as `lightningcssFeatureNamesToMaskNapi`,
callable through `bindings.css.lightning.featureNamesToMask(names)`
- Single source of truth for feature name resolution — both webpack and
Turbopack paths use this Rust function
**Webpack path:**
- `global.ts` / `modules.ts` pass config through to loader options
- `loader.ts` calls `featureNamesToMask()` via the native bindings to
compute include/exclude masks, then passes them to the SWC `transform()`
call
- The `lightningCssFeatures` without `useLightningcss` warning only
shows when using webpack (Turbopack always uses lightningcss)
**Turbopack path (Rust):**
- `next_config.rs`: `LightningCssFeatures` struct for deserialization,
accessor methods converting names → u32 bitmask via
`lightningcss_feature_names_to_mask()`
- Config flows through `CssOptionsContext` → `ModuleType::Css` →
`CssModuleAsset` (using `LightningCssFeatureFlags { include, exclude }`
struct) → `process.rs` where bitmasks are merged into
`lightningcss::targets::Targets { include, exclude }`
- Uses `u32` bitmask representation throughout to avoid adding
lightningcss dependency to non-CSS crates
**Defaults preserved:** `Nesting | MediaRangeSyntax` for Turbopack,
`Nesting` for Webpack. User `include` is OR-ed on top, user `exclude`
masks bits off.
**Feature names:** 21 individual features (bit 0–20) + 3 composite
groups (`selectors`, `media-queries`, `colors`), all in dash-case.
### Test
- **Include test**
(`test/e2e/app-dir/experimental-lightningcss-features/`) — targets
Chrome 123 (which natively supports `light-dark()`) with `include:
['light-dark']`, then asserts the CSS output contains lightningcss
transpilation markers (`--lightningcss-light`, `--lightningcss-dark`)
instead of raw `light-dark()`.
- **Exclude test**
(`test/e2e/app-dir/experimental-lightningcss-features-exclude/`) —
targets Chrome 100 (which does NOT support `light-dark()` natively) with
`exclude: ['light-dark']`, then asserts the CSS output preserves raw
`light-dark()` calls and does not contain transpilation markers.
- [x] update links to demo
- [x] minor polishing identified by AI
- [x] update links (dep: docs-unify-caching-story)
- [x] check the implementation details vs actionable info balance
- [x] how (and when) to block streaming?
https://github.com/vercel/next.js/pull/90450
- [x] INP and the hydrate me later trick link to demo
---------
Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
Some users have been confused by the relationship of
`images.remotePatterns` and `images.maximumRedirects` so lets document
it.
This behavior is expected since you might allowlist something like
`https://github.com/styfle.png` and that can redirect to whatever it
needs to redirect to (assuming maximumRedirects > 0). For example, it
currently redirects to
`https://avatars.githubusercontent.com/u/229881?v=4` but you can imagine
in the future if the redirect was changed, you wouldn't want your app to
break.
Regardless of redirects, the final response must be an image.
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
## Summary
- document how to use custom deploy, logs, and cleanup scripts with the
deploy test workflow
- describe the expected stdout/log marker contract for custom scripts
- keep the examples generic to adapter implementations
---------
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
### What?
Updated all proxy code examples in the API reference to use the
`NextProxy` typed arrow function pattern, consistent with the convention
used in `src/proxy.ts`.
### Why?
The proxy function is typed as `NextProxy` so parameters are inferred
from the type, removing the need for explicit `NextRequest` imports.
### How?
Updated all proxy code examples in the API reference to use the
`NextProxy` typed arrow function pattern, consistent with the convention
used in `src/proxy.ts`.
---------
Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
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 <joseph.chamochumbi@vercel.com>
While reviewing the [JSON-LD
documentation](https://nextjs.org/docs/app/guides/json-ld ), I noticed
that seeing `<script>` instead of `<Script>` can easily feel like a typo
> Our current recommendation for JSON-LD is to render structured data as
a <script> tag in your layout.js or page.js components.
This PR adds a short clarification explaining why the native `<script>`
tag is intentionally recommended for JSON-LD. The goal is to reduce
confusion and make the guidance clearer for developers reading the docs.
@icyJoseph
---------
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
## For Contributors
### Improving Documentation
- [x] Run `pnpm prettier-fix` to fix formatting issues before opening
the PR.
- [x] Read the Docs Contribution Guide to ensure your contribution
follows the docs guidelines:
https://nextjs.org/docs/community/contribution-guide
### What?
Fix two bugs in the `useReportWebVitals` API reference docs:
1. `navigationType` value `"back_forward"` → `"back-forward"`: the
`web-vitals`
library intentionally renames this value to use a hyphen for
consistency.
2. Variable name mismatch in `handleCustomMetrics` example: parameter
was named
`metrics` (plural) but the function body referenced `metric.name`
(singular),
causing a `ReferenceError`.
### Why?
The `navigationType` description reflected the raw
`PerformanceNavigationTiming`
API value (`"back_forward"`), not the actual value emitted by the
`web-vitals`
library (`"back-forward"`), which `useReportWebVitals` is built on top
of
Ref: https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#types
The variable name mismatch in the code example would cause a
`ReferenceError`
if copied as-is.
### How?
- Updated `navigationType` description to use `"back-forward"`.
- Renamed parameter `metrics` → `metric` in the `handleCustomMetrics`
example
---------
Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
This proposal adds Hostinger Web Apps Hosting as one additional
deployment option in existing deployment documentation.
- Keeps language provider-neutral
- No runtime or code behavior changes
- Keeps current structure and recommendations intact
Link used: https://github.com/hostinger/deploy-nextjs
---------
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
As we discussed, let's scale back how much Activity we teach and focus
on UI preservation, choice of pattern, and wrap it all with a demo where
these are implemented.
- [x] rename file
---------
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
### What?
Updates the
[Deploying](https://nextjs.org/docs/app/getting-started/deploying) page
Docker section to document the new and updated Docker examples and add
description to old ones.
### Why?
The Docker examples were added/updated in
[#87069](https://github.com/vercel/next.js/pull/87069). The Deploying
page still only listed the generic "Docker" and "Docker
Multi-Environment" templates, so the new **Docker Standalone** and
**Docker Export** examples were not discoverable from the docs.
### How?
- Add **Docker Standalone** template linking to `examples/with-docker`
(`output: "standalone"` for minimal container images).
- Add **Docker Export** template linking to
`examples/with-docker-export-output` (`output: "export"` for static HTML
in a container).
- Order templates as: Docker Standalone, Docker Export, then Docker
Multi-Environment.
---
**Related:** This PR follows up on the merged [PR
#87069](https://github.com/vercel/next.js/pull/87069) (Docker examples
for standalone and export output). It updates the docs so the Deploying
page links to those examples.
---------
Co-authored-by: Wyatt Johnson <accounts+github@wyattjoh.ca>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
Co-authored-by: kristiyan.velkov <kristiyan.velkov@ffw.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
### What?
Small improvements to the Forms guide for consistency and clarity.
### Why?
Some examples didn’t fully match the recommendations in the guide (e.g.
HTML validation), and there was a minor inconsistency between
`event.target` and `event.currentTarget`. This update keeps the examples
aligned and easier to follow.
### How?
- Added `required` to relevant input examples
- Standardized usage of `event.currentTarget`
- Made minor wording refinements for clarity
---------
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
There have been multiple discussions and some confusion around [React
version handling](https://nextjs.org/docs#react-version-handling) in
Next.js. This PR adds an in-depth explanation to clarify how React and
react-dom versions are managed internally, and why they still need to be
declared in package.json.
The goal is to help developers better understand this behavior and
reduce recurring questions around it.
Reference discussion:
https://github.com/vercel/next.js/discussions/87958
@icyJoseph
---------
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
This PR adds an LRU disk cache so that reads and writes from the Image
Optimization API will evict old entries based on the value of
`images.maximumDiskCacheSize` configuration.
The LRU ensures that cache reads bump the entry to the top so that they
don't get evicted - only the least recently used entries get evicted.
When `next start` is run, if there is an existing disk cache the we will
replay the files in order to populate the LRU and respect
`images.maximumDiskCacheSize` if it was changed.
If no configuration is provided, default to 50% available disk space.
Adds a guide for configuring AI coding agents to use the version-matched
documentation bundled in `node_modules/next/dist/docs/` (shipped via the
`copy_docs` build task in #89850) instead of stale training data.
The guide covers how the bundled docs work, the `AGENTS.md` and
`CLAUDE.md` files generated by `create-next-app --agents-md`, and how to
add project-specific instructions outside the `<!--
BEGIN:nextjs-agent-rules -->` markers.
Explicitly document that Next.js waits for an async instrumentation
register function to complete before handling incoming requests, and
align wording between the guide and API reference.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
The second and third bullet points in the 'Good to know' callout were
incorrectly placed outside the blockquote, breaking the visual grouping
on the rendered documentation page.
<!-- 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: Andrew Damelio <andrewdamelio@users.noreply.github.com>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
## What?
Adds support for inline loader configuration in Turbopack via import attributes. Developers can apply webpack-compatible loaders to individual imports using the `with` clause, without needing global `turbopack.rules` configuration.
```tsx
import rawText from '../data.txt' with { turbopackLoader: 'raw-loader', turbopackAs: '*.js' }
import value from '../data.js' with {
turbopackLoader: 'string-replace-loader',
turbopackLoaderOptions: '{"search":"PLACEHOLDER","replace":"replaced value"}'
}
```
## Why?
Global `turbopack.rules` applies loaders to all files matching a pattern. This PR provides per-import granularity — useful when only a specific import needs special treatment, avoiding side effects on other imports of the same file type.
## How?
### Import attributes parsing (`turbopack-ecmascript/src/analyzer/imports.rs`)
- Extended `ImportAnnotations` to parse four new attributes: `turbopackLoader`, `turbopackLoaderOptions`, `turbopackAs`, `turbopackModuleType`
- All values are strings per TC39 import attributes spec (`turbopackLoaderOptions` is a JSON-encoded string)
- Added unit tests for the parser
### New structured loader type (`turbopack-core/src/loader.rs`)
- Added `WebpackLoaderItem` struct shared between inline and global loader paths
### Reference type plumbing (`turbopack-core/src/reference_type.rs`, `turbopack-ecmascript/src/references/esm/base.rs`)
- Added `ImportWithTurbopackUse` variant to `EcmaScriptModulesReferenceSubType` carrying the parsed loader, rename_as, and module_type
- ESM reference resolution maps the parsed annotations to this new subtype
### Loader execution (`turbopack/src/lib.rs`)
- In `process_default_internal`, detects `ImportWithTurbopackUse` references and applies the loader as a source transform via the existing webpack loader infrastructure
- Requires `enable_webpack_loaders` to be configured (same as global rules)
- Supports `turbopackAs` (re-processes with new extension) and `turbopackModuleType` (directly sets module type)
- Avoids infinite recursion by switching to plain `Import` reference type on re-processing
### Documentation (`docs/.../turbopack.mdx`)
- Added section documenting the four import attributes with examples
- Added version history entry for v16.2.0
### Testing (`test/development/app-dir/turbopack-import-assertions-use/`)
- E2e test covering raw loader, replace loader with options, `turbopackModuleType: 'ecmascript'`, and `turbopackModuleType: 'json'`
- Turbopack-only (skipped for webpack)
## What?
Moves the `turbopackIgnoreIssue` config from `experimental` to the stable `turbopack` config as `turbopack.ignoreIssue`.
## Why?
Reviewers on #89682 agreed the API is stable enough to graduate from experimental. Also addresses a docs wording suggestion.
## How?
- **TypeScript types**: Moved `ignoreIssue` field from `ExperimentalConfig` to `TurbopackOptions` in `config-shared.ts`
- **Zod schema**: Moved validation from `experimentalSchema` to `zTurbopackConfig` in `config-schema.ts`
- **Serialization**: Moved RegExp serialization logic into the turbopack block in `build/swc/index.ts`
- **Rust**: Moved `ignore_issue` field from `ExperimentalConfig` to `TurbopackConfig` in `next_config.rs`, updated the `turbopack_ignore_issue_rules()` method to read from `self.turbopack`
- **Tests**: Updated config in test to use `turbopack.ignoreIssue` instead of `experimental.turbopackIgnoreIssue`
- **Docs**: Removed `version: experimental`, updated all code examples, moved entry from experimental table to stable config list in turbopack.mdx, fixed "Good to know" wording to say "prefer using more specific `path` patterns" (since `path` is already required)
## Summary
- Add note that omitting `expire` in `cacheLife` results in cache never
expiring
- Fix `default` preset table: `expire` was documented as "1 year" but
actual code uses `INFINITE_CACHE` (never)
- Add mention of expire omission behavior in custom profiles section
## Why
The `expire` property is optional (`expire?: number`), but the
documentation didn't explain
what happens when it's omitted. The source code shows it defaults to
`INFINITE_CACHE` (0xfffffffe),
meaning the cache never expires. Additionally, the preset profile table
incorrectly listed
the `default` profile's expire as "1 year" when the actual value is
`INFINITE_CACHE`.
### Source code references
- `packages/next/src/lib/constants.ts:45` — `INFINITE_CACHE =
0xfffffffe`
- `packages/next/src/server/config-shared.ts:1580` — `default.expire:
INFINITE_CACHE`
- `packages/next/src/server/use-cache/cache-life.ts:156` — only sets
`explicitExpire` when `expire !== undefined`
- `packages/next/src/server/use-cache/use-cache-wrapper.ts:477-479` —
falls back to `defaultCacheLife.expire` (INFINITE_CACHE)
---------
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>