const items = doc?.items?.length ? doc.items : DEFAULT_MENU;Baris itu contoh pola yang dipakai getter konfigurasi di modul data proyeknya, dan konstanta yang dirujuknya adalah default menu yang tinggal di kode. Sekilas dia terbaca seperti pengaman: kalau dokumennya belum ada, pakai default dari kode.
Yang lebih menentukan sebenarnya arah prioritasnya. Setiap getter yang mengambil dari Sanity mendahulukan dokumen Sanity kalau dokumennya ada, dan baru jatuh ke default di kode kalau dokumennya hilang atau kosong. Bukan kode yang berkuasa dengan CMS sebagai pelengkap, melainkan kebalikannya.
Satu remap menu yang tidak mau muncul
Kejadiannya 1 Mei 2026, di sebuah proyek Next.js 16 yang memakai Sanity. Satu bagian di menu utama harus pindah tujuan, jadi saya ubah satu href di lib/default-menu.ts supaya bagian itu menunjuk rute baru /updates, bukan lagi rute lama /listing. Staging tetap menampilkan pemetaan yang lama.
Ekspresi seperti di atas juga tidak menghasilkan peringatan apa pun. Dia memilih satu cabang, lalu selesai.
Membaca ulang barisnya
Ternary itu punya dua cabang, dan DEFAULT_MENU cuma tinggal di cabang kedua. Cabang kedua baru terpakai kalau doc tidak ada sama sekali, atau ada tapi isinya kosong, karena yang diperiksa memang panjang array. Selama dokumennya hadir dan arraynya berisi, ekspresi itu tidak pernah menoleh ke default di kode.
Jadi edit saya bukan salah. Dia cuma tidak terjangkau.
Bentuk yang sama juga bukan milik getter menu saja. Semua getter yang mengambil dari Sanity memakai urutan itu, dokumen dulu dan default belakangan, jadi apa yang terjadi pada menu bisa terjadi juga pada konfigurasi lain yang lewat jalur sama.
Dokumennya memang sudah ada
Penyelidikannya berhenti begitu dokumen konfigurasi menu di Sanity dibuka. Isinya masih struktur hasil seed sebelumnya, lengkap dengan href lama, persis seperti yang dirender staging.
Yang menulisnya bukan editor yang mengutak-atik menu lewat Studio, melainkan skrip seed proyeknya sendiri, yang mengisi dokumen itu lewat createOrReplace. Begitu skrip seed sudah mengisi dokumennya, suntingan pada lib/default-menu.ts atau default kode lain tidak akan muncul di situs yang dirender, karena dokumen Sanity menutupinya.
Satu fakta dengan dua tempat tinggal
Beberapa dokumen konfigurasi di proyek itu hidup di Sanity sebagai singleton, satu dokumen per tipe dengan _id tetap.
Konfigurasi menu menyimpan struktur top nav dan sub nav, dan pasangannya di kode adalah DEFAULT_MENU di lib/default-menu.ts. Tata letak beranda menentukan section mana yang dirender dan dalam urutan apa, pasangannya DEFAULT_SECTIONS di lib/config-data.ts. Konfigurasi marquee menentukan aset mana yang muncul di marquee, pasangannya DEFAULT_MARQUEE di berkas yang sama. Satu lagi menyimpan setelan provider, yaitu provider mana yang aktif beserta cap waktu error dan sukses terakhirnya.
Skrip seed-nya menelusuri DEFAULT_MENU beserta default kode lainnya, lalu melakukan createOrReplace pada dokumen singleton itu.
Satu dataset dipakai bareng lokal dan staging
Sanity di proyek ini dipakai bersama antara lokal dan staging lewat satu dataset yang sama. Karena itu seed ulang dari environment mana pun menyebar ke semuanya, dan tidak ada seed staging terpisah yang perlu diurus.
Perbaikannya urusan urutan, bukan urusan kode
Keputusannya menambah satu langkah wajib. Setiap kali lib/default-menu.ts atau apa pun yang muncul lewat singleton itu diubah, seed harus dijalankan lagi.
pnpm seed:configUrutan dua langkah itu ternyata bukan detail bebas, karena dua arah salahnya punya harga yang berbeda.
Kalau kode yang menambah rute baru seperti /updates didorong tanpa seed ulang, dokumen menu yang lama tetap menaut ke href lama, dan rute barunya tersembunyi dari pengguna. Kebalikannya, kalau seed ulang dilakukan sebelum kode pasangannya naik, menunya menaut ke rute yang belum ada dan yang didapat pengunjung adalah 404.
Urutan yang saya tulis di catatan proyek adalah seed ulang Sanity, baru dorong kode, lalu tunggu redeploy. Arah sebaliknya, dorong kode dulu baru seed ulang, harganya pengguna bisa melihat nav basi sekitar 60 detik sampai cachenya kedaluwarsa.
Aturan yang saya pakai sekarang
- Sebelum mengedit sebuah default di kode, cek dulu apakah dokumen singleton-nya sudah ada. Kalau sudah ada dan isinya tidak kosong, yang dibaca situs adalah dokumen itu.
- Baca pola dokumen dulu, default belakangan sebagai penentu prioritas, bukan sebagai pengaman. Kalimat sebenarnya adalah CMS dulu, kode hanya kalau dokumennya hilang atau kosong.
- Perlakukan perubahan default di kode sebagai pekerjaan dua langkah: ubah kodenya, lalu jalankan seed lagi.
- Tulis urutan dua langkah itu di catatan rilis, karena dua arahnya punya harga yang berbeda, 404 di navigasi utama atau nav basi sekitar semenit.
- Kalau nanti ada singleton baru yang punya suntingan editor sekaligus default di kode, dugaan saya shadowing yang sama akan terulang. Itu masih dugaan, bukan sesuatu yang sudah saya ukur.