docs: Papercuts Feb26 (#89484)

This commit is contained in:
Joseph
2026-02-11 21:07:26 +01:00
committed by GitHub
parent 18a6866676
commit dc35817f9b
6 changed files with 18 additions and 14 deletions
@@ -33,8 +33,8 @@ Cache Components eliminates these tradeoffs by prerendering routes into a **stat
At build time, Next.js renders your route's component tree. As long as components don't access network resources, certain system APIs, or require an incoming request to render, their output is **automatically added to the static shell**. Otherwise, you must choose how to handle them:
- Defer rendering to request time by wrapping components in React's [`<Suspense>`](https://react.dev/reference/react/Suspense), [showing fallback UI](#defer-rendering-to-request-time) until the content is ready, or
- Cache the result using the [`use cache`](/docs/app/api-reference/directives/use-cache) directive to [include it in the static shell](#using-use-cache) (if no request data is needed)
- Either defer rendering to request time by wrapping components in React's [`<Suspense>`](https://react.dev/reference/react/Suspense), [showing fallback UI](#defer-rendering-to-request-time) until the content is ready
- Or cache the result using the [`use cache`](/docs/app/api-reference/directives/use-cache) directive to [include it in the static shell](#using-use-cache) (if no request data is needed)
Because this happens ahead of time, before a request arrives, we refer to it as prerendering. This generates a static shell consisting of HTML for initial page loads and a serialized [RSC Payload](/docs/app/getting-started/server-and-client-components#on-the-server) for client-side navigation, ensuring the browser receives fully rendered content instantly whether users navigate directly to the URL or transition from another page.
+2 -2
View File
@@ -176,7 +176,7 @@ To display validation errors or messages, turn the component that defines the `<
When using `useActionState`, the Server function signature will change to receive a new `prevState` or `initialState` parameter as its first argument.
```tsx filename="app/actions.ts" highlight={4} switcher
```tsx filename="app/actions.ts" highlight={5} switcher
'use server'
import { z } from 'zod'
@@ -189,7 +189,7 @@ export async function createUser(initialState: any, formData: FormData) {
}
```
```jsx filename="app/actions.ts" highlight={4} switcher
```jsx filename="app/actions.ts" highlight={7} switcher
'use server'
import { z } from 'zod'
@@ -14,7 +14,7 @@ related:
- app/api-reference/functions/connection
---
While the `use cache` directive is sufficient for most application needs, you might occasionally notice that cached operations are re-running more often than expected, or that your upstream services (CMS, databases, external APIs) are getting more hits than you'd expect. This can happen because in-memory caching has inherent limitations:
While the `use cache` directive is sufficient for most application needs, you might notice that cached operations are re-running more often than expected, or that your upstream services (CMS, databases, external APIs) are getting more hits than you'd expect. This can happen because `use cache` stores entries in-memory, which has inherent limitations:
- Cache entries being evicted to make room for new ones
- Memory constraints in your deployment environment
@@ -22,7 +22,7 @@ While the `use cache` directive is sufficient for most application needs, you mi
Note that `use cache` still provides value beyond server-side caching: it informs Next.js what can be prefetched and defines stale times for client-side navigation.
The `'use cache: remote'` directive lets you declaratively specify that a cached output should be stored in a **remote cache** instead of in-memory. While this gives you more durable caching for specific operations, it comes with tradeoffs: infrastructure cost and network latency during cache lookups.
The `'use cache: remote'` directive lets you declaratively specify that a cached output should be stored in a remote cache instead of in-memory, providing durable caching shared across all server instances. This comes with tradeoffs: infrastructure cost and network latency during cache lookups.
## Usage
@@ -73,7 +73,7 @@ Compelling scenarios for `'use cache: remote'`:
In these cases, the cost and latency of remote caching is justified by avoiding worse outcomes (rate limit errors, backend overload, high compute bills, or degraded user experience).
For static shell content, `use cache` is usually sufficient. However, if your static pages share data from an upstream that can't handle concurrent revalidation requests (like a rate-limited CMS), `use cache: remote` acts as a shared cache layer in front of that upstream. This is the same pattern as putting a key-value store in front of a database, but declared in your code rather than configured in infrastructure.
For static shell content, `use cache` is usually sufficient. If your upstream source can't handle concurrent revalidation requests (like a rate-limited CMS), `use cache: remote` acts as a shared cache layer. This is the same pattern as putting a key-value store in front of a database, but declared in code.
### How `use cache: remote` differs from `use cache` and `use cache: private`
@@ -90,9 +90,13 @@ Next.js provides three caching directives, each designed for different use cases
### Caching with runtime data
Both `use cache` and `'use cache: remote'` directives can't access runtime data like cookies or search params directly, since this data isn't available when computing the cache. However, you can extract values from these APIs and pass them as arguments to cached functions. See [with runtime data](/docs/app/getting-started/cache-components#with-runtime-data) for this pattern.
Both `use cache` and `'use cache: remote'` can't access runtime values like cookies or search params directly. You can extract these values and pass them as arguments to cached functions. See [with runtime data](/docs/app/getting-started/cache-components#with-runtime-data) for this pattern.
In general, but most importantly for `'use cache: remote'`, be thoughtful about which values you include in cache keys. Each unique value creates a separate cache entry, reducing cache utilization. Consider this example with search filters:
> **Good to know**: `use cache` stores entries in-memory. In serverless environments, memory is not shared between instances and is typically destroyed after serving a request, leading to frequent cache misses for runtime caching.
### Cache key considerations
Be thoughtful about which values you include in cache keys. Each unique value creates a separate cache entry, reducing cache utilization. Consider this example with search filters:
```tsx filename="app/products/[category]/page.tsx"
import { Suspense } from 'react'
@@ -57,7 +57,7 @@ export async function fetchUsers() {
Then you can import the `fetchUsers` Server Function into a Client Component and execute it on the client-side.
```tsx filename="app/components/my-button.tsx" highlight={1,2,8} switcher
```tsx filename="app/components/my-button.tsx" highlight={1,2,5} switcher
'use client'
import { fetchUsers } from '../actions'
@@ -66,7 +66,7 @@ export default function MyButton() {
}
```
```jsx filename="app/components/my-button.js" highlight={1,2,8} switcher
```jsx filename="app/components/my-button.js" highlight={1,2,5} switcher
'use client'
import { fetchUsers } from '../actions'
@@ -61,7 +61,7 @@ export default function Layout({ children }) {
You can use request APIs such as [`cookies`](/docs/app/api-reference/functions/cookies) and [`headers`](/docs/app/api-reference/functions/headers) inside `after` in [Server Functions](/docs/app/getting-started/updating-data) and [Route Handlers](/docs/app/api-reference/file-conventions/route). This is useful for logging activity after a mutation. For example:
```ts filename="app/api/route.ts" highlight={2,7-9} switcher
```ts filename="app/api/route.ts" highlight={2,10-16} switcher
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
@@ -86,7 +86,7 @@ export async function POST(request: Request) {
}
```
```js filename="app/api/route.js" highlight={2,7-9} switcher
```js filename="app/api/route.js" highlight={2,10-16} switcher
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
@@ -1274,7 +1274,7 @@ export async function generateMetadata() {
If metadata genuinely requires runtime data, add a dynamic marker component to your page:
```tsx filename="app/page.tsx" highlight={11-14,19,28}
```tsx filename="app/page.tsx" highlight={11-14,19,31}
import { Suspense } from 'react'
import { cookies } from 'next/headers'
import { connection } from 'next/server'