Completing the input-output pair for cached functions.
This is addressing user confusion around what happens to a cached
function, and functions within the scope.
The implementation of `unstable_eager` is currently incomplete, causes
bugs in the main Partial Prefetching flow (see #97469), and is generally
not worth the complexity it adds, so we're removing it. We may add
something like this back later if we think it's useful.
Importantly, removing it fixes a bug that caused apps that use
incremental opt-in (i.e. no global `partialPrefetching` config and
`export const prefetch = 'partial'`) to issue speculative prefetches for
all links without `prefetch={true}`, because any segment without an
explicit `prefetch = "partial"` was marked as needing eager prefetching,
which was then propagated to the whole route. See #97469 for a full
explanation.
This fix causes a lot of changes in tests, which were previously
incorrectly asserting that we should be seeing two requests. Now that
the unnecesary speculative prefetch is gone, most of them only see one.
### Why?
generateMetadata can be marked with use cache, but Cache Function return
values must be serializable. The metadataBase examples use URL objects,
so the interaction needs co-located guidance for cached metadata.
### How?
Add a Good to know note that recommends returning metadataBase as a
string, such as with url.toString(), and links to the use cache
serialization requirements. Runtime behavior is unchanged.
<!-- NEXT_JS_LLM -->
---------
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
## What?
Updates the Interactive Apps guide to show how an optimistic mutation
handles an expected server error.
## Why?
The optimistic card move automatically returns to the confirmed data
when the write fails, but the guide did not show how to explain that
failure to the user. A success toast would duplicate the visible card
movement, so the example only adds feedback for the error case.
## How?
- Return a structured error result when the task no longer exists.
- Display that expected error in a toast while `useOptimistic` reverts
the card.
- Forward unexpected thrown errors to the nearest error boundary.
LCP can be affected if the LCP element is sitting within a Suspense
boundary, even if its nothing but static content, if the static content
is "too large".
Apps should prefer, as long as possible, to not have a Suspense boundary
around the LCP element.
-
https://react.dev/reference/react/Suspense#what-activates-a-suspense-boundary
> Waiting for a large boundary’s HTML to arrive during streaming server
rendering. Sending HTML takes time, so a boundary with enough content
activates even when nothing in it suspends. React reveals the content as
the HTML arrives.
### What?
Documents the `pagination` metadata field in the `generateMetadata` API
reference.
### Why?
The `Metadata` type supports `pagination.previous` and
`pagination.next`, but the Metadata Fields documentation did not list
the field.
Fixes#83264
### How?
Adds a `pagination` section with an example and the generated `<link
rel="prev">` / `<link rel="next">` output.
### Tests
- `pnpm prettier --check
docs/01-app/03-api-reference/04-functions/generate-metadata.mdx`
- `pnpm lint-eslint
docs/01-app/03-api-reference/04-functions/generate-metadata.mdx`
- `git diff --check HEAD~1..HEAD`
<!-- NEXT_JS_LLM_PR -->
## What
Vercel's **Edge Config** product is now **Global Config**. This updates
the two stale-name occurrences flagged in the redirecting guide.
The URL was already migrated in #96723 (`/docs/edge-config/get-started`
→ `/docs/global-config/get-started`), but that pass only rewrote link
targets — the visible product name and the SDK import in the code
samples still said `Edge Config` / `@vercel/edge-config`, so the page
read *"Vercel's Edge Config"* while linking to the Global Config docs.
## Changes
`docs/01-app/02-guides/redirecting.mdx`, in *Managing redirects at scale
→ Creating and storing a redirect map*:
| | Before | After |
| --- | --- | --- |
| Prose | Vercel's [Edge Config] | Vercel's [Global Config] |
| `proxy.ts` / `proxy.js` samples | `import { get } from
'@vercel/edge-config'` | `import { get } from '@vercel/global-config'` |
The link target, the neighbouring [Redis](https://vercel.com/docs/redis)
link, and the surrounding sentence structure are unchanged.
## Why the package import changed too
The renamed package is published and is the same library —
`@vercel/global-config@1.5.1`, from `vercel/storage` at
`packages/global-config`, matching `@vercel/edge-config@1.5.1` — and it
exports the same `get`. Vercel's own [Global Config
quickstart](https://vercel.com/docs/global-config/get-started) now uses
`import { get } from '@vercel/global-config'`. Leaving the old specifier
would have left the sample importing a legacy package name on a page
that calls the product Global Config. `@vercel/edge-config` is not yet
formally deprecated on npm, so this is a naming-consistency change
rather than a fix for broken code.
## Both flagged pages
Two docs paths were flagged — `/docs/app/guides/redirecting` and
`/docs/pages/guides/redirecting` — but they share one source.
`docs/02-pages/02-guides/redirecting.mdx` is a generated stub (`source:
app/guides/redirecting`, carrying the *DO NOT EDIT* banner), and the
affected paragraph is not wrapped in `<AppOnly>`/`<PagesOnly>`, so it
renders on both. Editing the App Router source fixes both pages; no
separate edit to the Pages file is needed or allowed.
## Verification
- `grep -rn "Edge Config\|edge-config" docs/` → no matches remain.
- `prettier --check` and `alex` pass on both files; the pre-commit
`lint-staged` (prettier + eslint) pass ran clean.
- `https://vercel.com/docs/global-config/get-started` → `200`; the old
`/docs/edge-config/get-started` → `308`, confirming the link already
points at the final target.
Docs-only change; no code or tests affected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Rich Haines <22930449+molebox@users.noreply.github.com>
### What?
Fix grammar issues in the "Linking and Navigating" guide.
### Why?
This sentence had a few grammar issues:
- "makes" should be "make"
- "a server-rendered apps" should be "server-rendered apps"
- "it enables" should be "they enable"
### How?
Updated the sentence in
`docs/01-app/01-getting-started/04-linking-and-navigating.mdx` to
correct grammar and improve subject-verb agreement.
---------
Co-authored-by: Marcos Hernanz <96699542+marcoshernanz@users.noreply.github.com>
## Summary
Document that `permanentRedirect()` throws and should be called outside
a broad `try/catch` block.
The `redirect()` and `notFound()` references already explain this
control-flow requirement. The `permanentRedirect()` reference omits it,
so application error handling can accidentally suppress the redirect.
Align the page with the `redirect()` reference by adding a dedicated
Behavior section for the try/catch guidance and temporary-redirect
cross-link.
## Verification
- Prettier, ESLint, and `git diff --check`
The forms guides recommend validating with a library like Zod. This
broadens the wording to also mention Valibot, which covers the same use
case with a smaller bundle footprint. The authentication guide already
lists Zod or Yup, so Valibot is added to that list as well. The existing
Zod examples are unchanged. I'm the author of Valibot.
- Ran `prettier --check` on the touched files with the repo's pinned
version.
- Adding
docs/01-app/03-api-reference/05-config/01-next-config-js/cacheMaxMemorySize.mdx
- Various use cache snippet fixes
- Break nuance for fetch default
- Point to correct turbopack cache flags
The `use-cache-private` suite covered private caches in server
components only, so this adds a route handler that calls one `'use
cache: private'` function three times: a concurrent pair, and a third
call after a short delay. The concurrent pair joins a single in-flight
invocation, while the delayed call lands after the map of pending
intra-request invocations has dropped its entry, so it is served from
the completed entry that the request retains. Each call passes a fresh
object literal, which makes the React `cache()` memo miss on reference
equality so that the lookup falls through to the serialized cache key.
The cache function also reads a cookie, which covers that request APIs
are allowed inside a private cache in a route handler.
A second test asserts that nothing is shared across requests. In
production private entries are neither persisted nor deduped across
requests, so every request re-runs the cache function. In development
they are persisted and forced to `revalidate: 0`, so the next request is
served the stale entry while a fresh one warms in the background, which
the dev branch of the test follows. Both tests pass their own `id`
search param, and therefore use their own cache key, so the entry that
dev persists for one is never served to the other.
This also drops the claim that the directive is not available in route
handlers from the `'use cache: private'` reference. Nothing in the
source rejects it, and it was already allowed for request work unit
stores when that note was written.
### What?
Updates the light and dark image references in the authentication guide
to use `authentication-overview-new.png`.
### Why?
The previous diagrams still showed `useFormState()` even though the
documentation has migrated to `useActionState()`.
Fixes#75709
### How?
Points both themed diagram references at the corrected replacement
assets.
Validation:
- Confirmed both replacement URLs return `200 image/png`
- `git diff --check`
- Enrich the directives entry point
- New guide for Server and Client components. Conceptual backing for the
getting started page.
---------
Co-authored-by: Aurora Scharff <aurora.sofie@gmail.com>
## Summary
- add an explicit `staleTime` to the server-seeded TanStack Query
example so hydration does not immediately refetch
- explain when stale TanStack Query data becomes eligible to refetch
- clarify that SWR fallback data revalidates after hydration by default
and that `revalidateIfStale: false` is not a timed freshness window
## Verification
- `prettier --write
docs/01-app/02-guides/client-side-data-fetching/{swr,tanstack-query}.mdx`
- `alex
docs/01-app/02-guides/client-side-data-fetching/{swr,tanstack-query}.mdx
--quiet`
- Not run: full `pnpm lint` (docs-only change; targeted formatting and
language checks passed)
<!-- NEXT_JS_LLM -->
## What changed
- Expands the SPA data-fetching guidance with focused SWR and TanStack
Query guides.
- Covers client-only fetching, optional Server Component seeding, shared
cache identities, and optimistic mutations.
- Explains how the Next.js server and client caches relate to
library-owned browser caches, including SWR `preload` and TanStack Query
hydration with Cache Components.
- Aligns the examples with `next-spa-patterns` and the team chat demo.
## Validation
- Prettier and diff checks pass for the updated guides.
- `next-spa-patterns` passes TypeScript checks.
### What?
Adds support for passing a module type to the TypeScript overloads for
`import.meta.glob`:
```ts
const entries = import.meta.glob<Entry>("./entries/*.ts");
```
This works with both lazy and eager imports. If a module type isn’t
provided, it defaults to `unknown`, which matches the current behavior.
### Why?
Next.js already supports Vite’s `import.meta.glob` API at runtime, but
its TypeScript declarations don’t support [Vite’s module
generic](https://github.com/vitejs/vite/blob/57fea001d154e7dd8d5d74d3082731f1dcfd31be/packages/vite/types/importGlob.d.ts#L113-L130).
Because of this, a typed glob works in Vite but fails in Next.js:
```text
TS2558: Expected 0 type arguments, but got 1.
```
Consumers currently have to cast the result or add their own
`ImportMeta` declaration to describe the matched modules. Supporting the
generic removes the need for those workarounds and makes typed glob
imports consistent between Next.js and Vite.
### How?
Each existing overload now accepts a generic module type, `M`, which
defaults to `unknown`:
- Lazy imports return `Record<string, () => Promise<M>>`.
- Eager imports return `Record<string, M>`.
Using `unknown` as the default means existing calls without a generic
keep the same types as before.
I also updated the existing e2e fixture. It had an old local
`ImportMeta.glob` declaration that returned `Record<string, any>`.
Removing that declaration exposed the missing generic and allowed the
five `as any` casts in the fixture to be removed. Without the generic,
all five glob calls fail during `next build` with `TS2558`. With it, all
five pass.
The Turbopack documentation has also been updated with examples showing
how to use the generic with lazy and eager imports.
### Checklist
- [x] `pnpm --filter=next types` passes
- [x] `pnpm prettier-fix` run
- [x] Documentation follows the docs contribution guide
- [x] E2E test passes
---------
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
## Summary
Rename the guide to `How to implement authentication with Cache
Components` so it follows the wording of the main authentication guide
while keeping the Cache Components context.
## Verification
- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--write docs/01-app/02-guides/authentication-with-cache-components.mdx`
- Not run: full test suite (frontmatter-only documentation change)
<!-- NEXT_JS_LLM -->
## Summary
- Fix wording in Link prefetch docs: `navigation's` -> `navigation`
- Fix wording in CRA migration guide: `clients components` -> `Client
Components`
## Why
These are user-facing documentation wording issues. This change improves
clarity and readability for readers following these guides.
## Scope
Docs-only changes. No runtime behavior changes.
Attribution: This change was originally authored by @Rezakarimzadeh98 in
#96998.
Co-authored-by: Reza Karimzadeh <r.karimzadeh1998@gmail.com>
The MDX guide’s “Handling `.md` files” section referenced `next/mdx`,
but the package used throughout the guide is `@next/mdx`.
This updates the text to match the correct package name to avoid
confusion for readers configuring `.md` support.
Attribution: This change was originally authored by @pavan-sh in #89710.
Co-authored-by: Pavan Shinde <pavann97@gmail.com>
Use "an" instead of "a" before words starting with a vowel sound
<!-- 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: Tim Neutkens <tim@timneutkens.nl>
With the latest GA changes, when using Cache Components with Partial
Prefetching:
> prefetch={true} turns on prefetching
These changes try to align around that idea.
- runtime prefetching guide is now about optimizing
- various changes in prose across docs
- even fix an error page for pages router, which had a broad title
---------
Co-authored-by: Aurora Scharff <aurora.sofie@gmail.com>
What?
When a static export is enabled, route handlers require export const
dynamic = 'force-static'. However, this instruction is missing in the
documentation.
Why?
Without export const dynamic = 'force-static', next dev and next build
fail when a static export is enabled.
How?
This PR adds the instruction to correct the usage of Route Handlers on
static exports.
Closes https://github.com/vercel/next.js/issues/96574.
Implements:
> experimental.turbopackMinify accepts per-environment granularity, e.g.
{ server: false, client: true } (restoring serverMinification parity)
I also added the edge runtime in there, even though it isn't too widely
used.
## What
Updates the [Designing view
transitions](/docs/app/guides/view-transitions) guide so the
`vercel-react-view-transitions` skill points to its **skills.sh** page
instead of the GitHub source, and reframes the sample prompt as an
example.
## Changes
- Link the skill to
`https://skills.sh/vercel-labs/agent-skills/vercel-react-view-transitions`
instead of the `github.com/vercel-labs/agent-skills/...` source tree.
- Use the skills.sh install form (`npx skills add
vercel-labs/agent-skills --skill ...`), consistent with the other skills
referenced in the docs.
- Frame the prompt as "a prompt like this" and add a sentence making
clear the example is not required, readers can prompt for whatever they
want to achieve and the skill guides the agent through the relevant
patterns.
## Why
The skills.sh page is the canonical place to view and install the skill.
The old wording read as if the one prompt was the only way to invoke the
skill.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
- new guide, Auth w/ Cache Components
- iron-session example w/ Cache Components
TODO:
- [x] opt-out from the instant requirements
- [x] e2e for the example, using instant helper
---------
Co-authored-by: Aurora Scharff <66901228+aurorascharff@users.noreply.github.com>
Co-authored-by: Aurora Scharff <aurora.sofie@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
`TurbopackModuleType` has listed `'text'` for a while, but the config
schema
and `ConfiguredModuleType::parse` both rejected it. It now maps to the
existing
`TextSourceTransform` (the same thing `import … with { type: 'text' }`
uses).
`'json'`, which Rust already accepted, is added to the TypeScript type
and
schema too.
`type: 'raw'` has always been documented as "Return raw contents as
string",
but it mapped to an opaque module with no exports instead — that
mismatch is
why `import * as ns from './alpha.md'` with `{ '*.md': { type: 'raw' }
}`
evaluated to `undefined`. `raw` is now an alias of `text`: both run the
file
through `TextSourceTransform` and export its contents as a string.
Neither
name is deprecated; `text` remains the descriptive spelling that matches
the
`import … with { type: 'text' }` import attribute, `raw` keeps working
exactly
as documented. No configuration value maps to the opaque module type
anymore;
`type: 'asset'` remains the way to emit a file and get its URL.
This is also what makes Vite's `?raw` workable: Turbopack has no
built-in
`?raw` handling, so a `{ condition: { query: '?raw' }, type: 'text' }`
(or
`'raw'`) rule is what turns those files into strings. Docs previously
implied
`?raw`/`?url` worked standalone; that's corrected, and the module type
table
is completed and describes `raw`/`text` as equivalent.
Reading a binding off a module that genuinely can't be placed in an
ECMAScript chunk (a stylesheet, a native addon, …) used to evaluate to
`undefined` with no diagnostic; it now reports an error naming the
module.
Side-effect-only imports still work.
<!-- NEXT_JS_LLM -->
---------
Co-authored-by: vercel-fleet[bot] <308483924+vercel-fleet[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
## What
Updates docs links whose targets have moved. Found by an automated docs
link audit: every old URL below currently serves a `308` (permanent
redirect), so readers take an extra hop and the links rot as redirect
maps are pruned.
Each replacement is the **final `200` URL** of the redirect chain
(verified with `curl -sIL`), not just the first hop. Only the path
component was rewritten — scheme, host, query strings
(`?utm_source=...`) and fragments are untouched.
| Old path | Now points at |
| --- | --- |
|
`vercel.com/docs/concepts/functions/edge-functions/og-image-generation`
| `/docs/og-image-generation` |
| `vercel.com/docs/frameworks/nextjs` |
`/docs/frameworks/full-stack/nextjs` |
| `vercel.com/docs/observability/otel-overview` |
`/docs/tracing/instrumentation` |
| `vercel.com/docs/concepts/observability/otel-overview/quickstart` |
`/docs/tracing/instrumentation` |
| `vercel.com/docs/edge-config/get-started` |
`/docs/global-config/get-started` |
| `vercel.com/docs/functions/vercel-functions-package` |
`/docs/functions/functions-api-reference/vercel-functions-package` |
| `vercel.com/docs/edge-network/overview` | `/docs/cdn` |
| `vercel.com/docs/storage/vercel-blob` (×4) | `/docs/vercel-blob` |
| `vercel.com/docs/storage/vercel-blob/server-upload` |
`/docs/vercel-blob/server-upload` |
| `vercel.com/docs/storage/vercel-blob/client-upload` |
`/docs/vercel-blob/client-upload` |
| `vercel.com/docs/concepts/image-optimization` |
`/docs/image-optimization` |
| `nextjs.org/docs/app/building-your-application/rendering` |
`/docs/app/getting-started/caching` |
The four Pages Router pages flagged by the audit (`deploying`,
`guides/instrumentation`, `guides/open-telemetry`, `guides/redirecting`)
share their source with the App Router versions via frontmatter
`source:`, so fixing the App Router files covers them.
## One link worth a reviewer's eye
In `use-client.mdx`, the client-server **boundary** link pointed at
`/docs/app/building-your-application/rendering#network-boundary`. That
path 308s to `/docs/app/getting-started/caching`, which is what this PR
uses — but the redirect target is topically unrelated to the
client-server boundary, and no `#network-boundary` heading exists on it
(or anywhere else in `docs/`). If you'd prefer,
`/docs/app/getting-started/server-and-client-components` is the closer
page and I'm happy to switch it (the anchor would have to be dropped
either way).
## Also checked: `viewTransition`
The `next-config-js` reference index on nextjs.org still lists an entry
linking to
`/docs/app/api-reference/config/next-config-js/viewTransition`, which
404s. No change is needed in this repo: that page was intentionally
deleted in 28a9465d4 ("docs: view transitions guide — skill section,
source-audit fixes, flag-removal docs", #96097) as the docs half of the
`experimental.viewTransition` flag removal (#96098), and the guide now
states that view transitions work with no configuration. There is no
surviving config option to repoint at, and no link to it remains
anywhere in `docs/` or `packages/*/src` on `main` — the stale index
entry comes from the nextjs.org versioned (v15) nav manifest, outside
this repo.
## Verification
- `prettier --check` passes on all changed files.
- `alex` (`lint-language`) reports only pre-existing prose warnings on
untouched lines.
- No `next.js` build was run; this is a docs-only, path-only change.
▲ Created with [Vercel
devbox](https://vercel.com/vercel/~/sandboxes/devboxes/1us5zdxyl2nk5ccodexgd9w3f6k2)
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Joseph <sephxd1234@gmail.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Each Skill section was a prose paragraph that assumed you had read the
ones above it. Reframe the three shipped Skills as a lead sentence,
three steps, and a linked prerequisite, so landing on an anchor from
search is enough.
Also drops the claim that the optimizer makes a route instant. It works
one navigation toward the UI you decide should be there, and commits the
passing test with the refactoring.
<!-- 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
We encourage you to use AI to assist you in researching, creating, and
reviewing changes. However, you must review and deeply understand the
contributions you are making. For this reason, **pull request
descriptions from external contributors must be written by a human**.
### 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: Claude Opus 5 <noreply@anthropic.com>
### What?
Two Skills assumed a default project layout, and both failed silently
when it didn't hold.
- `next-cache-components-adoption` hardcoded `./app` for the
`cache-components-instant-false` codemod, and checked its work under
`app/` too. It now resolves the app directory from `next.config.*` and
reads the file count the codemod reports.
- `next-dev-loop` probed `/_next/mcp` in preflight, but `NEXT_MCP_URL`
for a non-default port was only mentioned much later. The port is now
resolved before the first probe.
The same `./app` argument is documented for both 16.3 codemods, so the
two guides and the codemods reference get a matching Good to know.
### Why?
On a `src/app` project the codemod matched nothing and no gate caught
it. A path that doesn't exist isn't an error for jscodeshift: it prints
`No files selected, nothing to do`, reports `0 ok`, and exits `0`. The
root-layout check looked in the same wrong place, and if the app's
routes were prerenderable the build passed too, so a repo the migration
never touched came out green.
On a dev server bound to another port, the preflight probe read
"unreachable" and refused to verify while `next dev` was running.
Both are silent failures, which is the worst case for instructions an
agent runs top to bottom.
### How?
- Anchor on `next.config.*` so an agent invoked from a subdirectory
doesn't test for `app/` against the wrong `cwd`.
- When `app/` and `src/app/` both exist, say so: Next.js builds `app/`
and never reads `src/app/`, so those routes are shadowed and unbuilt.
Ask which tree to migrate.
- Treat `0 ok` as a wrong path rather than a finished run.
- Move the `NEXT_MCP_URL` resolution into the `next-dev-loop` preflight.
The transforms are fine. Their path regexes match `src/app/...`, and
pointed at `./src/app` they convert every segment.
`remove-partial-prefetch` has the same shape and hardcoded path, so it's
covered here too.
Fixes#96649
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
### What?
Adds a **Quick start** section to the top of the instant navigation
guide. It names the two migrations Instant Navigation is built on,
[Cache
Components](https://nextjs.org/docs/app/guides/migrating-to-cache-components)
and [Partial
Prefetching](https://nextjs.org/docs/app/guides/adopting-partial-prefetching),
links the adoption Skill for each, and gives a paste-ready prompt that
runs both in order.
Also rewords the intro to the existing **AI workflow** section, which
describes optimizing a single navigation rather than adopting the
features across an app.
### Why?
The guide explains how instant navigation works, but it never said how
to get it. Someone asked to "make navigations instant" landed here and
worked through the concepts by hand instead of using the adoption
Skills, and so did their coding agent. That has produced migrations that
satisfy validation while leaving nothing in the static shell, for
example wrapping a whole page in `<Suspense fallback={null}>`.
Instant navigations are the result of using Cache Components and Partial
Prefetching correctly, so the entry point belongs at the top of this
guide, ahead of the concepts, with a line handing readers back to the
rest of it.
### How?
One paragraph with inline links, then the prompt. The prompt has the
agent explain the change and ask how to split the work across PRs before
it starts, install the two adoption Skills plus `next-dev-loop` to
verify against a running dev server, adopt Cache Components before
Partial Prefetching one feature at a time, and report each step as a
table of routes and what changed.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The event parameter (second position) passed to proxy was not documented
in the Params section
<!-- 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
We encourage you to use AI to assist you in researching, creating, and
reviewing changes. However, you must review and deeply understand the
contributions you are making. For this reason, **pull request
descriptions from external contributors must be written by a human**.
### 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 #
-->
- Rework the
`/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache`
API reference.
- Adjust the table notes in
`/docs/app/api-reference/turbopack#configuration` — `[^1]` works well,
but the table notes are auto-magically placed at the bottom of the page.
Going with this hand rolled table notes for now.
- Tidy the Build Caching section in
`/docs/app/api-reference/turbopack#configuration`
- Update the Upgrade to version 16 section on dev/build cache
- Removed the `Build caching` from Webpack gaps
- Added Filesystem caching to Performance and Fast Refresh
Reworks the instant-navigation guide's e2e testing example to cover both
ways a route is reached: a direct visit (SSR document load) and a client
navigation.
Each test wraps the navigation in `instant()` and asserts the shell
renders while the streamed content is held back, then appears after.
Also documents where the testing API is available: automatically under
`next dev`, and in a production build via
`experimental.exposeTestingApiInProductionBuild`.
Closes:
https://linear.app/vercel/issue/DOC-6477/instant-e2e-helper-for-ssr-and-soft-navs-snippets-show-difference
---------
Co-authored-by: Aurora Scharff <aurora.sofie@gmail.com>
Co-authored-by: Aurora Scharff <66901228+aurorascharff@users.noreply.github.com>
## Summary
- clarify how runtime foundations, interactive workflows, and unattended
loops fit into the AI agents and Instant Navigation guides
- harden the Cache Components and Partial Prefetching Skills around
capability checks, trustworthy `instant()` tests, route scope, and
real-app verification failures
- add migration-guide comments to temporary Partial Prefetching route
config and update `remove-partial-prefetch` to remove only generated
comments while preserving runtime-prefetch TODOs and user comments
This keeps the experimental Partial Prefetching optimizer in #96471
separate.
## Testing
- `pnpm --filter @next/codemod build`
- `pnpm --filter @next/codemod test --
transforms/__tests__/remove-partial-prefetch.test.js --runInBand`
## Summary
Enable the project-local TypeScript CLI checker by default during `next
build`, while preserving `experimental.useTypeScriptCli: false` as an
opt-out to the TypeScript compiler API. Update the TypeScript 7
guidance, diagnostics, tests, and documentation to match the new
default.
## Verification
- `pnpm exec jest --runTestsByPath test/unit/isolated/config.test.ts`
- Pre-commit lint-staged checks passed (Prettier and ESLint)
- Not run: `pnpm test-start-turbo
test/production/app-dir/typescript-cli/typescript-cli.test.ts` (isolated
fixture dependency installation was blocked by unavailable npm registry
access)
- Not run: `pnpm --filter=next types` (repository has pre-existing
unrelated TypeScript errors)
<!-- NEXT_JS_LLM -->
## Summary
Enable `experimental.turbopackFileSystemCacheForBuild` by default in all
environments, including generic CI. Explicitly setting the option to
`false` remains the opt-out. Update the focused coverage and
documentation to match.
## Verification
- `IS_TURBOPACK_TEST=1 pnpm test-start-turbo
test/e2e/filesystem-cache/build-cache-default.test.ts`
- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--check packages/next/src/server/config-shared.ts
test/e2e/filesystem-cache/build-cache-default.test.ts
docs/01-app/03-api-reference/08-turbopack.mdx
docs/01-app/03-api-reference/05-config/01-next-config-js/turbopackFileSystemCache.mdx`
- Not run: `pnpm --filter=next build` (the checkout has 11 pre-existing
TypeScript errors in unrelated files)
<!-- NEXT_JS_LLM -->