Saya lagi mengerjakan tema toko Shopify klien, dan tugasnya sederhana: buang satu section Reviews dari halaman About yang sudah tidak dipakai. Saya edit templates/page.about.json, hapus block Reviews-nya, dan push:
shopify theme push --only=templates/page.about.jsonPush sukses, tidak ada error. Saya buka halaman About di live, section Reviews hilang seperti yang diharapkan. Selesai, pikir saya. Sampai beberapa jam kemudian klien kirim pesan: "kok gambar berubah ya?" Gambar hero di halaman About yang tadinya foto produk pilihan mereka, sekarang balik ke gambar fallback default tema, product-3in1-box.webp. Klien harus upload ulang gambarnya secara manual lewat admin.
Refleks pertama saya: apa saya salah hapus block? Saya cek diff, tidak. Saya cuma menyentuh block Reviews. Tapi gambar hero yang sama sekali tidak saya utak-atik ikut berubah. Rasanya seperti push saya menjangkau ke tempat yang tidak saya sentuh.
Kenapa ini terjadi
Begini duduk perkaranya, dan ini jebakan klasik saat tema live dibagi ke klien yang juga mengedit lewat theme editor Shopify.
Ketika klien meng-upload gambar atau mengubah teks lewat theme editor, perubahan itu tidak masuk ke file markup Liquid. Perubahan itu tersimpan sebagai setting di dalam templates/*.json (dan config/settings_data.json), di server. Setting seperti image_picker, text, dan block settings lainnya hidup di JSON itu, bukan di kode template. Jadi gambar hero yang di-upload klien sebenarnya adalah sebuah field image_picker di dalam templates/page.about.json versi server.
Masalahnya: copy lokal saya tidak punya field itu. Working copy saya masih versi lama, dari sebelum klien upload gambar. Waktu saya edit file JSON lokal itu untuk buang Reviews lalu push, saya menimpa seluruh isi templates/page.about.json di server dengan versi lokal saya. Field image_picker hero yang berisi gambar upload klien tidak ada di versi lokal, jadi Shopify jatuh ke fallback Liquid, dan muncullah product-3in1-box.webp.
Yang penting dipahami: push itu operasi timpa file, bukan merge cerdas. Push tidak tahu mana perubahan yang "milik saya" dan mana yang "milik klien". Dia cuma mengganti file server dengan file lokal. Semua kerja admin-side yang tidak ada di lokal saya, hilang.
Perbaikannya
Kuncinya: sebelum menyentuh file apa pun yang bisa diedit klien lewat editor, pull dulu versi server-nya, lalu edit di atas versi itu.
Sebelum push apa pun yang menyentuh templates/*.json, config/settings_data.json, atau section yang punya media picker, saya sekarang selalu pull file spesifiknya dulu dengan --nodelete:
shopify theme pull --path=<dir> --store=<store> --theme=<id> --only=templates/page.about.json --nodelete--nodelete penting supaya pull ini tidak menghapus file lokal lain yang tidak ada di server. Setelah pull, saya diff-nya untuk melihat setting dan block apa yang ditambahkan klien:
git diffDi diff itulah field image_picker hero yang berisi gambar klien akan muncul, yang tadinya tidak ada di copy lokal saya. Baru setelah itu saya lakukan edit saya, buang block Reviews, di atas versi yang sudah lengkap dengan kerja klien. Lalu push:
shopify theme push --only=templates/page.about.jsonSekarang push saya membawa serta gambar hero klien dan edit saya sekaligus, tanpa menimpa apa pun yang berharga.
Mana yang aman, mana yang tidak
Yang bikin jebakan ini licin: tidak semua file butuh ritual pull-dulu ini. File kode murni, seperti markup Liquid, CSS, dan JS, aman di-push langsung. Kenapa? Karena theme editor tidak bisa mengubah file itu. Klien tidak bisa mengedit sections/hero.liquid lewat editor, jadi tidak ada kerja server-side di sana yang bisa saya timpa.
Yang berbahaya spesifik file yang menyimpan nilai yang bisa diubah klien: templates/*.json, config/settings_data.json, dan section apa pun yang punya setting bertipe image_picker, video, atau file_reference. Di file-file itulah upload dan edit copy klien tinggal, dan di situlah push polos bisa menghapusnya.
Pelajaran
Di tema yang dibagi dengan klien, templates/*.json dan settings_data.json itu bukan cuma milik saya, itu wilayah bersama. Server adalah source of truth untuk apa pun yang diketik atau di-upload klien lewat editor. Push itu timpa, bukan merge, jadi push tanpa pull dulu akan diam-diam menghapus kerja admin-side klien. Sejak insiden ini, alur saya selalu: pull --only=<file> --nodelete, diff untuk melihat apa yang ditambahkan klien, edit di atasnya, baru push. Untuk file kode murni saya lewati ritual ini, tapi begitu ada image_picker atau media picker terlibat, saya pull dulu tanpa kecuali. Lebih baik satu perintah ekstra daripada menjelaskan ke klien kenapa foto mereka hilang.
