Cả hai làm mới Data Cache trên server sau khi data đổi (thường gọi trong Server Action / Route Handler). Khác nhau ở đơn vị nhắm tới.
revalidatePath(path) — làm mới cache theo đường dẫn route.
revalidatePath('/blog') // làm mới đúng trang /blog
revalidatePath('/blog/[slug]', 'page') // mọi trang khớp dynamic segmentDùng khi bạn biết rõ trang nào bị ảnh hưởng và nó tập trung ở một (vài) route.
revalidateTag(tag) — làm mới mọi fetch đã gắn tag đó, bất kể nằm ở route nào.
await fetch(url, { next: { tags: ['products'] } })
// sau khi sửa sản phẩm:
revalidateTag('products') // mọi nơi fetch 'products' đều mớiDùng khi cùng một loại data xuất hiện ở nhiều route rải rác (list, detail, sidebar) — chỉ một lệnh là đồng bộ hết.
Quy tắc chọn: ảnh hưởng theo trang → revalidatePath; ảnh hưởng theo loại data dùng chung khắp nơi → revalidateTag. Lưu ý: cả hai vô hiệu cache nhưng không re-render ngay; trang sẽ regenerate ở request kế tiếp.
Both refresh the server Data Cache after data changes (usually called in a Server Action / Route Handler). They differ in what they target.
revalidatePath(path) — refreshes cache by route path.
revalidatePath('/blog') // refreshes the /blog page
revalidatePath('/blog/[slug]', 'page') // every page matching the dynamic segmentUse it when you know exactly which page is affected and it's concentrated in one (few) route(s).
revalidateTag(tag) — refreshes every fetch tagged with that tag, regardless of route.
await fetch(url, { next: { tags: ['products'] } })
// after editing a product:
revalidateTag('products') // every fetch of 'products' anywhere is refreshedUse it when the same data type appears across many scattered routes (list, detail, sidebar) — one call syncs them all.
Rule of thumb: affected by page → revalidatePath; affected by a shared data type used everywhere → revalidateTag. Note: both invalidate the cache but don't re-render immediately; the page regenerates on the next request.