nextjsisrrevalidateMahir4 mnt baca

Revalidasi: ISR & On-Demand

Update konten statis tanpa rebuild: time-based dan on-demand revalidation.

ISR: statis yang bisa disegarkan

Bayangkan papan pengumuman di sekolah. Ada dua cara mengurusnya: (1) diganti rutin tiap jam sesuai jadwal, atau (2) diganti segera begitu ada pengumuman baru dari guru. Keduanya membuat papan tetap akurat tanpa harus membangun ulang seluruh papan setiap menit.

Itulah kenapa revalidasi ada. Kamu dihadapkan pada dilema klasik: halaman statis itu super cepat (disajikan langsung dari cache) tapi bisa basi, sedangkan halaman dinamis selalu segar tapi lambat (render + fetch tiap request). ISR (Incremental Static Regeneration) adalah jalan tengahnya: sajikan versi statis yang cepat, lalu regenerate di background saat waktunya tiba atau saat ada pemicu.

Time-based revalidation: regenerate terjadwal

tsx
// app/blog/page.tsx
// Contoh 1: artikel regenerate maksimal tiap 1 jam
export const revalidate = 3600; // dalam detik

export default async function Blog() {
  const res = await fetch("https://api.example.com/posts");
  const posts = await res.json();
  return <PostList posts={posts} />;
}

Alurnya perlu dipahami baik-baik karena tidak intuitif: pengunjung pertama yang datang SETELAH 1 jam berlalu masih menerima versi lama (cepat!), tapi kunjungannya memicu regenerate di background. Pengunjung berikutnya barulah mendapat versi baru. Pola ini disebut stale-while-revalidate: layani yang basi dulu, segarkan diam-diam.

Cara ini ideal untuk konten yang berubah terjadwal atau tidak kritis: blog, dokumentasi, halaman arsip.

On-demand revalidation: regenerate saat ada event

Kadang kamu tidak mau menunggu jadwal. Misalnya editor menekan "Publish" di CMS, artikel baru harus langsung tampil. Untuk itu ada revalidasi on-demand lewat Route Handler:

tsx
// app/api/revalidate/route.ts
// Contoh 2: endpoint yang dipanggil CMS setiap ada artikel baru
import { revalidatePath, revalidateTag } from "next/cache";
import { NextRequest } from "next/server";

export async function POST(req: NextRequest) {
  // Lindungi endpoint: hanya CMS yang tahu secret ini boleh memicu
  const secret = req.nextUrl.searchParams.get("secret");
  if (secret !== process.env.REVALIDATE_SECRET) {
    return Response.json({ error: "Unauthorized" }, { status: 401 });
  }

  revalidatePath("/blog"); // regenerate halaman /blog
  return Response.json({ revalidated: true });
}

Untuk kontrol yang lebih granular, pakai tags. Tandai fetch dengan tag, lalu revalidasi per tag tanpa menyentuh halaman lain:

tsx
// lib/api.ts
const res = await fetch("https://api.example.com/posts", {
  next: { tags: ["posts"] },
});
// di tempat lain: revalidateTag("posts") meregenerasi semua
// halaman yang fetch-nya bertag "posts", halaman lain tidak tersentuh.

Pola nyatanya: CMS punya webhook "on publish" yang memanggil /api/revalidate?secret=..., dan dalam hitungan detik artikel baru tampil tanpa rebuild atau redeploy.

Catatan teknis: Pilih time-based untuk konten yang "cukup segar berkala" (blog, docs), dan on-demand untuk konten yang "harus segar saat event" (publish CMS, update produk). Keduanya bisa digabung: revalidate = 3600 sebagai jaring pengaman, plus on-demand untuk momen penting. Dan jangan lupa: endpoint revalidasi WAJIB dilindungi secret, kalau tidak siapa pun bisa memaksa servermu regenerate terus-menerus.

Tantangan

Revalidasi manual

Buat halaman dengan revalidate = 60 yang menampilkan timestamp build. Buat juga API route yang memanggil revalidatePath. Panggil API-nya dan amati timestamp berubah.