Rilis · 2 menit baca · 21 Oktober 2026

Publish tanpa rebuild

Satu link di footer diganti, build-nya lolos, tapi situsnya tetap menampilkan nilai lama. Jadi publish diubah menjadi transaksi database, bukan deployment.

Orang kartun menarik tuas yang menukar satu halaman berbingkai dengan halaman lain, sementara crane konstruksi tertidur di latar belakang
0
build frontend yang dipicu oleh publish konten
1
transaksi untuk mengganti versi live
8
unit konten yang di-publish dengan cara ini

01 · Bug yang memulainya

Konten menunggu deployment.

Situs publiknya berupa HTML statis. Publish di CMS memicu build frontend, dan sebuah Worker menandai publikasi berhasil setelah build selesai. Lalu satu handle media sosial di footer diganti. Build-nya lolos dan staging menampilkan handle baru, tapi catatan publikasinya masih pending. Apa pun yang membaca "publikasi terakhir yang berhasil" tetap menyajikan handle lama. Edit konten satu baris jadi bergantung pada pipeline build.

02 · Draft, snapshot, satu versi aktif

Editor bebas menyimpan kapan saja. Pengunjung hanya melihat satu versi.

  • Draft bersifat privat. Menyimpannya tidak membuat versi baru dan tidak mengubah situs.
  • Publish memvalidasi draft, menyalinnya menjadi snapshot yang tidak bisa diubah, lalu mengganti versi aktif, semuanya dalam satu transaksi database.
  • Versi sebelumnya tetap ada di riwayat, siap ditinjau atau di-rollback.
  • Versi A: live sebelum B di-publish, lalu masuk riwayat, siap di-rollback.
  • Versi B: draft yang tidak dilihat siapa pun sebelum di-publish, lalu live.

03 · Dibaca saat request

Situs membaca snapshot live di setiap request.

Halaman yang kontennya dari CMS dirender on-demand dengan Astro di Cloudflare Workers. Fungsi baca anonim hanya mengembalikan snapshot aktif, tidak pernah draft. Tidak ada fallback lokal: kalau publikasi hilang, request gagal secara jelas, bukan diam-diam menyajikan data fixture lama. Fixture tetap ada, tapi hanya sebagai data test.

-- Ilustrasi, bukan fungsi production
begin;
  insert into snapshots (unit, payload, draft_hash)
    values ('site', build_payload('site'), :reviewed_draft_hash)
    returning id into new_id;
  update publications set active_snapshot_id = new_id where unit = 'site';
commit;

04 · Ditinjau sebelum tayang

Yang tayang persis yang kamu tinjau, atau tidak sama sekali.

Alur di CMS-nya "Simpan draf → Tinjau & tayangkan", dengan tampilan sebelum/sesudah untuk seluruh unit. Transaksi publish mengunci tabel sumber dengan urutan yang tetap. Lalu ia mengecek dua hal: draft masih sama dengan yang kamu tinjau, dan versi live masih sama dengan yang kamu bandingkan. Kalau hasil publish tidak diketahui, misalnya karena koneksi putus, CMS mengecek hash versi live dulu sebelum menawarkan percobaan ulang.

05 · Satu batas kepercayaan

Browser tidak pernah memegang credential server.

Hanya Worker tepercaya yang memegang service role database. CMS berbicara dengan Worker itu, dan pengunjung membaca lewat fungsi anonim. Bundle browser yang bocor tidak membuka apa pun yang bisa menulis.

06 · Kapan saya tetap memilih statis

Situs ini melakukan kebalikannya.

Portfolio saya adalah export statis. Saya mengedit konten secara lokal lalu deploy. Itu berhasil karena editornya hanya satu, perubahannya jarang, dan biaya runtime-nya nol. Dengan beberapa editor yang mengharapkan "publish" berarti "langsung tayang", rebuild bukan fitur. Rebuild adalah bug-nya.

Tulisan berikutnyaHeader sticky yang mengecil tanpa JavaScript