revalidatePath & redirect
After a mutation, refresh cached data with revalidatePath or send the user elsewhere with redirect.
Syntax
revalidatePath('/blog'); redirect('/blog/1');After a Server Action changes data, you usually want the UI to reflect it. Two helpers from Next handle the aftermath:
revalidatePath('/path')— clears the cache for a route so it re-fetches fresh data.revalidateTag('tag')— revalidates every fetch tagged with that label.redirect('/path')— navigates the user to another route after the action.
Call these at the end of your action once the write succeeds.
Example
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
const post = await db.post.create({ data: { title } });
revalidatePath('/blog'); // refresh the list
redirect(`/blog/${post.id}`); // go to the new post
}When to use it
- After saving a blog post, a Server Action calls revalidatePath('/blog') so the post list shows the new entry immediately.
- A delete action calls revalidateTag('products') to purge all cached pages that display product data.
- After a successful checkout, a Server Action calls redirect('/order/confirmation') to send the user to the thank-you page.
More examples
Revalidate after create
revalidatePath clears the cache for /blog so the next visit re-fetches and shows the new post.
'use server';
import { revalidatePath } from 'next/cache';
import { db } from '@/lib/db';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
await db.post.create({ data: { title } });
revalidatePath('/blog');
}Redirect after form submit
redirect inside a Server Action sends the browser to the new post page immediately after the save.
'use server';
import { redirect } from 'next/navigation';
import { db } from '@/lib/db';
export async function createPost(formData: FormData) {
const post = await db.post.create({
data: { title: formData.get('title') as string },
});
redirect(`/blog/${post.slug}`);
}Revalidate by tag
revalidateTag invalidates every cached fetch that was tagged with 'products', across all routes at once.
'use server';
import { revalidateTag } from 'next/cache';
export async function deleteProduct(id: string) {
await db.product.delete({ where: { id } });
revalidateTag('products');
}
Discussion