Skip to content

On-demand Revalidation

On-demand revalidation lets you purge cached data instantly when content changes — without waiting for time-based ISR. When you publish a new blog post, update a product, or modify CMS content, you can trigger immediate revalidation via revalidatePath or revalidateTag.

FunctionWhat it doesUse case
revalidatePath(path)Purges cache for a specific URL pathBlog post published → revalidate /blog
revalidateTag(tag)Purges all fetch requests with a tagCMS update → revalidate all posts tagged fetches
import { revalidatePath } from 'next/cache'
// After creating a new post
export default async function createPost(formData: FormData) {
const post = await db.post.create({ data: { title: formData.get('title') } })
// Revalidate the blog listing and the new post page
revalidatePath('/blog')
revalidatePath(`/blog/${post.slug}`)
return { success: true }
}

First, tag your fetches:

export default async function BlogPage() {
const posts = await fetch('https://api.example.com/posts', {
next: { tags: ['posts'] } // Tag this fetch with 'posts'
}).then(r => r.json())
return <BlogList posts={posts} />
}

Then revalidate by tag:

import { revalidateTag } from 'next/cache'
export default async function updatePost(id: string, data: any) {
await db.post.update({ where: { id }, data })
// This revalidates ALL fetch calls tagged with 'posts'
revalidateTag('posts')
return { success: true }
}

For CMS-driven sites, trigger revalidation via webhook:

app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache'
import { NextResponse } from 'next/server'
export async function POST(request: Request) {
const { secret, path, tag } = await request.json()
// Verify secret to prevent unauthorized revalidation
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
if (path) revalidatePath(path)
if (tag) revalidateTag(tag)
return NextResponse.json({ revalidated: true })
}

Configure your CMS to POST to /api/revalidate whenever content is published.

MethodGranularityUse CaseExample
revalidatePath('/blog')Route-levelSpecific page needs refreshNew blog post
revalidateTag('posts')Data-levelAll tagged data needs refreshCMS content update
Time-based ISRTime-granularPredictable update cyclesNews site
WebhookEvent-drivenCMS publishing workflowHeadless CMS
  1. Use tags over paths — More granular, revalidates exactly what changed
  2. Secure webhook endpoints — Use a secret to prevent abuse
  3. Combine with ISR — Use on-demand for critical updates, ISR for routine freshness
  4. Call revalidation after mutations — Inside Server Actions or Route Handlers
  • Not securing webhook endpoints (anyone can trigger revalidation)
  • Calling revalidatePath with the wrong path (case-sensitive)
  • Using revalidateTag without tagging fetches first (no effect)
  • Over-revalidating — revalidating entire site when only one page changed

On-demand revalidation (revalidatePath and revalidateTag) lets you instantly refresh cached content when data changes. Use tags for granular control, paths for page-level refreshes, and webhooks for CMS integration.