Next.js has multiple cache layers: Request Memoization (dedupes fetch calls per render), Data Cache (persists fetch results across requests), Full Route Cache (caches rendered routes), and Router Cache (client-side cache). Revalidation can be time-based (revalidate option), on-demand (revalidatePath/revalidateTag), or opt-out entirely with cache: 'no-store'.
getUser() in multiple components, only one request madefetch() options: cache, next.revalidate, next.tagsrouter.refresh(), revalidatePath, cookie changes// No caching - always fresh
fetch(url, { cache: 'no-store' })
// Cache indefinitely (default for GET)
fetch(url, { cache: 'force-cache' })
// Revalidate every 60 seconds
fetch(url, { next: { revalidate: 60 } })
// Tag for on-demand revalidation
fetch(url, { next: { tags: ['posts'] } })
revalidatePath('/blog') - Revalidate specific pathrevalidatePath('/blog', 'layout') - Revalidate layout and childrenrevalidateTag('posts') - Revalidate all fetches with tag// Force dynamic rendering
export const dynamic = 'force-dynamic';
// Force static (error if dynamic functions used)
export const dynamic = 'force-static';
// Revalidate entire route every hour
export const revalidate = 3600;
// app/products/page.tsx
// Cached indefinitely (default) - good for static data
async function getCategories() {
const res = await fetch('https://api.example.com/categories');
return res.json();
}
// Time-based revalidation - good for data that changes periodically
async function getProducts() {
const res = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 }, // Revalidate every hour
});
return res.json();
}
// No caching - good for real-time data
async function getInventory(productId: string) {
const res = await fetch(`https://api.example.com/inventory/${productId}`, {
cache: 'no-store', // Always fresh
});
return res.json();
}
// Tagged for on-demand revalidation
async function getProductDetails(id: string) {
const res = await fetch(`https://api.example.com/products/${id}`, {
next: {
tags: [`product-${id}`, 'products'], // Multiple tags
revalidate: 86400, // Also time-based (1 day)
},
});
return res.json();
}