### Next.js: Cache Entire Route Segments using `use cache` Directive
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Illustrates how to apply the 'use cache' directive to `layout` and `page` files to enable full route segment caching. Each segment (layout and page) is cached independently, meaning any components imported into them will also be part of that segment's cache output.
```tsx
'use cache'
export default async function Layout({ children }: { children: ReactNode }) {
return
{children}
}
```
```jsx
'use cache'
export default async function Layout({ children }) {
return
{children}
}
```
```tsx
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default async function Page() {
return (
)
}
```
```jsx
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default async function Page() {
return (
)
}
```
--------------------------------
### Use cacheTag with Cache Components and use cache Directive
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/01-getting-started/09-caching-and-revalidating.mdx
Tag cached data within Cache Components using the cacheTag function alongside the 'use cache' directive. This allows caching of any computation beyond fetch requests, including database queries and file system operations. The example demonstrates caching product data fetched from a database.
```typescript
import { cacheTag } from 'next/cache'
export async function getProducts() {
'use cache'
cacheTag('products')
const products = await db.query('SELECT * FROM products')
return products
}
```
```javascript
import { cacheTag } from 'next/cache'
export async function getProducts() {
'use cache'
cacheTag('products')
const products = await db.query('SELECT * FROM products')
return products
}
```
--------------------------------
### Next.js: Cache Component Output with `use cache` for Repeated Renders
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Demonstrates applying the 'use cache' directive within a React component to cache any data fetches or computations performed inside it. The cached output is reused across renders as long as the serialized component props remain identical, improving performance for frequently rendered components.
```tsx
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
}
```
```jsx
export async function Bookings({ type = 'haircut' }) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
```
--------------------------------
### Next.js: Cache Asynchronous Function Output with `use cache` Directive
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Shows how to leverage the 'use cache' directive on any asynchronous function, not just components or routes, to cache its return value. This is useful for optimizing expensive operations like network requests, database queries, or complex computations by storing their results for subsequent calls.
```tsx
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
```
```jsx
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
```
--------------------------------
### Fetch Data with Default Cache Profile in Next.js
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Shows basic usage of 'use cache' directive to implicitly use the default cache profile with 5-minute client-side stale time, 15-minute server-side revalidation, and no time-based expiration. The function fetches data that is automatically cached at runtime.
```typescript
async function getData() {
'use cache'
// Implicitly uses default profile
return fetch('/api/data')
}
```
--------------------------------
### fetch options.cache
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/caching.mdx
Allows opting an individual `fetch` request into caching by setting the `cache` option to `'force-cache'`. This explicitly instructs Next.js to cache the fetched data.
```APIDOC
## FUNCTION_CALL fetch(resource, { cache: 'force-cache' })
### Description
Opt an individual `fetch` request into caching by setting the `cache` option to `'force-cache'`. This will store the fetched data in the Data Cache.
### Method
FUNCTION_CALL
### Endpoint
fetch(resource, { cache: 'force-cache' })
### Parameters
#### Request Body
- **cache** (string) - Required - Set to `'force-cache'` to enable caching for this specific fetch call.
### Request Example
```jsx
// Opt into caching
fetch(`https://...`, { cache: 'force-cache' })
```
### Response
#### Success Response (200)
- **data** (any) - The fetched data, now stored in the Data Cache for subsequent requests.
```
--------------------------------
### Apply `use cache` Directive to Files, Components, and Functions
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
The `use cache` directive can be strategically placed at the top of a file to cache all exports, within a React component definition, or directly inside an asynchronous function to cache its return value. This demonstrates its flexible application across various Next.js code structures.
```tsx
// 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
}
```
--------------------------------
### Next.js Cache Timeout with Shared Dynamic Promises in Map (Problem)
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
This example illustrates a build hang caused by a `use cache` component (`Cached`) retrieving a dynamic Promise from a shared `Map`. The `Dynamic` component stores a `fetch` Promise, which the `Cached` component then awaits, triggering a timeout. The recommended approach is to use Next.js's built-in `fetch()` deduplication or maintain separate storage for cached and uncached contexts.
```tsx
// Problem: Map stores dynamic Promises, accessed by cached code
import { Suspense } from 'react'
const cache = new Map>()
export default function Page() {
return (
<>
Loading...}>
>
)
}
async function Dynamic({ id }: { id: string }) {
// Stores dynamic Promise in shared Map
cache.set(
id,
fetch(`https://api.example.com/${id}`).then((r) => r.text())
)
return
Dynamic
}
async function Cached({ id }: { id: string }) {
'use cache'
return
{await cache.get(id)}
// Build hangs - retrieves dynamic Promise
}
```
--------------------------------
### Customize Cache Lifetime with cacheLife Function
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Demonstrates using the cacheLife function to apply a built-in cache profile ('hours') to a cached function, overriding the default cache duration settings. This enables fine-grained control over how long data remains cached on both client and server.
```typescript
import { cacheLife } from 'next/cache'
async function getData() {
'use cache'
cacheLife('hours') // Use built-in 'hours' profile
return fetch('/api/data')
}
```
--------------------------------
### Next.js: Implement On-Demand Cache Revalidation with `cacheTag` and `updateTag`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Demonstrates how to use `cacheTag` to mark fetched data for caching and `updateTag` to programmatically invalidate cached data associated with a specific tag. This allows for fine-grained control over cache invalidation based on data changes, ensuring users always see up-to-date information.
```tsx
import { cacheTag } from 'next/cache'
async function getProducts() {
'use cache'
cacheTag('products')
return fetch('/api/products')
}
```
```tsx
'use server'
import { updateTag } from 'next/cache'
export async function updateProduct() {
await db.products.update(...)
updateTag('products') // Invalidates all 'products' caches
}
```
--------------------------------
### Next.js Cache Nesting Rules for Remote, Regular, and Private Caches (TypeScript/TSX)
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This code illustrates the valid and invalid nesting patterns for different Next.js cache directives: 'use cache: remote', 'use cache', and 'use cache: private'. It demonstrates that remote caches can be nested within other remote or regular caches, but attempting to nest remote caches inside private caches, or private caches inside remote caches, will result in errors.
```tsx
// VALID: Remote inside remote
async function outerRemote() {
'use cache: remote'
const result = await innerRemote()
return result
}
async function innerRemote() {
'use cache: remote'
return getData()
}
// VALID: Remote inside regular cache
async function outerCache() {
'use cache'
// If this is in a dynamic context, the inner remote cache will work
const result = await innerRemote()
return result
}
async function innerRemote() {
'use cache: remote'
return getData()
}
// INVALID: Remote inside private
async function outerPrivate() {
'use cache: private'
const result = await innerRemote() // Error!
return result
}
async function innerRemote() {
'use cache: remote'
return getData()
}
// INVALID: Private inside remote
async function outerRemote() {
'use cache: remote'
const result = await innerPrivate() // Error!
return result
}
async function innerPrivate() {
'use cache: private'
return getData()
}
```
--------------------------------
### Opt into Caching with fetch force-cache Option
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/caching.mdx
Configure individual fetch requests to opt into caching by setting the cache option to 'force-cache'. This ensures fetched data is stored in the Data Cache and rendered output is stored in the Full Route Cache until revalidation occurs.
```jsx
fetch(`https://...`, { cache: 'force-cache' })
```
--------------------------------
### Generate Cache Key with Outer Scope Variables and Arguments
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
This example illustrates how a function using `'use cache'` automatically incorporates variables from its outer scope (like `userId`) along with its direct arguments (like `filter`) into the cache key. This ensures distinct cache entries for different combinations of these values, optimizing data fetching for personalized or filtered content.
```tsx
async function Component({ userId }: { userId: string }) {
const getData = async (filter: string) => {
'use cache'
// Cache key includes both userId (from closure) and filter (argument)
return fetch(`/api/users/${userId}/data?filter=${filter}`)
}
return getData('active')
}
```
--------------------------------
### get() - Retrieve Cached Value
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/incrementalCacheHandlerPath.mdx
Retrieves a cached value from the custom cache handler using the provided key. Returns the cached value or null if not found.
```APIDOC
## get()
### Description
Retrieves a cached value from the custom cache storage using the provided key.
### Method
GET
### Parameters
#### Required Parameters
- **key** (string) - The key to the cached value
### Returns
- Returns the cached value or `null` if not found
### Example
```js
const cachedValue = await cacheHandler.get('my-cache-key');
// Returns: cached data or null
```
```
--------------------------------
### Configure Next.js Cache in Azure Pipelines
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This YAML task utilizes `Cache@2` in Azure Pipelines to cache the `.next/cache` directory. The cache key is generated using the agent OS and `yarn.lock`, ensuring that the Next.js build cache is persisted and restored efficiently between pipeline runs, speeding up build processes.
```yaml
- task: Cache@2
displayName: 'Cache .next/cache'
inputs:
key: next | $(Agent.OS) | yarn.lock
path: '$(System.DefaultWorkingDirectory)/.next/cache'
```
--------------------------------
### fetch(url, options) - Cache Option
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/04-functions/fetch.mdx
Configure how server-side fetch requests interact with Next.js Data Cache using the cache option. Controls whether responses are cached, reused from cache, or always fetched fresh.
```APIDOC
## fetch(url, options) - options.cache
### Description
Sets caching behavior for fetch requests with Next.js Data Cache. Controls whether data is cached, revalidated, or always fetched fresh from the remote server.
### Parameters
#### Cache Option Values
- **`auto`** (default) - Optional - Next.js fetches on every request in development, once during build for static routes. Uses Dynamic APIs detection to determine caching.
- **`no-store`** - Optional - Fetch from remote server on every request, bypassing Data Cache entirely
- **`force-cache`** - Optional - Always check Data Cache first, fetch from remote server only if not cached or stale
### Request Example
```ts
// Default behavior (auto)
fetch('https://api.example.com/data')
// Never cache, always fetch fresh
fetch('https://api.example.com/data', { cache: 'no-store' })
// Always use cache if available
fetch('https://api.example.com/data', { cache: 'force-cache' })
```
### Cache Behavior Details
- **`auto` (default)**: Fetches on every request during development. Fetches once during `next build` for statically prerendered routes. Detects Dynamic APIs to determine runtime caching behavior.
- **`no-store`**: Fetches from remote server on every request regardless of Dynamic API detection or caching configuration.
- **`force-cache`**: Returns cached response if fresh and available. Fetches from remote server if no cache match or if cached response is stale. Updates cache with fresh response.
```
--------------------------------
### Cache Individual fetch Requests in Next.js
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/01-getting-started/09-caching-and-revalidating.mdx
Cache individual fetch requests by setting the cache option to 'force-cache'. By default, fetch requests are not cached in Next.js, but this option enables caching for specific requests. The code demonstrates how to configure fetch with force-cache in both TypeScript and JavaScript.
```typescript
export default async function Page() {
const data = await fetch('https://...', { cache: 'force-cache' })
}
```
```javascript
export default async function Page() {
const data = await fetch('https://...', { cache: 'force-cache' })
}
```
--------------------------------
### Cache Next.js Remote API Responses in Streaming Contexts
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This example illustrates caching external API responses within streaming contexts using 'use cache: remote' in Next.js. The `getFeedItems` function fetches data from an API and caches it for 2 minutes using `cacheLife` and `cacheTag`, thereby reducing requests to the external service during dynamic operations.
```tsx
import { Suspense } from 'react'
import { connection } from 'next/server'
import { cacheLife, cacheTag } from 'next/cache'
export default async function FeedPage() {
return (
}>
)
}
async function FeedItems() {
// Dynamic context
await connection()
const items = await getFeedItems()
return items.map((item) => )
}
async function getFeedItems() {
'use cache: remote'
cacheTag('feed-items')
cacheLife({ expire: 120 }) // 2 minutes
// This API call is cached, reducing requests to your external service
const response = await fetch('https://api.example.com/feed')
return response.json()
}
```
--------------------------------
### set() - Store Cached Value
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/incrementalCacheHandlerPath.mdx
Stores data in the custom cache handler with an associated key and optional cache tags for invalidation purposes.
```APIDOC
## set()
### Description
Stores data in the custom cache handler with an associated key and optional cache tags for revalidation.
### Method
POST
### Parameters
#### Required Parameters
- **key** (string) - The key to store the data under
- **data** (Data or null) - The data to be cached
- **ctx** (object) - The cache context object
- **tags** (array) - The cache tags provided for revalidation
### Returns
- Returns `Promise`
### Example
```js
await cacheHandler.set('my-cache-key', { data: 'value' }, { tags: ['tag1', 'tag2'] });
```
```
--------------------------------
### Control Individual `fetch` Request Caching in Next.js
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/upgrading/version-15.mdx
`fetch` requests in Next.js are no longer cached by default. To re-enable caching for specific requests, pass the `cache: 'force-cache'` option to the `fetch` call. This allows granular control over caching behavior for individual data fetches.
```js
export default async function RootLayout() {\n const a = await fetch('https://...') // Not Cached\n const b = await fetch('https://...', { cache: 'force-cache' }) // Cached\n\n // ...\n}
```
--------------------------------
### Enable Cache Components in Next.js Configuration
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
To activate the `use cache` directive, set the `cacheComponents` option to `true` within your `next.config.ts` or `next.config.js` file. This configures your Next.js application to utilize the caching feature.
```typescript
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig
```
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
cacheComponents: true,
}
module.exports = nextConfig
```
--------------------------------
### Remove fetchCache config and use use cache directive
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/01-getting-started/06-cache-components.mdx
The fetchCache route segment config is no longer needed with the new caching model. When you use the 'use cache' directive, all data fetching within that cached scope is automatically cached, eliminating the need for fetchCache.
```typescript
// Before
export const fetchCache = 'force-cache'
```
```typescript
// After - Use 'use cache' to control caching behavior
export default async function Page() {
'use cache'
// All fetches here are cached
return
...
}
```
--------------------------------
### Configure Next.js Cache with GitHub Actions `actions/cache`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This GitHub Actions YAML step leverages `actions/cache@v4` to persist the Next.js build cache (`.next/cache`) and npm cache (`~/.npm`). The cache key is generated based on the runner OS, `package-lock.json`, and source files, ensuring efficient cache invalidation and restoration to speed up your workflow runs.
```yaml
uses: actions/cache@v4
with:
# See here for caching with `yarn`, `bun` or other package managers https://github.com/actions/cache/blob/main/examples.md or you can leverage caching with actions/setup-node https://github.com/actions/setup-node
path: |
~/.npm
${{ github.workspace }}/.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
```
--------------------------------
### Next.js Cache Timeout with Dynamic Cookies as Props (Problem)
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
This example demonstrates how passing a `cookies()` Promise directly as a prop to a `use cache` component (`Cached`) causes a build hang. The `Cached` component awaits data that is runtime-specific, leading to a timeout during prerendering. To avoid this, resolve the cookie value in the parent component before passing it.
```tsx
import { cookies } from 'next/headers'
import { Suspense } from 'react'
export default function Page() {
return (
Loading...}>
)
}
async function Dynamic() {
const cookieStore = cookies()
return // Build hangs
}
async function Cached({ promise }: { promise: Promise }) {
'use cache'
const data = await promise // Waits for runtime data during build
return
..
}
```
--------------------------------
### Next.js Remote Cache Example with Dynamic Context (TypeScript/TSX)
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This example demonstrates how to use the 'use cache: remote' directive and 'cacheLife' configuration to cache data in a remote handler within a dynamic component. The presence of 'connection()' makes the context dynamic, while 'getAnalytics()' is configured for remote caching with a 5-minute expiration, and 'getStats()' remains uncached, running on every request.
```tsx
async function UserDashboard() {
// Calling connection() makes the context dynamic
await connection()
// Without any caching directive, this runs on every request
const stats = await getStats()
// With 'use cache: remote', this is cached in the remote handler
const analytics = await getAnalytics()
return (
)
}
async function getAnalytics() {
'use cache: remote'
cacheLife({ expire: 300 }) // 5 minutes
// This expensive operation is cached and shared across all requests
return fetchAnalyticsData()
}
```
--------------------------------
### resetRequestCache() - Reset Request Cache
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/incrementalCacheHandlerPath.mdx
Resets the temporary in-memory cache for a single request before the next request is processed.
```APIDOC
## resetRequestCache()
### Description
Resets the temporary in-memory cache for a single request before the next request is processed.
### Method
RESET
### Returns
- Returns `void`
### Example
```js
cacheHandler.resetRequestCache();
```
```
--------------------------------
### Create Valid and Invalid Cached Components in Next.js
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Demonstrates proper usage of 'use cache' with serializable primitives and plain objects, and shows invalid patterns with class instances. The valid example accepts serializable arguments while the invalid example attempts to cache a class instance, which throws a serialization error.
```tsx
// Valid - primitives and plain objects
async function UserCard({
id,
config,
}: {
id: string
config: { theme: string }
}) {
'use cache'
return
{id}
}
// Invalid - class instance
async function UserProfile({ user }: { user: UserClass }) {
'use cache'
// Error: Cannot serialize class instance
return
{user.name}
}
```
--------------------------------
### revalidateTag() - Revalidate Cache by Tag
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/incrementalCacheHandlerPath.mdx
Revalidates cached data associated with one or more tags. Used for invalidating specific cache entries without clearing the entire cache.
```APIDOC
## revalidateTag()
### Description
Revalidates cached data associated with specified tags. This is used for cache invalidation based on tags rather than individual keys.
### Method
DELETE
### Parameters
#### Required Parameters
- **tag** (string or string[]) - The cache tag(s) to revalidate
### Returns
- Returns `Promise`
### Notes
- `revalidatePath` is a convenience layer on top of cache tags
- Calling `revalidatePath` will invoke your `revalidateTag` function
- You can choose whether to tag cache keys based on the path
### Example
```js
await cacheHandler.revalidateTag('tag1');
// or multiple tags
await cacheHandler.revalidateTag(['tag1', 'tag2']);
```
```
--------------------------------
### Configure Next.js Cache in GitLab CI `.gitlab-ci.yml`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This YAML snippet adds a cache configuration to your `.gitlab-ci.yml` file. It specifies `node_modules/` and `.next/cache/` as paths to be cached, using the commit reference slug as the cache key. This improves build performance by persisting dependencies and Next.js build artifacts across GitLab CI jobs.
```yaml
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .next/cache/
```
--------------------------------
### Memoize Asynchronous Data Fetching in React with `cache`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/caching.mdx
The React `cache` function memoizes the return value of an asynchronous function, preventing redundant executions. It's particularly useful for database or third-party library calls that don't automatically memoize, ensuring efficiency for repeated calls within the same request lifecycle.
```ts
import { cache } from 'react'
import db from '@/lib/db'
export const getItem = cache(async (id: string) => {
const item = await db.item.findUnique({ id })
return item
})
```
```js
import { cache } from 'react'
import db from '@/lib/db'
export const getItem = cache(async (id) => {
const item = await db.item.findUnique({ id })
return item
})
```
--------------------------------
### Configure Custom Cache Handler in Next.js
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/self-hosting.mdx
This snippet demonstrates how to configure `next.config.js` to use a custom cache handler and disable the default in-memory caching. This is crucial for consistent cache behavior in distributed environments like Kubernetes, ensuring cache state is managed externally.
```javascript
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0 // disable default in-memory caching
}
```
--------------------------------
### Implement set() method in Next.js cache handler
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/cacheHandlers.mdx
Store a cache entry for a given cache key. The method must await the pending entry promise before storing, as the cache entry may still be generating when called. This is essential for ensuring complete cache entries are persisted to the cache system.
```typescript
set(cacheKey: string, pendingEntry: Promise): Promise
```
```javascript
const cacheHandler = {
async set(cacheKey, pendingEntry) {
// Wait for the entry to be ready
const entry = await pendingEntry
// Store in your cache system
cache.set(cacheKey, entry)
},
}
```
--------------------------------
### Configure Next.js Cache in AWS CodeBuild `buildspec.yml`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This YAML snippet updates your `buildspec.yml` to include `.next/cache` and `node_modules` in the CodeBuild cache paths. Caching these directories accelerates subsequent builds by reusing previously built Next.js artifacts and installed npm packages.
```yaml
cache:
paths:
- 'node_modules/**/*' # Cache `node_modules` for faster `yarn` or `npm i`
- '.next/cache/**/*' # Cache Next.js for faster application rebuilds
```
--------------------------------
### Pass Next.js Server Actions via `use cache` to Client Components
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Illustrates how to pass a Next.js Server Action through a `use cache` component to a Client Component. This pattern allows server-side operations to be triggered from client-side interactions, ensuring the Server Action is not invoked within the cached function and maintaining the integrity of the cache.
```tsx
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise
}) {
'use cache'
// Do not call performUpdate here
return
}
// --- app/ClientComponent.tsx ---
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise
}) {
return
}
```
```jsx
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return
}
async function CachedComponent({ performUpdate }) {
'use cache'
// Do not call performUpdate here
return
}
// --- app/ClientComponent.js ---
'use client'
export default function ClientComponent({ action }) {
return
}
```
--------------------------------
### Cache Next.js Remote Database Queries Per-Request
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This example demonstrates how to cache expensive database queries using 'use cache: remote' in a Next.js component. The `getGlobalStats` function uses `cacheTag` and `cacheLife` to store query results for 1 minute, reducing database load across all users accessing dynamic contexts.
```tsx
import { connection } from 'next/server'
import { cacheLife, cacheTag } from 'next/cache'
export default async function DashboardPage() {
// Make context dynamic
await connection()
const stats = await getGlobalStats()
return
}
async function getGlobalStats() {
'use cache: remote'
cacheTag('global-stats')
cacheLife({ expire: 60 }) // 1 minute
// This expensive database query is cached and shared across all users,
// reducing load on your database
const stats = await db.analytics.aggregate({
total_users: 'count',
active_sessions: 'count',
revenue: 'sum',
})
return stats
}
```
--------------------------------
### Configure Next.js Cache in Travis CI `.travis.yml`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This YAML snippet modifies your `.travis.yml` to include `.next/cache` in the list of directories to be cached. It helps persist the Next.js build cache, along with `node_modules` and Yarn's cache, between Travis CI builds, significantly reducing build times.
```yaml
cache:
directories:
- $HOME/.cache/yarn
- node_modules
- .next/cache
```
--------------------------------
### Configure fetch cache option
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/04-functions/fetch.mdx
Shows how to use the cache option parameter in fetch requests to control interaction with Next.js Data Cache. Options include 'force-cache' for persistent caching and 'no-store' for bypassing the cache on every request. The default 'auto' behavior depends on whether Dynamic APIs are detected.
```typescript
fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
```
--------------------------------
### set() - Store Cache Entry
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/cacheHandlers.mdx
Stores a cache entry for the given cache key. The method receives a promise that resolves to the cache entry, which may still be pending when called. The handler must await the promise before processing and storing the entry in the cache system.
```APIDOC
## set()
### Description
Store a cache entry for the given cache key.
### Method
Asynchronous function
### Signature
```ts
set(cacheKey: string, pendingEntry: Promise): Promise
```
### Parameters
- **cacheKey** (string) - Required - The unique key to store the entry under.
- **pendingEntry** (Promise) - Required - A promise that resolves to the cache entry. The entry may still be pending when this is called (i.e., its value stream may still be written to).
### Returns
Promise
### Implementation Notes
Your `set` method must await the `pendingEntry` promise before storing it, since the cache entry may still be generating when this method is called. Once resolved, store the entry in your cache system.
### Example Implementation
```js
const cacheHandler = {
async set(cacheKey, pendingEntry) {
// Wait for the entry to be ready
const entry = await pendingEntry
// Store in your cache system
cache.set(cacheKey, entry)
}
}
```
```
--------------------------------
### Cache Handler Configuration
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/05-config/01-next-config-js/incrementalCacheHandlerPath.mdx
Configure the Next.js cache handler in next.config.js to use a custom cache implementation for server cache operations such as storing and revalidating ISR and route handler responses.
```APIDOC
## CONFIGURATION
### Description
Configure a custom cache handler in next.config.js to persist cached pages and data to external storage services.
### Configuration
```js
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
}
```
### Parameters
- **cacheHandler** (string) - Required - Path to the custom cache handler module
- **cacheMaxMemorySize** (number) - Optional - Maximum memory size for in-memory caching (set to 0 to disable)
### Notes
- The `cacheHandler` (singular) is used for server cache operations including ISR and route handler responses
- For `'use cache'` directives, use `cacheHandlers` (plural) instead
- Implement custom handler for services like Redis, Memcached, or other external storage
```
--------------------------------
### Cache Next.js Remote Computed Data After Dynamic Checks
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This example demonstrates how to cache the results of expensive computations after dynamic security or feature checks in Next.js. The `generateReport` function uses 'use cache: remote' and `cacheLife` to store computed data for 1 hour, avoiding repeated calculations for authorized users.
```tsx
import { connection } from 'next/server'
import { cacheLife } from 'next/cache'
export default async function ReportsPage() {
// Dynamic security check
await connection()
const report = await generateReport()
return
}
async function generateReport() {
'use cache: remote'
cacheLife({ expire: 3600 }) // 1 hour
// This expensive computation is cached and shared across all authorized users,
// avoiding repeated calculations
const data = await db.transactions.findMany()
return {
totalRevenue: calculateRevenue(data),
topProducts: analyzeProducts(data),
trends: calculateTrends(data),
}
}
```
--------------------------------
### Pass Server Actions Through Cached Components
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Demonstrates passing Server Actions as non-serializable function arguments to cached components without introspecting or invoking them. The action is passed through to a form element, maintaining the pass-through pattern for composition.
```tsx
async function CachedForm({ action }: { action: () => Promise }) {
'use cache'
// Don't call action here - just pass it through
return
}
```
--------------------------------
### Wrap database queries with React cache function
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/01-getting-started/07-fetching-data.mdx
Use React's cache function to wrap direct database or ORM queries for request memoization. This deduplicates identical queries within a single render pass and can be shared across render passes.
```tsx
import { cache } from 'react'
import { db, posts, eq } from '@/lib/db'
export const getPost = cache(async (id: string) => {
const post = await db.query.posts.findFirst({
where: eq(posts.id, parseInt(id)),
})
})
```
```jsx
import { cache } from 'react'
import { db, posts, eq } from '@/lib/db'
import { notFound } from 'next/navigation'
export const getPost = cache(async (id) => {
const post = await db.query.posts.findFirst({
where: eq(posts.id, parseInt(id)),
})
})
```
--------------------------------
### Configure Next.js Cache in Heroku `package.json`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
This JSON snippet adds a `cacheDirectories` array to your `package.json` file, specifying `.next/cache` as a directory to be cached by Heroku's build system. This ensures that the Next.js build cache is preserved across deployments, leading to faster subsequent builds on Heroku.
```javascript
"cacheDirectories": [".next/cache"]
```
--------------------------------
### Basic cacheTag Usage with Cached Function
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/04-functions/cacheTag.mdx
Import cacheTag from 'next/cache' and call it within a cached function to tag the cached data. The function must use the 'use cache' directive to enable caching. Pass one or more string values as tags for later invalidation.
```typescript
import { cacheTag } from 'next/cache'
export async function getData() {
'use cache'
cacheTag('my-data')
const data = await fetch('/api/data')
return data
}
```
```javascript
import { cacheTag } from 'next/cache'
export async function getData() {
'use cache'
cacheTag('my-data')
const data = await fetch('/api/data')
return data
}
```
--------------------------------
### Next.js: Implement Remote Caching for Dynamic Product Prices with `cacheLife` and `cacheTag`
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-remote.mdx
This code snippet demonstrates how to cache product pricing that needs to be fetched at request time but can be shared across all users in a Next.js application. It utilizes `connection()` to mark the component as dynamic, then applies `'use cache: remote'`, `cacheTag`, and `cacheLife` to enable remote caching for the `getProductPrice` function, ensuring dynamic data can still be effectively cached.
```tsx
import { Suspense } from 'react'
import { connection } from 'next/server'
import { cacheTag, cacheLife } from 'next/cache'
export default async function ProductPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
return (
Loading price...
}>
)
}
function ProductDetails({ id }: { id: string }) {
return
Product: {id}
}
async function ProductPrice({ productId }: { productId: string }) {
// Calling connection() makes this component dynamic, preventing
// it from being included in the static shell. This ensures the price
// is always fetched at request time.
await connection()
// Now we can cache the price in a remote cache handler.
// Regular 'use cache' would NOT work here because we're in a dynamic context.
const price = await getProductPrice(productId)
return
Price: ${price}
}
async function getProductPrice(productId: string) {
'use cache: remote'
cacheTag(`product-price-${productId}`)
cacheLife({ expire: 3600 }) // 1 hour
// This database query is cached and shared across all users
return db.products.getPrice(productId)
}
```
```jsx
import { Suspense } from 'react'
import { connection } from 'next/server'
import { cacheTag, cacheLife } from 'next/cache'
export default async function ProductPage({ params }) {
const { id } = await params
return (
Loading price...
}>
)
}
function ProductDetails({ id }) {
return
Product: {id}
}
async function ProductPrice({ productId }) {
// Calling connection() makes this component dynamic, preventing
// it from being included in the static shell. This ensures the price
// is always fetched at request time.
await connection()
// Now we can cache the price in a remote cache handler.
// Regular 'use cache' would NOT work here because we're in a dynamic context.
const price = await getProductPrice(productId)
return
Price: ${price}
}
async function getProductPrice(productId) {
'use cache: remote'
cacheTag(`product-price-${productId}`)
cacheLife({ expire: 3600 }) // 1 hour
// This database query is cached and shared across all users
return db.products.getPrice(productId)
}
```
--------------------------------
### Cache Revalidation Comparison
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/01-getting-started/09-caching-and-revalidating.mdx
Comparison of the three cache revalidation functions, their use cases, available contexts, and behavioral differences for choosing the right function for your caching needs.
```APIDOC
## Cache Revalidation Functions Comparison
### Overview
Three main functions for cache revalidation in Next.js:
### Comparison Table
| Feature | revalidateTag | updateTag | revalidatePath |
|---------|---------------|-----------|----------------|
| **Available In** | Server Actions, Route Handlers | Server Actions only | Server Actions, Route Handlers |
| **Revalidation Type** | Tag-based | Tag-based (immediate) | Path-based |
| **Stale-While-Revalidate** | Yes (with profile='max') | No | No |
| **Behavior** | Serves stale + fetches fresh (with profile='max') or immediate expiration | Immediately expires cache | Immediately revalidates path |
| **Use Case** | Background updates, performance optimization | Read-your-own-writes | Path-specific cache refresh |
### Key Differences
#### revalidateTag
- **Behavior**: Tag-based cache invalidation with optional stale-while-revalidate support
- **Profile Parameter**: Supports `profile="max"` for background revalidation
- **Context**: Server Actions and Route Handlers
- **Best For**: General cache invalidation with performance optimization
#### updateTag
- **Behavior**: Immediately expires tagged cache entries
- **Constraints**: Server Actions only
- **Best For**: Ensuring users see their own writes immediately (read-your-own-writes)
#### revalidatePath
- **Behavior**: Path-based cache invalidation
- **Context**: Server Actions and Route Handlers
- **Best For**: Revalidating entire routes or pages
### Selection Guide
1. **Use `revalidateTag('max')`** when you want background revalidation with stale-while-revalidate semantics
2. **Use `updateTag`** in Server Actions for immediate cache expiration in read-your-own-writes scenarios
3. **Use `revalidatePath`** when you need to revalidate based on URL paths rather than tags
```
--------------------------------
### Pass Through ReactNode Children in Cached Components
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache.mdx
Shows how to compose cached components with dynamic children by accepting ReactNode as a pass-through argument without reading or modifying it. This enables caching the wrapper structure while allowing child components to remain dynamic and uncached.
```tsx
async function CachedWrapper({ children }: { children: ReactNode }) {
'use cache'
// Don't read or modify children - just pass it through
return (
Cached Header
{children}
)
}
// Usage: children can be dynamic
export default function Page() {
return (
{/* Not cached, passed through */}
)
}
```
--------------------------------
### Tag Cache Entries with fetch next.tags
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/caching.mdx
Tag cache entries when using fetch by setting the next.tags option with an array of tag strings. Tagged cache entries can later be purged using the revalidateTag function for fine-grained cache control.
```jsx
fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } })
```
--------------------------------
### Configure Next.js to Enable Cache Components for Private Caching
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/01-directives/use-cache-private.mdx
To use the `"use cache: private"` directive, you must first enable the `cacheComponents` flag in your `next.config.js` or `next.config.ts` file. This configuration is essential for Next.js to process and optimize private cache functions, allowing for runtime prefetching of personalized content.
```typescript
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig
```
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
cacheComponents: true,
}
export default nextConfig
```
--------------------------------
### Configure Next.js Cache in Bitbucket Pipelines
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/02-guides/ci-build-caching.mdx
These YAML snippets define a custom cache named `nextcache` for `.next/cache` at the top level of `bitbucket-pipelines.yml` and then reference it within a build step's `caches` section. This configuration allows Bitbucket Pipelines to persist the Next.js build cache, along with `node_modules`, between builds to enhance performance.
```yaml
definitions:
caches:
nextcache: .next/cache
```
```yaml
- step:
name: your_step_name
caches:
- node
- nextcache
```
--------------------------------
### Override Default Fetch Caching with fetchCache Export
Source: https://github.com/vercel/next.js/blob/canary/docs/01-app/03-api-reference/03-file-conventions/route-segment-config.mdx
Export a fetchCache constant to override the default caching behavior of all fetch requests in a layout or page. Provides granular control over whether fetch requests are cached or not, with options ranging from auto-detection to forced caching or no-store strategies. This is an advanced option for specific use cases.
```typescript
export const fetchCache = 'auto'
// 'auto' | 'default-cache' | 'only-cache'
// 'force-cache' | 'force-no-store' | 'default-no-store' | 'only-no-store'
```
```javascript
export const fetchCache = 'auto'
// 'auto' | 'default-cache' | 'only-cache'
// 'force-cache' | 'force-no-store' | 'default-no-store' | 'only-no-store'
```