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 <joseph.chamochumbi@vercel.com>
This commit is contained in:
Delba de Oliveira
2026-03-03 13:14:24 +00:00
committed by GitHub
parent ce14ca88a4
commit c2b4c0815c
111 changed files with 1764 additions and 2448 deletions
+2 -2
View File
@@ -19,5 +19,5 @@ To resolve this issue, you have two main options:
## Useful Links
- [Static and Dynamic Rendering](/docs/app/guides/caching#rendering-strategies) - Learn more about the differences between static and dynamic rendering in Next.js.
- [Dynamic APIs](/docs/app/guides/caching#dynamic-rendering) - Understand more about the usage of dynamic server functions in your Next.js application.
- [Prerendering and Dynamic Rendering](/docs/app/getting-started/caching#how-rendering-works) - Learn more about the differences between prerendering and dynamic rendering in Next.js.
- [Request-time APIs](/docs/app/glossary#request-time-apis) - Understand more about the usage of dynamic server functions in your Next.js application.
+6 -6
View File
@@ -4,17 +4,17 @@ title: Entire page deopted into client-side rendering
## Why This Error Occurred
During static rendering, the entire page was deopted into client-side rendering by `useSearchParams` as there was no [Suspense boundary](/docs/app/api-reference/functions/use-search-params#static-rendering) that caught it.
During prerendering, the entire page was deopted into client-side rendering by `useSearchParams` as there was no [Suspense boundary](/docs/app/api-reference/functions/use-search-params#prerendering) that caught it.
If a route is statically rendered, calling `useSearchParams()` will cause the tree up to the closest [Suspense boundary](/docs/app/api-reference/functions/use-search-params#static-rendering) to be client-side rendered.
If a route is prerendered, calling `useSearchParams()` will cause the tree up to the closest [Suspense boundary](/docs/app/api-reference/functions/use-search-params#prerendering) to be client-side rendered.
This allows a part of the page to be statically rendered while the dynamic part that uses `searchParams` can be client-side rendered.
This allows a part of the page to be prerendered while the dynamic part that uses `searchParams` can be client-side rendered.
## Possible Ways to Fix It
You can reduce the portion of the route that is client-side rendered by wrapping the component that uses useSearchParams in a Suspense boundary.
For example if `app/dashboard/search-bar.tsx` uses `useSearchParams` wrap the component in a [Suspense boundary](/docs/app/api-reference/functions/use-search-params#static-rendering) as shown in `app/dashboard/page.tsx`.
For example if `app/dashboard/search-bar.tsx` uses `useSearchParams` wrap the component in a [Suspense boundary](/docs/app/api-reference/functions/use-search-params#prerendering) as shown in `app/dashboard/page.tsx`.
```tsx filename="app/dashboard/search-bar.tsx"
'use client'
@@ -26,7 +26,7 @@ export default function SearchBar() {
const search = searchParams.get('search')
// This will not be logged on the server when using static rendering
// This will not be logged on the server during prerendering
console.log(search)
return <>Search: {search}</>
@@ -61,4 +61,4 @@ export default function Page() {
## Useful Links
- [`useSearchParams` static rendering documentation](/docs/app/api-reference/functions/use-search-params#static-rendering)
- [`useSearchParams` prerendering documentation](/docs/app/api-reference/functions/use-search-params#prerendering)
+2 -2
View File
@@ -4,7 +4,7 @@ title: Empty generateStaticParams with Cache Components
## Why This Error Occurred
You're using [Cache Components](https://nextjs.org/docs/app/getting-started/cache-components) in your Next.js application, and one of your `generateStaticParams` functions returned an empty array, which causes a build error.
You're using [Cache Components](https://nextjs.org/docs/app/getting-started/caching) in your Next.js application, and one of your `generateStaticParams` functions returned an empty array, which causes a build error.
When Cache Components is enabled, Next.js performs build-time validation to ensure your routes can be properly prerendered without runtime dynamic access errors. If `generateStaticParams` returns an empty array, Next.js cannot validate that your route won't access dynamic values (like `await cookies()`, `await headers()`, or `await searchParams`) at runtime, which would cause errors.
@@ -73,6 +73,6 @@ Using placeholders provides minimal build-time validation and increases the risk
## Useful Links
- [Cache Components Documentation](https://nextjs.org/docs/app/getting-started/cache-components)
- [Cache Components Documentation](https://nextjs.org/docs/app/getting-started/caching)
- [generateStaticParams API Reference](https://nextjs.org/docs/app/api-reference/functions/generate-static-params)
- [Dynamic Routes with Cache Components](/docs/app/api-reference/file-conventions/dynamic-routes#with-cache-components)
+1 -1
View File
@@ -4,7 +4,7 @@ title: Failed to find Server Action
## Why This Message Occurred
For security purposes, Next.js creates encrypted, non-deterministic keys (IDs) to allow for the client to reference and call the [Server Action](/docs/app/getting-started/updating-data). These keys are periodically recalculated between builds for enhanced security.
For security purposes, Next.js creates encrypted, non-deterministic keys (IDs) to allow for the client to reference and call the [Server Action](/docs/app/getting-started/mutating-data). These keys are periodically recalculated between builds for enhanced security.
When self-hosting your Next.js application across multiple servers, each server instance may end up with a different encryption key, leading to potential inconsistencies.
+2 -2
View File
@@ -6,7 +6,7 @@ title: 'Invalid "use server" Value'
This error occurs when a `"use server"` file exports a value that is not an async function. It might happen when you unintentionally export something like a configuration object, an arbitrary value, or missed the `async` keyword in the exported function declaration.
These functions are required to be defined as async, because `"use server"` marks them as [Server Actions](/docs/app/getting-started/updating-data) and they can be invoked directly from the client through a network request.
These functions are required to be defined as async, because `"use server"` marks them as [Server Actions](/docs/app/getting-started/mutating-data) and they can be invoked directly from the client through a network request.
Examples of incorrect code:
@@ -39,5 +39,5 @@ Check all exported values in the `"use server"` file (including `export *`) and
## Useful Links
- [Server Actions and Mutations - Next.js](/docs/app/getting-started/updating-data)
- [Server Actions and Mutations - Next.js](/docs/app/getting-started/mutating-data)
- ['use server' directive - React](https://react.dev/reference/react/use-server)
@@ -187,5 +187,4 @@ This provides unminified stack traces with source maps, making it easier to pinp
- [`useSearchParams`](/docs/app/api-reference/functions/use-search-params)
- [`connection`](/docs/app/api-reference/functions/connection)
- [Dynamic Rendering guide](/docs/app/guides/caching#dynamic-rendering)
- [Debugging prerender errors](/docs/app/api-reference/cli/next#debugging-prerender-errors)
+4 -4
View File
@@ -1,16 +1,16 @@
---
title: Dynamic API was called outside request
title: Request-time API was called outside request
---
## Why This Error Occurred
A Dynamic API was called outside a request scope. (Eg.: Global scope).
A Request-time API was called outside a request scope. (Eg.: Global scope).
Note that Dynamic APIs could have been called deep inside other modules/functions (eg.: third-party libraries) that are not immediately visible.
Note that Request-time APIs could have been called deep inside other modules/functions (eg.: third-party libraries) that are not immediately visible.
## Possible Ways to Fix It
Make sure that all Dynamic API calls happen in a request scope.
Make sure that all Request-time API calls happen in a request scope.
Example:
+1 -1
View File
@@ -4,7 +4,7 @@ title: '`<title>` should not be used in _document.js `<Head>`'
## Why This Error Occurred
Adding `<title>` in `pages/_document.js` will lead to unexpected results with `next/head` since `_document.js` is only rendered on the initial pre-render.
Adding `<title>` in `pages/_document.js` will lead to unexpected results with `next/head` since `_document.js` is only rendered on the initial prerender.
## Possible Ways to Fix It
+1 -1
View File
@@ -4,7 +4,7 @@ title: No Router Instance
## Why This Error Occurred
During Pre-rendering (SSR or SSG) you tried to access a router method `push`, `replace`, `back`, which is not supported.
During Prerendering (SSR or SSG) you tried to access a router method `push`, `replace`, `back`, which is not supported.
## Possible Ways to Fix It
+2 -2
View File
@@ -4,9 +4,9 @@ title: Text content does not match server-rendered HTML
## Why This Error Occurred
While rendering your application, there was a difference between the React tree that was pre-rendered from the server and the React tree that was rendered during the first render in the browser (hydration).
While rendering your application, there was a difference between the React tree that was prerendered from the server and the React tree that was rendered during the first render in the browser (hydration).
[Hydration](https://react.dev/reference/react-dom/client/hydrateRoot) is when React converts the pre-rendered HTML from the server into a fully interactive application by attaching event handlers.
[Hydration](https://react.dev/reference/react-dom/client/hydrateRoot) is when React converts the prerendered HTML from the server into a fully interactive application by attaching event handlers.
### Common Causes
-1
View File
@@ -50,4 +50,3 @@ export async function createPost() {
- [revalidateTag Documentation](/docs/app/api-reference/functions/revalidateTag)
- [updateTag Documentation](/docs/app/api-reference/functions/updateTag)
- [Caching in Next.js](/docs/app/getting-started/caching-and-revalidating)
+1 -1
View File
@@ -5,7 +5,7 @@ description: Learn more about why accessing certain APIs synchronously now warns
## Why This Warning Occurred
Somewhere in your code you used an API that opts into [dynamic rendering](/docs/app/guides/caching#dynamic-rendering).
Somewhere in your code you used an API that opts into [dynamic rendering](/docs/app/glossary#dynamic-rendering).
Dynamic APIs are: