After my server action updates a record and redirects to the list page, the list sometimes shows the old data until I refresh. How do I make it update immediately?
DEV3 Developer Forum
Why does my page still show old data after a mutation in Next.js, and how do I revalidate it?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
Two caches can serve stale data: the server's Data/Full Route cache and the client Router Cache. A mutation has to invalidate both.
"use server";
import { revalidatePath, revalidateTag } from "next/cache";
import { redirect } from "next/navigation";
export async function updateProduct(id: string, formData: FormData) {
await db.product.update({ where: { id }, data: { name: String(formData.get("name")) } });
revalidatePath("/products"); // the list page
revalidatePath(`/products/${id}`); // the detail page
// or, if the reads are tagged:
revalidateTag("products");
redirect("/products"); // call last, it throws internally
}
Rules
- Calling
revalidatePathorrevalidateTaginside a Server Action also clears the client Router Cache for the affected paths, so the next navigation shows fresh data. - From a route handler (webhooks, cron) the client cache of existing visitors is not cleared; they get fresh data when their client cache expires or on a hard load.
redirect()must come after revalidation, and outsidetry/catch.- Tags only work if the read used the same tag:
fetch(url, { next: { tags: ["products"] } })orunstable_cache(..., { tags }). - For layouts use
revalidatePath("/products", "layout").
In Next.js 16, revalidateTag takes a second cacheLife profile argument (for example revalidateTag("products", "max")) and a new updateTag("products") gives read-your-own-writes inside Server Actions; the single-argument form is deprecated.
Client refresh
In a client component you can also call router.refresh() from useRouter to re-fetch the current route's server data.
Pitfall: in production with several server instances, the default file-based cache is per instance. Use a shared cache handler (Redis) or a platform that handles it (Vercel) so revalidation reaches every instance.