CodeIgniter 4: Diagnosa Render Mismatch saat Hydration UI menjelaskan bagaimana mengatasi perbedaan antara markup server yang dirender oleh CI4 dan rehidrasi yang dilakukan oleh library frontend seperti Vue atau React. Jika sebuah halaman tampak berbeda setelah hydration, penyebabnya biasanya adalah data initial state yang tidak sinkron. Artikel ini langsung membahas gejala tersebut, cara memeriksa state dari controller, serta teknik menyamakan data antara backend dan frontend agar pengguna tidak bingung.

Kasus Realistis Hydration di CodeIgniter 4

Pada aplikasi hybrid, CI4 bertanggung jawab merender struktur HTML awal dan menanamkan data setempat, sementara Vue/React mengambil alih interaktivitas dengan hydrating elemen yang sudah ada. Misalnya, template list produk dirender di server dengan data stok terbaru, lalu markup tersebut di-hydrate oleh Vue untuk fitur filtering client-side. Jika data stok berubah di backend, markup lama tetap tampil hingga hydration selesai, sehingga jika frontend membaca state awal yang berbeda, terjadi render mismatch.

Kunci diagnosis: pastikan controller mengirimkan data yang sama dengan nilai yang digunakan frontend. Penyesuaian ini menjaga konsistensi markup dan menghindari hydration warning di console browser.

Tanda Render Mismatch dan Pemeriksaan State Awal

Tanda render mismatch

Berikut indikator pertama:

  • Console browser menampilkan pesan seperti Warning: Text content did not match. (React) atau [Vue warn]: Hydration failed.
  • Bagian UI seperti daftar, badge, atau status tombol berubah setelah hydration selesai.
  • Snapshot DOM server sebelum hydration berbeda dengan DOM setelah hydration.

Pemeriksaan state controller CI4

Periksa controller yang membuat view. Gunakan logging dan variabel sebelumnya untuk memastikan data yang disisipkan ke view sesuai. Contoh:

public function showProducts()
{
    $products = $this->productModel->findAll();
    log_message('debug', 'Products payload: ' . json_encode($products));

    return view('products/list', [
        'products' => $products,
        'user' => service('auth')->user()
    ]);
}

Log membantu meninjau payload sebelum diteruskan ke view. Jangan lupa menyesuaikan log level atau gunakan profiler saat di lingkungan pengembangan.

Menyamakan Data Server dan Initial State Frontend

Serialisasi aman dan atribut data

Tempatkan data backend ke dalam atribut data atau tag script yang kemudian dibaca frontend. Pastikan serialisasinya konsisten:

<script id="initial-state" type="application/json">
    
</script>

Pada sisi Vue/React, baca JSON tersebut sekali sebelum mount dan jadikan props atau store. Bila menggunakan React:

const initialState = JSON.parse(document.getElementById('initial-state').textContent);
ReactDOM.hydrate(<App {...initialState} />, document.getElementById('root'));

Mechanism ini memastikan data yang digunakan saat render server sama persis dengan input awal library frontend.

Placeholder dan atribut wajib

Walau data valid, beberapa komponen memerlukan atribut eksplisit agar niekspektasi. Misalnya, Vue memerlukan key pada v-for agar tidak terjadi perbedaan struktur saat hydration. Tambahkan atribut default agar markup server tidak kosong:

<template v-for="product in products" :key="product.id">
  <li>...</li>
</template>

Pastikan data seperti products tidak null atau undefined saat server render, karena frontend akan menganggapnya sudah siap.

Debugging dan Mitigasi

Logging dan snapshot DOM

Gunakan log server (misal log_message('info', ...)) untuk memastikan payload. Sementara itu, ambil snapshot markup HTML sebelum dan sesudah hydration dengan:

  • Tools browser seperti DevTools – lihat DOM sebelum script di-load dan setelah hydration.
  • Screenshot atau copy innerHTML untuk dibandingkan setara.

Jika DOM berubah drastis, identifikasi bagian mana yang berbeda (misalnya atribut data-foo yang hilang atau nilai teks berbeda) dan telusuri dalam view CI4.

Console warnings dan mitigation

Periksa warning hydration di console browser. Biasanya menyertakan node yang gagal di-hydrate. Gunakan pesan tersebut untuk menemukan data mana yang tidak match.

Untuk mitigasi:

  • Validasi data server sebelum render, cegah nilai null atau tipe berbeda.
  • Sinkronisasi update state backend ke frontend dengan menyertakan timestamp atau versi data yang konsisten.
  • Buat placeholder di markup server yang cocok dengan markup awal frontend sehingga React/Vue tidak memerlukan perubahan struktural.

Dengan teknik ini, render mismatch bisa diminimalkan, dan pengguna tidak melihat flashing UI atau error hydration.