Skip to content

Commit 7fef3a0

Browse files
authored
docs: fresh up getting started 00 (#85736)
1 parent 2f86fba commit 7fef3a0

File tree

4 files changed

+209
-158
lines changed

4 files changed

+209
-158
lines changed

docs/01-app/01-getting-started/09-caching-and-revalidating.mdx

Lines changed: 163 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,23 @@ related:
66
description: Learn more about the features mentioned in this page by reading the API Reference.
77
links:
88
- app/api-reference/functions/fetch
9-
- app/api-reference/functions/unstable_cache
10-
- app/api-reference/functions/revalidatePath
9+
- app/api-reference/functions/cacheTag
1110
- app/api-reference/functions/revalidateTag
1211
- app/api-reference/functions/updateTag
12+
- app/api-reference/functions/revalidatePath
13+
- app/api-reference/functions/unstable_cache
1314
---
1415

1516
Caching is a technique for storing the result of data fetching and other computations so that future requests for the same data can be served faster, without doing the work again. While revalidation allows you to update cache entries without having to rebuild your entire application.
1617

1718
Next.js provides a few APIs to handle caching and revalidation. This guide will walk you through when and how to use them.
1819

1920
- [`fetch`](#fetch)
20-
- [`unstable_cache`](#unstable_cache)
21-
- [`revalidatePath`](#revalidatepath)
21+
- [`cacheTag`](#cachetag)
2222
- [`revalidateTag`](#revalidatetag)
2323
- [`updateTag`](#updatetag)
24+
- [`revalidatePath`](#revalidatepath)
25+
- [`unstable_cache`](#unstable_cache) (Legacy)
2426

2527
## `fetch`
2628

@@ -56,103 +58,65 @@ export default async function Page() {
5658

5759
This will revalidate the data after a specified amount of seconds.
5860

59-
See the [`fetch` API reference](/docs/app/api-reference/functions/fetch) to learn more.
60-
61-
## `unstable_cache`
61+
You can also tag `fetch` requests to enable on-demand cache invalidation:
6262

63-
`unstable_cache` allows you to cache the result of database queries and other async functions. To use it, wrap `unstable_cache` around the function. For example:
64-
65-
```ts filename="app/lib/data.ts" switcher
66-
import { db } from '@/lib/db'
63+
```tsx filename="app/lib/data.ts" switcher
6764
export async function getUserById(id: string) {
68-
return db
69-
.select()
70-
.from(users)
71-
.where(eq(users.id, id))
72-
.then((res) => res[0])
65+
const data = await fetch(`https://...`, {
66+
next: {
67+
tags: ['user'],
68+
},
69+
})
7370
}
7471
```
7572

7673
```jsx filename="app/lib/data.js" switcher
77-
import { db } from '@/lib/db'
78-
7974
export async function getUserById(id) {
80-
return db
81-
.select()
82-
.from(users)
83-
.where(eq(users.id, id))
84-
.then((res) => res[0])
75+
const data = await fetch(`https://...`, {
76+
next: {
77+
tags: ['user'],
78+
},
79+
})
8580
}
8681
```
8782

88-
```tsx filename="app/page.tsx" highlight={2,11,13} switcher
89-
import { unstable_cache } from 'next/cache'
90-
import { getUserById } from '@/app/lib/data'
83+
See the [`fetch` API reference](/docs/app/api-reference/functions/fetch) to learn more.
9184

92-
export default async function Page({
93-
params,
94-
}: {
95-
params: Promise<{ userId: string }>
96-
}) {
97-
const { userId } = await params
85+
## `cacheTag`
9886

99-
const getCachedUser = unstable_cache(
100-
async () => {
101-
return getUserById(userId)
102-
},
103-
[userId] // add the user ID to the cache key
104-
)
105-
}
106-
```
87+
[`cacheTag`](/docs/app/api-reference/functions/cacheTag) allows you to tag cached data in [Cache Components](/docs/app/getting-started/cache-components) so it can be revalidated on-demand. Previously, cache tagging was limited to `fetch` requests, and caching other work required the experimental `unstable_cache` API.
10788

108-
```jsx filename="app/page.js" highlight={2,7,9} switcher
109-
import { unstable_cache } from 'next/cache'
110-
import { getUserById } from '@/app/lib/data'
89+
With Cache Components, you can use the [`use cache`](/docs/app/api-reference/directives/use-cache) directive to cache any computation, and `cacheTag` to tag it. This works with database queries, file system operations, and other server-side work.
11190

112-
export default async function Page({ params }) {
113-
const { userId } = await params
91+
```tsx filename="app/lib/data.ts" switcher
92+
import { cacheTag } from 'next/cache'
11493

115-
const getCachedUser = unstable_cache(
116-
async () => {
117-
return getUserById(userId)
118-
},
119-
[userId] // add the user ID to the cache key
120-
)
94+
export async function getProducts() {
95+
'use cache'
96+
cacheTag('products')
97+
98+
const products = await db.query('SELECT * FROM products')
99+
return products
121100
}
122101
```
123102

124-
The function accepts a third optional object to define how the cache should be revalidated. It accepts:
103+
```jsx filename="app/lib/data.js" switcher
104+
import { cacheTag } from 'next/cache'
125105

126-
- `tags`: an array of tags used by Next.js to revalidate the cache.
127-
- `revalidate`: the number of seconds after cache should be revalidated.
106+
export async function getProducts() {
107+
'use cache'
108+
cacheTag('products')
128109

129-
```tsx filename="app/page.tsx" highlight={6-9} switcher
130-
const getCachedUser = unstable_cache(
131-
async () => {
132-
return getUserById(userId)
133-
},
134-
[userId],
135-
{
136-
tags: ['user'],
137-
revalidate: 3600,
138-
}
139-
)
110+
const products = await db.query('SELECT * FROM products')
111+
return products
112+
}
140113
```
141114

142-
```jsx filename="app/page.js" highlight={6-9} switcher
143-
const getCachedUser = unstable_cache(
144-
async () => {
145-
return getUserById(userId)
146-
},
147-
[userId],
148-
{
149-
tags: ['user'],
150-
revalidate: 3600,
151-
}
152-
)
153-
```
115+
Once tagged, you can use [`revalidateTag`](#revalidatetag) or [`updateTag`](#updatetag) to invalidate the cache entry for products.
154116

155-
See the [`unstable_cache` API reference](/docs/app/api-reference/functions/unstable_cache) to learn more.
117+
> **Good to know**: `cacheTag` is used with [Cache Components](/docs/app/getting-started/cache-components) and the [`use cache`](/docs/app/api-reference/directives/use-cache) directive. It expands the caching and revalidation story beyond `fetch`.
118+
119+
See the [`cacheTag` API reference](/docs/app/api-reference/functions/cacheTag) to learn more.
156120

157121
## `revalidateTag`
158122

@@ -161,55 +125,7 @@ See the [`unstable_cache` API reference](/docs/app/api-reference/functions/unsta
161125
- **With `profile="max"`**: Uses stale-while-revalidate semantics, serving stale content while fetching fresh content in the background
162126
- **Without the second argument**: Legacy behavior that immediately expires the cache (deprecated)
163127

164-
To use it with `fetch`, start by tagging the function with the `next.tags` option:
165-
166-
```tsx filename="app/lib/data.ts" highlight={3-5} switcher
167-
export async function getUserById(id: string) {
168-
const data = await fetch(`https://...`, {
169-
next: {
170-
tags: ['user'],
171-
},
172-
})
173-
}
174-
```
175-
176-
```jsx filename="app/lib/data.js" highlight={3-5} switcher
177-
export async function getUserById(id) {
178-
const data = await fetch(`https://...`, {
179-
next: {
180-
tags: ['user'],
181-
},
182-
})
183-
}
184-
```
185-
186-
Alternatively, you can mark an `unstable_cache` function with the `tags` option:
187-
188-
```tsx filename="app/lib/data.ts" highlight={6-8} switcher
189-
export const getUserById = unstable_cache(
190-
async (id: string) => {
191-
return db.query.users.findFirst({ where: eq(users.id, id) })
192-
},
193-
['user'], // Needed if variables are not passed as parameters
194-
{
195-
tags: ['user'],
196-
}
197-
)
198-
```
199-
200-
```jsx filename="app/lib/data.js" highlight={6-8} switcher
201-
export const getUserById = unstable_cache(
202-
async (id) => {
203-
return db.query.users.findFirst({ where: eq(users.id, id) })
204-
},
205-
['user'], // Needed if variables are not passed as parameters
206-
{
207-
tags: ['user'],
208-
}
209-
)
210-
```
211-
212-
Then, call `revalidateTag` in a [Route Handler](/docs/app/api-reference/file-conventions/route) or Server Action:
128+
After tagging your cached data, using [`fetch`](#fetch) with `next.tags`, or the [`cacheTag`](#cachetag) function, you may call `revalidateTag` in a [Route Handler](/docs/app/api-reference/file-conventions/route) or Server Action:
213129

214130
```tsx filename="app/lib/actions.ts" highlight={1,5} switcher
215131
import { revalidateTag } from 'next/cache'
@@ -233,28 +149,6 @@ You can reuse the same tag in multiple functions to revalidate them all at once.
233149

234150
See the [`revalidateTag` API reference](/docs/app/api-reference/functions/revalidateTag) to learn more.
235151

236-
## `revalidatePath`
237-
238-
`revalidatePath` is used to revalidate a route and following an event. To use it, call it in a [Route Handler](/docs/app/api-reference/file-conventions/route) or Server Action:
239-
240-
```tsx filename="app/lib/actions.ts" highlight={1} switcher
241-
import { revalidatePath } from 'next/cache'
242-
243-
export async function updateUser(id: string) {
244-
// Mutate data
245-
revalidatePath('/profile')
246-
```
247-
248-
```jsx filename="app/lib/actions.js" highlight={1} switcher
249-
import { revalidatePath } from 'next/cache'
250-
251-
export async function updateUser(id) {
252-
// Mutate data
253-
revalidatePath('/profile')
254-
```
255-
256-
See the [`revalidatePath` API reference](/docs/app/api-reference/functions/revalidatePath) to learn more.
257-
258152
## `updateTag`
259153

260154
`updateTag` is specifically designed for Server Actions to immediately expire cached data for read-your-own-writes scenarios. Unlike `revalidateTag`, it can only be used within Server Actions and immediately expires the cache entry.
@@ -307,3 +201,123 @@ The key differences between `revalidateTag` and `updateTag`:
307201
- **`revalidateTag`**: In Server Actions and Route Handlers, supports stale-while-revalidate with `profile="max"`
308202

309203
See the [`updateTag` API reference](/docs/app/api-reference/functions/updateTag) to learn more.
204+
205+
## `revalidatePath`
206+
207+
`revalidatePath` is used to revalidate a route and following an event. To use it, call it in a [Route Handler](/docs/app/api-reference/file-conventions/route) or Server Action:
208+
209+
```tsx filename="app/lib/actions.ts" highlight={1} switcher
210+
import { revalidatePath } from 'next/cache'
211+
212+
export async function updateUser(id: string) {
213+
// Mutate data
214+
revalidatePath('/profile')
215+
```
216+
217+
```jsx filename="app/lib/actions.js" highlight={1} switcher
218+
import { revalidatePath } from 'next/cache'
219+
220+
export async function updateUser(id) {
221+
// Mutate data
222+
revalidatePath('/profile')
223+
```
224+
225+
See the [`revalidatePath` API reference](/docs/app/api-reference/functions/revalidatePath) to learn more.
226+
227+
## `unstable_cache`
228+
229+
> **Good to know**: `unstable_cache` is an experimental API. We recommend opting into [Cache Components](/docs/app/getting-started/cache-components) and replacing `unstable_cache` with the [`use cache`](/docs/app/api-reference/directives/use-cache) directive. See the [Cache Components documentation](/docs/app/getting-started/cache-components) for more details.
230+
231+
`unstable_cache` allows you to cache the result of database queries and other async functions. To use it, wrap `unstable_cache` around the function. For example:
232+
233+
```ts filename="app/lib/data.ts" switcher
234+
import { db } from '@/lib/db'
235+
export async function getUserById(id: string) {
236+
return db
237+
.select()
238+
.from(users)
239+
.where(eq(users.id, id))
240+
.then((res) => res[0])
241+
}
242+
```
243+
244+
```jsx filename="app/lib/data.js" switcher
245+
import { db } from '@/lib/db'
246+
247+
export async function getUserById(id) {
248+
return db
249+
.select()
250+
.from(users)
251+
.where(eq(users.id, id))
252+
.then((res) => res[0])
253+
}
254+
```
255+
256+
```tsx filename="app/page.tsx" highlight={2,11,13} switcher
257+
import { unstable_cache } from 'next/cache'
258+
import { getUserById } from '@/app/lib/data'
259+
260+
export default async function Page({
261+
params,
262+
}: {
263+
params: Promise<{ userId: string }>
264+
}) {
265+
const { userId } = await params
266+
267+
const getCachedUser = unstable_cache(
268+
async () => {
269+
return getUserById(userId)
270+
},
271+
[userId] // add the user ID to the cache key
272+
)
273+
}
274+
```
275+
276+
```jsx filename="app/page.js" highlight={2,7,9} switcher
277+
import { unstable_cache } from 'next/cache'
278+
import { getUserById } from '@/app/lib/data'
279+
280+
export default async function Page({ params }) {
281+
const { userId } = await params
282+
283+
const getCachedUser = unstable_cache(
284+
async () => {
285+
return getUserById(userId)
286+
},
287+
[userId] // add the user ID to the cache key
288+
)
289+
}
290+
```
291+
292+
The function accepts a third optional object to define how the cache should be revalidated. It accepts:
293+
294+
- `tags`: an array of tags used by Next.js to revalidate the cache.
295+
- `revalidate`: the number of seconds after cache should be revalidated.
296+
297+
```tsx filename="app/page.tsx" highlight={6-9} switcher
298+
const getCachedUser = unstable_cache(
299+
async () => {
300+
return getUserById(userId)
301+
},
302+
[userId],
303+
{
304+
tags: ['user'],
305+
revalidate: 3600,
306+
}
307+
)
308+
```
309+
310+
```jsx filename="app/page.js" highlight={6-9} switcher
311+
const getCachedUser = unstable_cache(
312+
async () => {
313+
return getUserById(userId)
314+
},
315+
[userId],
316+
{
317+
tags: ['user'],
318+
revalidate: 3600,
319+
}
320+
)
321+
```
322+
323+
See the [`unstable_cache` API reference](/docs/app/api-reference/functions/unstable_cache) to learn more.

0 commit comments

Comments
 (0)