ข้ามไปยังเนื้อหา

Revalidation และ Cache Invalidation

เมื่อ data อยู่ใน Data Cache แล้ว เรา invalidate ได้สองทาง time-based (ปล่อยให้ stale หลัง N วินาที) หรือ on-demand (revalidateTag / revalidatePath หลัง mutation) และทั้งคู่ยัง refresh Full Route Cache ของ route ที่เกี่ยวข้องด้วย

ตั้ง lifetime ให้ fetch ที่ cache ไว้ด้วย next: { revalidate: N } หรือตั้งทั้ง route segment ด้วย export const revalidate เมื่อผ่านช่วงเวลานั้น request ถัดไปจะ trigger การ refresh แบบ background

// Per fetch: this data is at most 60 seconds stale
await fetch('https://api.example.com/posts', { next: { revalidate: 60 } })
// app/blog/page.tsx — revalidate the entire segment every hour
export const revalidate = 3600

สำหรับ data ที่เปลี่ยนตาม event ไม่ใช่ตามนาฬิกา ให้ tag fetch ไว้ แล้วเรียก revalidateTag หลัง mutation ทุก fetch ที่ถือ tag นั้นจะถูกทิ้งจาก Data Cache

lib/posts.ts
export async function getPosts() {
const res = await fetch('https://api.example.com/posts', {
next: { tags: ['posts'] },
})
return res.json()
}
app/actions.ts
'use server'
import { revalidateTag } from 'next/cache'
export async function createPost(formData: FormData) {
await fetch('https://api.example.com/posts', {
method: 'POST',
body: JSON.stringify({ title: formData.get('title') }),
})
// Invalidate every fetch tagged 'posts'
revalidateTag('posts')
}

ทั้งคู่รันใน Server Action หรือ Route Handler revalidateTag เล็งไปที่ data ตาม tag ไม่ว่า fetch จากที่ไหน revalidatePath เล็งไปที่ route และเคลียร์ทุกอย่างที่ cache ไว้ให้ route นั้น ใช้ตอนที่เราไม่รู้ tag

'use server'
import { revalidatePath } from 'next/cache'
export async function updateProfile() {
// Re-render and refetch everything for this exact route
revalidatePath('/profile')
}

revalidation แตะสองในสี่ชั้น เริ่มจากทิ้ง entry ที่ match จาก Data Cache และเพราะผล render ของ route ขึ้นกับ data นั้น จึง mark Full Route Cache ที่เกี่ยวข้องให้ stale ด้วย request ถัดไปจะ render ใหม่ด้วย data สดและเติมทั้งสอง cache กลับ ส่วน Request Memoization และ Router Cache ฝั่ง client ไม่ถูกแตะ Router Cache จะ refresh เองหลัง Server Action

flowchart LR
  A["Server Action: mutate"] --> B["revalidateTag('posts')"]
  B --> C["Data Cache: drop tagged entries"]
  C --> D["Full Route Cache: mark routes stale"]
  D --> E["Next request re-renders with fresh data"]
A mutation invalidating the Data and Route caches
สองวิธีในการทำ time-based revalidation คืออะไร?
เรียก revalidateTag ได้ที่ไหน?
revalidatePath ต่างจาก revalidateTag ยังไง?
fetch ต้องมีอะไรก่อน revalidateTag ถึงจะ invalidate fetch นั้นได้?