rembrembdocs

revalidatePath

Last updated April 23, 2026

revalidatePath allows you to invalidate cached data on-demand for a specific path.

Usage

revalidatePath can be called in Server Functions and Route Handlers.

revalidatePath cannot be called in Client Components or Proxy, as it only works in server environments.

Good to know:

  • Server Functions: Updates the UI immediately (if viewing the affected path). Currently, it also causes all previously visited pages to refresh when navigated to again. This behavior is temporary and will be updated in the future to apply only to the specific path.
  • Route Handlers: Marks the path for revalidation. The revalidation is done on the next visit to the specified path. This means calling revalidatePath with a dynamic route segment will not immediately trigger many revalidations at once. The invalidation only happens when the path is next visited.

Parameters

revalidatePath(path: string, type?: 'page' | 'layout'): void;

Use a literal path when you want to refresh a single page. Use a route pattern plus type to refresh all matching pages.

Returns

revalidatePath does not return a value.

What can be invalidated

The path parameter can point to pages, layouts, or route handlers:

app/api/data/route.ts

export async function GET() {
  const data = await fetch('https://api.vercel.app/blog', {
    cache: 'force-cache',
  })
 
  return Response.json(await data.json())
}

Using revalidatePath with rewrites

When using rewrites, you must pass the destination path (the actual route file location), not the source path that appears in the browser's address bar.

For example, if you have a rewrite from /blog to /news:

next.config.js

module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog',
        destination: '/news',
      },
    ]
  },
}

To revalidate this page, use the destination path:

// Correct: use the destination path
revalidatePath('/news')
 
// Incorrect: the source path won't match the cache entry
revalidatePath('/blog')

This is because revalidatePath operates on the route file structure, not the URL visible to users. Cache entries are tagged based on which route file renders them.

Relationship with revalidateTag and updateTag

revalidatePath, revalidateTag and updateTag serve different purposes:

When you call revalidatePath, only the specified path gets fresh data on the next visit. Other pages that use the same data tags will continue to serve cached data until those specific tags are also revalidated:

// Page A: /blog
const posts = await fetch('https://api.vercel.app/blog', {
  next: { tags: ['posts'] },
})
 
// Page B: /dashboard
const recentPosts = await fetch('https://api.vercel.app/blog?limit=5', {
  next: { tags: ['posts'] },
})

After calling revalidatePath('/blog'):

Learn about the difference between revalidateTag and updateTag.

Building revalidation utilities

revalidatePath and updateTag are complementary primitives that are often used together in utility functions to ensure comprehensive data consistency across your application:

'use server'
 
import { revalidatePath, updateTag } from 'next/cache'
 
export async function updatePost() {
  await updatePostInDatabase()
 
  revalidatePath('/blog') // Refresh the blog page
  updateTag('posts') // Refresh all pages using 'posts' tag
}

This pattern ensures that both the specific page and any other pages using the same data remain consistent.

Examples

Revalidating a specific path

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/post-1')

This will invalidate one specific path for revalidation on the next page visit.

Revalidating a Page path

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'page')
// or with route groups
revalidatePath('/(main)/blog/[slug]', 'page')

This will invalidate any path that matches the provided page file for revalidation on the next page visit. This will not invalidate pages beneath the specific page. For example, /blog/[slug] won't invalidate /blog/[slug]/[author].

Revalidating a Layout path

import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'layout')
// or with route groups
revalidatePath('/(main)/post/[slug]', 'layout')

This will invalidate any path that matches the provided layout file for revalidation on the next page visit. This will cause pages beneath with the same layout to be invalidated and revalidated on the next visit. For example, in the above case, /blog/[slug]/[another] would also be invalidated and revalidated on the next visit.

Revalidating all data

import { revalidatePath } from 'next/cache'
 
revalidatePath('/', 'layout')

This will purge the Client Cache, and invalidate all cached data for revalidation on the next page visit.

Server Function

app/actions.ts

JavaScriptTypeScript

'use server'
 
import { revalidatePath } from 'next/cache'
 
export default async function submit() {
  await submitForm()
  revalidatePath('/')
}

Route Handler

app/api/revalidate/route.ts

JavaScriptTypeScript

import { revalidatePath } from 'next/cache'
import type { NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
  const path = request.nextUrl.searchParams.get('path')
 
  if (path) {
    revalidatePath(path)
    return Response.json({ revalidated: true, now: Date.now() })
  }
 
  return Response.json({
    revalidated: false,
    now: Date.now(),
    message: 'Missing path to revalidate',
  })
}

Was this helpful?