āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š nextjs/app/api-reference/directives/use-cache ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
The use cache directive allows you to mark a route, React component, or a function as cacheable. It can be used at the top of a file to indicate that all exports in the file should be cached, or inline at the top of function or component to cache the return value.
Good to know: For caching user-specific content that requires access to cookies or headers, see
'use cache: private'.
use cache is a Cache Components feature. To enable it, add the cacheComponents option to your next.config.ts file:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
cacheComponents: true,
}
module.exports = nextConfig
Then, add use cache at the file, component, or function level:
// File level
'use cache'
export default async function Page() {
// ...
}
// Component level
export async function MyComponent() {
'use cache'
return <></>
}
// Function level
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
use cache worksA cache entry's key is generated using a serialized version of its inputs, which includes:
The arguments passed to the cached function, as well as any values it reads from the parent scope automatically become a part of the key. This means, the same cache entry will be reused as long as its inputs are the same.
Any non-serializable arguments, props, or closed-over values will turn into references inside the cached function, and can be only passed through and not inspected nor modified. These non-serializable values will be filled in at the request time and won't become a part of the cache key.
For example, a cached function can take in JSX as a children prop and return <div>{children}</div>, but it won't be able to introspect the actual children object. This allows you to nest uncached content inside a cached component.
async function CachedComponent({ children }: { children: ReactNode }) {
'use cache'
return <div>{children}</div>
}
async function CachedComponent({ children }) {
'use cache'
return <div>{children}</div>
}
The return value of the cacheable function must be serializable props. This ensures that the cached data can be stored and retrieved correctly.
Good to know: The supported types for arguments and the supported types for returned values are not the same. For more details, refer to Serializable Parameters and Return Values for function arguments and Serializable Types for return values.
use cache at build timeWhen used at the top of a layout or page, the route segment will be prerendered, allowing it to later be revalidated.
This means use cache cannot be used with runtime data like cookies or headers.
Note: If you need to cache content that depends on cookies, headers, or search params, use
'use cache: private'instead.
use cache at runtimeOn the server, the cache entries of individual components or functions will be cached in-memory.
Then, on the client, any content returned from the server cache will be stored in the browser's memory for the duration of the session or until revalidated.
By default, use cache has server-side revalidation period of 15 minutes. While this period may be useful for content that doesn't require frequent updates, you can use the cacheLife and cacheTag APIs to configure when the individual cache entries should be revalidated.
Both of these APIs integrate across the client and server caching layers, meaning you can configure your caching semantics in one place and have them apply everywhere.
See the cacheLife and cacheTag API docs for more information.
use cacheTo pre-render an entire route, add use cache to the top of both the layout and page files. Each of these segments are treated as separate entry points in your application, and will be cached independently.
'use cache'
export default async function Layout({ children }: { children: ReactNode }) {
return <div>{children}</div>
}
'use cache'
export default async function Layout({ children }) {
return <div>{children}</div>
}
Any components imported and nested in page file are part of the cache output associated with the page.
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default async function Page() {
return (
<main>
<Users />
</main>
)
}
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default async function Page() {
return (
<main>
<Users />
</main>
)
}
Good to know:
- If
use cacheis added only to thelayoutor thepage, only that route segment and any components imported into it will be cached.- If any of the nested children in the route use Dynamic APIs, then the route will opt out of pre-rendering.
use cacheYou can use use cache at the component level to cache any fetches or computations performed within that component. The cache entry will be reused as long as the serialized props produce the same value in each instance.
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
interface BookingsProps {
type: string
}
export async function Bookings({ type = 'haircut' }) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
use cacheSince you can add use cache to any asynchronous function, you aren't limited to caching components or routes only. You might want to cache a network request, a database query, or a slow computation.
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
In React, composition with children or slots is a well-known pattern for building flexible components. When using use cache, you can continue to compose your UI in this way. Anything included as children, or other compositional slots, in the returned JSX will be passed through the cached component without affecting its cache entry.
As long as you don't directly reference any of the JSX slots inside the body of the cacheable function itself, their presence in the returned output won't affect the cache entry.
export default async function Page() {
const uncachedData = await getData()
return (
// Pass compositional slots as props, e.g. header and children
<CacheComponent header={<h1>Home</h1>}>
{/* DynamicComponent is provided as the children slot */}
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({
header, // header: a compositional slot, injected as a prop
children, // children: another slot for nested composition
}: {
header: ReactNode
children: ReactNode
}) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
{header}
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
export default async function Page() {
const uncachedData = await getData()
return (
// Pass compositional slots as props, e.g. header and children
<CacheComponent header={<h1>Home</h1>}>
{/* DynamicComponent is provided as the children slot */}
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({
header, // header: a compositional slot, injected as a prop
children, // children: another slot for nested composition
}) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
{header}
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
You can also pass Server Actions through cached components to Client Components without invoking them inside the cacheable function.
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise<void>
}) {
'use cache'
// Do not call performUpdate here
return <ClientComponent action={performUpdate} />
}
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({ performUpdate }) {
'use cache'
// Do not call performUpdate here
return <ClientComponent action={performUpdate} />
}
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise<void>
}) {
return <button onClick={action}>Update</button>
}
'use client'
export default function ClientComponent({ action }) {
return <button onClick={action}>Update</button>
}
| Deployment Option | Supported | | ------------------------------------------------------------------- | ----------------- | | Node.js server | Yes | | Docker container | Yes | | Static export | No | | Adapters | Platform-specific |
Learn how to configure caching when self-hosting Next.js.
| Version | Changes |
| --------- | ----------------------------------------------------------- |
| v16.0.0 | "use cache" is enabled with the Cache Components feature. |
| v15.0.0 | "use cache" is introduced as an experimental feature. |
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā