Skip to content
Konsultasi

Homepage Live: Timeline Artikel Langsung dari API

Adityo Guni Waluyo

Section blog homepage yang dulu diisi manual lewat blog-posts.json sekarang fetch live dari API, plus helper formatDateWIB yang pin timezone Asia/Jakarta.

Setiap kali gue nulis artikel baru, ada satu ritual yang nggak pernah gagal bikin gue kesel: buka frontend/src/components/Blog.tsx, cari blog-posts.json, edit handcraft JSON-nya: ganti judul, ganti tanggal, ganti slug. Tiga kartu, tiga baris, tiga kesempatan salah ketik. Dan yang paling bikin gue geregetan: tanggal di kartu itu nggak pernah update sendiri. Artikel yang publish jam 3 pagi WIB tetap muncul tanpa jam, di-zone waktu server yang beda dari pengunjung.

Gue duga masalahnya di caching. Mungkin Next.js nge-cache render homepage jadi statis, makanya data nggak update. Gue sempat mau tambahin revalidate atau pakai ISR biar halaman ke-refresh periodik.

Ternyata bukan itu masalahnya.

blog-posts.json itu memang benar-benar statis, file hardcode yang gue maintain manual. Bukan data yang di-fetch dari manapun. Kartu-kartu di homepage itu cuma mirror dari file JSON yang sama dari awal projek ini dibuat. Jadi mau Next.js cache atau nggak, datanya tetap stale karena memang nggak ada sumber data live yang di-connect ke homepage.

Solusinya: buang JSON itu. Fetch langsung dari API yang sama dipake blog.

Ganti JSON Jadi Live Fetch

Gue bikin komponen baru ArticleTimelineItem.tsx yang render satu item di timeline. Blog.tsx sekarang terima articles dan locale sebagai props, bukan lagi nge-hardcode dari JSON. Dan yang paling penting, app/[locale]/page.tsx sekarang jadi async function yang langsung await fetch data:

fetchArticles({ locale, perPage: 6 })

Enam artikel published terbaru, live dari API. Tiap kali gue publish artikel baru, homepage langsung nggak perlu diutak-atik.

Tapi gue nggak mau homepage jadi blank kalau API-nya mati. Jadi fetch-nya dibungkus try/catch; kalau gagal, section blog cuma hilang mulus, bukan nge-crash seluruh halaman. Graceful degradation: pengunjung tetap lihat homepage utuh, cuma tanpa section blog.

try {
  const articles = await fetchArticles({ locale, perPage: 6 })
  // render timeline
} catch {
  // section hilang, nggak ada error
}

Satu Helper, Satu Masalah Waktu

Sebelum gue bikin fetch live, ada satu masalah kecil yang gue dulu abaikan: tanggal di homepage gue format pake Intl.DateTimeFormat tanpa explicitly set locale atau timezone. Hasilnya? Tergantung runtime server. Di local dev di Mac gue mungkin keliatan benar (WIB), tapi di Vercel edge function bisa beda.

MDN secara eksplisit bilang: tanpa locale dan options, Intl.DateTimeFormat pakai default locale dan default timezone dari runtime [2]. Jadi kalau server gue jalan di UTC, tanggal yang ditampilin juga UTC. Nggak ada yang salah secara teknis, tapi beda sama yang pengunjung Jakarta harapkan.

Solusinya simple: bikin helper formatDateWIB di lib/blog/format-date.ts yang fix set "Asia/Jakarta" sebagai timezone-nya. Formatter-nya tetap Intl.DateTimeFormat, tapi sekarang opsi timezone-nya di-pin, bukan ngikutin server.

new Intl.DateTimeFormat(locale, {
  timeZone: 'Asia/Jakarta',
  // ...options lain
})

Date chip di homepage sekarang konsisten, entah render di server, di client, atau di runtime mana pun. Nggak ada lagi tanggal yang keliatan "aneh" cuma karena timezone nggak cocok. Satu helper kecil, tapi bikin satu kategori bug hilang total.

Fetch Live di Server Components, dan Jejak Caching Next.js 15

Yang gue pelajari dari commit ini: Server Components di Next.js App Router emang bisa fetch data langsung — komponen jadi async function, await di dalamnya, data masuk sebagai props [1]. Dan fetch yang identik di pohon komponen otomatis di-memoize, jadi kalau ada beberapa komponen yang minta data sama, request ke API cuma terjadi sekali [1]. Pattern fetch begini sama dengan yang gue pakai pas bikin <a href="/id/blog/related-articles-satu-fetch-paralel">related articles yang sekali fetch paralel</a>.

Tapi ada satu hal yang berubah di Next.js 15 dan perlu gue catat: fetch nggak lagi di-cache secara default. Sebelumnya ada implicit caching, sekarang harus explicit opt-in pakai cache: 'force-cache' kalau mau cache [3]. Artinya, homepage gue yang sekarang fetch dari API berpotensi lebih "dynamic" dari sebelumnya: setiap request bisa trigger fresh fetch ke API, tergantung bagaimana konfigurasi caching di repo gue di-set.

Gue belum 100% cek apakah ada revalidate di repo yang bikin halaman home tetap static atau nggak. Tapi prinsipnya jelas: kalau kamu pindah dari JSON statis ke live fetch di Next.js 15, kamu perlu aware bahwa fetch behavior-nya beda dari Next.js 14 ke bawah. Jangan asumsi semua tetap cached.

Gue pribadi lebih suka approach ini: homepage yang live, tanggal yang konsisten, dan section yang bisa hilang sendiri tanpa drama. Lebih baik punya homepage yang sedikit lebih dynamic daripada harus edit JSON setiap kali nulis sesuatu. JSON statis di homepage itu teknik tahun 2019 yang seharusnya nggak kita bawa ke 2026.

Artikel terkait