Careeroza
Time-based Revalidation
ISR in the App Router
Set revalidate on a fetch or for the whole route. Next.js serves the cached version; after the time passes, the next request still gets the old page, while a fresh one is built in the background (stale-while-revalidate).
// app/deals/page.tsx — rebuild at most once every 10 minutes
export const revalidate = 600;
export default async function DealsPage() {
const deals = await fetch('https://api.shopease.in/deals').then((r) => r.json());
return <pre>{JSON.stringify(deals, null, 2)}</pre>;
}Stale-While-Revalidate in TypeScript
Example
This version behaves like Next.js: a stale request returns the old value and triggers a background refresh.
type Entry<T> = { value: T; storedAt: number };
class SwrCache<T> {
private store = new Map<string, Entry<T>>();
constructor(private revalidate: number, private load: (key: string, now: number) => T) {}
get(key: string, now: number): string {
const hit = this.store.get(key);
if (!hit) {
const value = this.load(key, now);
this.store.set(key, { value, storedAt: now });
return 'MISS -> ' + value;
}
const age = now - hit.storedAt;
if (age < this.revalidate) return 'HIT -> ' + hit.value;
// serve stale, refresh "in the background"
this.store.set(key, { value: this.load(key, now), storedAt: now });
return 'STALE -> ' + hit.value + ' (refreshed for next time)';
}
}
let version = 0;
const cache = new SwrCache<string>(60, (key, now) => key + ' v' + ++version + ' @' + now + 's');
for (const t of [0, 30, 61, 62, 130]) {
console.log('t=' + String(t).padStart(3) + ' ' + cache.get('/deals', t));
}Output
t= 0 MISS -> /deals v1 @0s t= 30 HIT -> /deals v1 @0s t= 61 STALE -> /deals v1 @0s (refreshed for next time) t= 62 HIT -> /deals v2 @61s t=130 STALE -> /deals v2 @61s (refreshed for next time)
Choosing the Number
| Data | Typical revalidate |
|---|---|
| Blog post, About page | None (static) or 1 day |
| Product description | 1 hour + on-demand when edited |
| Price, stock on listing pages | 1–5 minutes + on-demand |
| Cart, order status | Do not cache (dynamic) |