Menjawab Langsung Masalah Render Mismatch Hydration Vue

Render mismatch terjadi ketika HTML yang disajikan server tidak sama dengan struktur atau nilai yang diharapkan Vue/Alpine saat proses hydration berlangsung di browser. Untuk frontend CodeIgniter 3 yang mengandalkan SSR sederhana, kuncinya adalah menyelaraskan seluruh data dan atribut DOM antara controller, view, serta script client-side agar Vue tidak mencoba mengubah markup secara drastis.

Dengan pendekatan yang konsisten—mengirim data tunggal sebagai JSON inline, menunda inisialisasi hydration sampai elemen siap, serta memanfaatkan DevTools untuk memeriksa perbedaan—we dapat mencegah mismatch tanpa mengorbankan performa.

1. Menyiapkan Controller CodeIgniter 3 untuk Data Single Source of Truth

Controller harus menyiapkan data yang sama untuk view dan untuk state awal Vue/Alpine. Jangan menyisipkan data dari multiple sources di view tanpa koordinasi.

Contoh sederhana:

$data = [
    'produk' => [
        'nama' => 'Laptop Bisnis',
        'stok' => 8,
    ],
];
$this->load->view('produk/detail', $data);

Pelajaran utamanya: selalu kirim entire state yang dibutuhkan Vue melalui satu array, kemudian serialisasi ke JSON saat di view (lihat bagian berikut).

2. View CodeIgniter: HTML, Data Inline, dan ID yang Konsisten

Di view, pastikan markup Vue memiliki atribut data atau ID yang tetap dan tidak di-render ulang oleh Vu atau Alpine setelah hydration. Gunakan JSON inline untuk mengisi state awal, jangan render bagian yang bisa berubah langsung tanpa mengikat ke Vue.

Contoh snippet view:

<div id="produk-app" data-initial='<?= json_encode($produk); ?>'>
    <h2><?= htmlspecialchars($produk['nama']); ?></h2>
    <p v-text="stokText"></p>
</div>

Dengan atribut data-initial, Vue dapat mengambil data yang sama persis saat hydration pertama kali tanpa harus mengambil ulang dari API. Hindari mencampur data server dengan script terpisah yang bisa menimbulkan perbedaan nilai.

3. Menyusun Skrip Vue/Alpine dengan Hydration Delayed

Untuk mencegah hydration otomatis sebelum markup siap, gunakan teknik menunda eksekusi. Misalnya, di script utama:

document.addEventListener('DOMContentLoaded', () => {
  const appEl = document.getElementById('produk-app');
  const payload = JSON.parse(appEl.dataset.initial);
  setTimeout(() => {
    new Vue({
      el: appEl,
      data: () => ({
        produk: payload,
      }),
      computed: {
        stokText() {
          return `Stok tersedia: ${this.produk.stok}`;
        },
      },
    });
  }, 0);
});

Penundaan tipis menggunakan setTimeout(..., 0) memberi kesempatan view untuk menempelkan HTML server sebelum Vue menerima kontrol, mencegah hydration yang terlalu cepat. Teknik ini terutama berguna bila ada SSR sederhana di CodeIgniter yang membungkus komponen dengan tipe data tertentu.

4. Memastikan State Static Tidak Digenerate Ulang di Client

Jika view mencoba membandingkan nilai dinamis dengan nilai yang akan di-render Vue (misalnya tanggal otomatis atau UUID), pastikan nilai tersebut sudah final di server dan tidak ditulis ulang saat hydration. Solusi umum: letakkan data semacam ini di variable JavaScript only-once daripada di-bind ke template lagi.

Kalau perlu mengubah data di client, lakukan setelah hydration selesai, bukan sebelum. Gunakan lifecycle hook (Vue) atau x-init (Alpine) untuk menyesuaikan state tambahan, tapi bukan untuk render ulang markup inti.

5. Debugging Render Mismatch dengan DevTools dan Chunked Data

Untuk menemukan mismatch, buka DevTools dan bandingkan DOM yang dihidupkan oleh server dengan tree Vue. Di tab Elements, cari elemen yang memiliki peringatan hydration. Lalu buka console untuk melihat error Vue yang menyebutkan text content atau attribute mismatch.

Kalau data besar, gunakan pendekatan chunked data. Misalnya, kirim data besar melalui data-chunk dan lakukan parsing bertahap agar perbedaan tidak terjadi ketika DOM utama sudah dibentuk. Ini juga membantu memisahkan logika penanganan data besar dari markup awal; setiap chunk hanya di-append ke state setelah berhasil diparsing.

Gunakan juga fitur Vue DevTools untuk melihat state sesaat setelah hydration: pastikan semua properti terisi sesuai data inline. Jika ada perbedaan, bandingkan JSON inline dengan state Vue di tab Components.

Kesimpulan

Mencegah render mismatch hydration Vue di frontend CodeIgniter 3 menuntut konsistensi data dari controller hingga view, penundaan hydration sampai DOM siap, serta debugging berbasis DevTools dan chunked data saat diperlukan. Dengan mengikuti pola ini, HTML SSR Anda tetap sejalan dengan runtime Vue/Alpine tanpa membuang kelebihan render.