import { revalidateTag } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const secret = request.nextUrl.searchParams.get('secret')
const tag = request.nextUrl.searchParams.get('tag')
if (secret !== process.env.MY_SECRET_TOKEN) {
return NextResponse.json({ message: 'Token invalid' }, { status: 401 })
}
if (!tag) {
return NextResponse.json({ message: 'Tag lipsa' }, { status: 400 })
}
try {
revalidateTag(tag)
return NextResponse.json({ revalidated: true, now: Date.now() })
} catch (err) {
return NextResponse.json({ message: 'Eroare la revalidare' }, { status: 500 })
}
}Salutare! Văd des pe forum oameni care se blochează în dilema SSG vs ISR vs SSR, de parcă ar alege religia proiectului. Am trecut prin asta pe un magazin online cu peste 15.000 de produse și am învățat pe pielea mea (și pe portofelul clientului) că o decizie greșită te costă fie build-time uriaș, fie serverless execution time de mii de dolari pe Vercel.
Hai să lăsăm teoria corporatistă și să vedem cum am împărțit lucrurile, folosind 5 cazuri absolut reale de care te lovești în producție.
Cele 5 cazuri reale și decizia din spate
1. Blogul companiei sau paginile de marketing
- Alegerea: SSG (Static Site Generation) pur.
- De ce: Conținutul se schimbă doar când scrie cineva un articol nou. Nu ai mii de pagini. Am setat build-ul să ruleze automat la fiecare push în CMS-ul headless. Build-ul complet durează sub 2 minute. Simplu, ieftin, zero load pe baza de date în runtime.
2. Pagina de produs (Specificații și imagini)
- Alegerea: ISR (Incremental Static Regeneration) cu timp generos (ex: 24 de ore).
- De ce: Descrierea unui produs sau dimensiunile lui nu se schimbă de la minut la minut. Cu un
revalidate: 86400în fetch, primul user din zi declanșează regenerarea în fundal, iar restul primesc instant pagina din cache-ul global (Edge). Am redus interogările la baza de date cu 85% la orele de vârf.
3. Prețul și stocul produsului (E-commerce critic)
- Alegerea: On-demand Revalidation (bazat pe tag-uri de cache).
- De ce: Aici e buba cu ISR-ul clasic. Dacă ai o reducere fulger sau stocul scade la zero, nu poți aștepta să expire cele 24 de ore, dar nici nu vrei SSR la fiecare request (moare baza de date când ai 5k useri concurenți). Când ERP-ul modifică prețul, trimite un webhook către Next.js care apelează
revalidateTag('products'). Instantaneu, cache-ul e invalidat global.
4. Dashboard-ul utilizatorului (Contul meu)
- Alegerea: SSR sau Client-side Fetching.
- De ce: Datele sunt ultra-dinamice și specifice fiecărui user. Să încerci să faci ISR aici e o prostie și un risc masiv de securitate (să nu servești din greșeală cache-ul lui Vasile lui Gheorghe). Noi am mers pe o pagină statică de tip "schelet" și fetch direct din browser cu React Query pentru datele efective.
5. Secțiunea de documentație tehnică (Knowledge Base)
- Alegerea: SSG combinat cu On-Demand Revalidation.
- De ce: Avem în jur de 800 de pagini de doc. Build-ul lor dura prea mult la fiecare deploy mic. Le generăm static, dar le invalidăm doar când se face commit în repo-ul de markdown-uri, printr-un webhook simplu din GitHub Actions.
Trade-off-ul de care nu-ți zice nimeni în tutoriale
ISR-ul clasic are o problemă majoră numită "stale-while-revalidate". Când expiră timpul, primul user care intră pe pagină vede tot varianta veche (stale). Next.js pornește abia atunci regenerarea pe spate, iar al doilea user va vedea pagina nouă. Dacă ai prețuri modificate sau stocuri critice, primul user poate cumpăra la preț greșit.
De asta, pentru tot ce înseamnă date tranzacționale, On-Demand Revalidation este singura soluție sigură, chiar dacă necesită să scrii cod suplimentar pentru endpoint-ul de webhook.
Voi cum gestionați treaba asta în App Router? Mergeți pe On-Demand sau lăsați totul pe seama unui ISR scurt de 60 de secunde și sperați să fie bine?