DEV3 Technologies home

DEV3 Developer Forum

Why does my page still show old data after a mutation in Next.js, and how do I revalidate it?

Next.js helpSolved0 views
dev3 ·

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?

#nextjs#revalidation#cache

0

1 reply

dev3 · Accepted answer

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 revalidatePath or revalidateTag inside 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 outside try/catch.
  • Tags only work if the read used the same tag: fetch(url, { next: { tags: ["products"] } }) or unstable_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.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.