Skip to content

Commit f4c886f

Browse files
authored
Next 16 updateTag and cache profiles examples (incremental cache handler) (#162)
* Added revalidate profile example * Added updateTag example
1 parent aab6a85 commit f4c886f

File tree

13 files changed

+1098
-19
lines changed

13 files changed

+1098
-19
lines changed

examples/redis-minimal/README.md

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,26 @@ Demonstrates persistent caching with `unstable_cache` for function results.
127127
- Click "Clear Tag Cache" to invalidate both caches
128128
- Understand when to use unstable_cache vs fetch
129129

130-
### 7. ISR with Static Params (`/examples/isr/blog/[id]`)
130+
### 7. revalidateTag() with cacheLife (`/examples/revalidate-tag-cachelife`)
131+
132+
Demonstrates the updated `revalidateTag()` API in Next.js 16 with cacheLife profiles.
133+
134+
**Features:**
135+
136+
- Breaking change from Next.js 15 (cacheLife now required)
137+
- Different cacheLife profiles: 'max', 'hours', 'days'
138+
- Stale-while-revalidate behavior
139+
- Examples for each profile type
140+
- Code examples showing migration from Next.js 15
141+
142+
**Try it:**
143+
144+
- Visit `/examples/revalidate-tag-cachelife` to see all three profiles
145+
- Click "Revalidate" buttons to test each profile
146+
- Compare the behavior of different cacheLife profiles
147+
- See code examples for Next.js 15 vs Next.js 16
148+
149+
### 8. ISR with Static Params (`/examples/isr/blog/[id]`)
131150

132151
Incremental Static Regeneration with `generateStaticParams`.
133152

@@ -144,7 +163,7 @@ Incremental Static Regeneration with `generateStaticParams`.
144163
- Try different IDs like `/examples/isr/blog/2`, `/examples/isr/blog/3`
145164
- Check the rendered timestamp to see caching in action
146165

147-
### 8. Static Params Test (`/examples/static-params/[testName]`)
166+
### 9. Static Params Test (`/examples/static-params/[testName]`)
148167

149168
Tests static params generation with dynamic routes.
150169

@@ -170,11 +189,14 @@ Unified endpoint for revalidating cache by tag or path.
170189

171190
**Tag-based revalidation (GET):**
172191

173-
- `GET /api/revalidate?tag=futurama` - Revalidates cache for the "futurama" tag
192+
- `GET /api/revalidate?tag=futurama` - Revalidates cache for the "futurama" tag with 'max' profile
193+
- `GET /api/revalidate?tag=futurama&cacheLife=hours` - Revalidates with 'hours' profile
194+
- `GET /api/revalidate?tag=futurama&cacheLife=days` - Revalidates with 'days' profile
174195

175196
**Tag-based revalidation (POST):**
176197

177-
- `POST /api/revalidate` with body `{ "tag": "futurama" }` - Revalidates cache for a tag
198+
- `POST /api/revalidate` with body `{ "tag": "futurama" }` - Revalidates cache for a tag (defaults to 'max')
199+
- `POST /api/revalidate` with body `{ "tag": "futurama", "cacheLife": "hours" }` - Revalidates with specific profile
178200

179201
**Path-based revalidation (POST):**
180202

@@ -183,14 +205,22 @@ Unified endpoint for revalidating cache by tag or path.
183205
**Examples:**
184206

185207
```bash
186-
# Revalidate by tag (GET)
208+
# Revalidate by tag (GET) - defaults to 'max' profile
187209
curl http://localhost:3000/api/revalidate?tag=futurama
188210

189-
# Revalidate by tag (POST)
211+
# Revalidate by tag with specific profile (GET)
212+
curl http://localhost:3000/api/revalidate?tag=futurama&cacheLife=hours
213+
214+
# Revalidate by tag (POST) - defaults to 'max' profile
190215
curl -X POST http://localhost:3000/api/revalidate \
191216
-H "Content-Type: application/json" \
192217
-d '{"tag": "futurama"}'
193218

219+
# Revalidate by tag with specific profile (POST)
220+
curl -X POST http://localhost:3000/api/revalidate \
221+
-H "Content-Type: application/json" \
222+
-d '{"tag": "futurama", "cacheLife": "days"}'
223+
194224
# Revalidate by path (POST)
195225
curl -X POST http://localhost:3000/api/revalidate \
196226
-H "Content-Type: application/json" \

examples/redis-minimal/src/app/api/revalidate/route.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ import { NextRequest } from "next/server";
44
export async function GET(request: NextRequest) {
55
const searchParams = request.nextUrl.searchParams;
66
const tag = searchParams.get("tag");
7+
const cacheLife = (searchParams.get("cacheLife") || "max") as
8+
| "max"
9+
| "hours"
10+
| "days";
711

812
if (tag) {
913
try {
10-
revalidateTag(tag, "max");
11-
return new Response(`Cache cleared for tag: ${tag}`, {
12-
status: 200,
13-
});
14-
} catch (error) {
15-
return new Response(`Error clearing cache for tag: ${tag}`, {
14+
revalidateTag(tag, cacheLife);
15+
return new Response(
16+
`Cache revalidated for tag: ${tag} with profile: ${cacheLife}`,
17+
{
18+
status: 200,
19+
}
20+
);
21+
} catch {
22+
return new Response(`Error revalidating cache for tag: ${tag}`, {
1623
status: 500,
1724
});
1825
}
@@ -29,10 +36,14 @@ export async function POST(request: NextRequest) {
2936
const { tag, path } = body;
3037

3138
if (tag) {
32-
revalidateTag(tag, "max");
33-
return new Response(`Cache cleared for tag: ${tag}`, {
34-
status: 200,
35-
});
39+
const cacheLife = (body.cacheLife || "max") as "max" | "hours" | "days";
40+
revalidateTag(tag, cacheLife);
41+
return new Response(
42+
`Cache revalidated for tag: ${tag} with profile: ${cacheLife}`,
43+
{
44+
status: 200,
45+
}
46+
);
3647
}
3748

3849
if (path) {

examples/redis-minimal/src/app/examples/no-store/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export default async function NoStoreExample() {
3636
<ExampleLayout
3737
title="No Store (Always Fresh) Example"
3838
description="This example demonstrates fetch with 'no-store' option, which always fetches fresh data and never caches the response. Perfect for real-time or user-specific data."
39+
actions={
40+
<RevalidatePathButton path="/examples/no-store" label="Refresh Page" />
41+
}
3942
>
4043
<div className="space-y-6">
4144
<InfoCard title="How it works">

0 commit comments

Comments
 (0)