Render Beda Server dan Client? Cara Mengatasi Text Content Does Not Match Server Rendered HTML Next Js

Error text content does not match server rendered HTML berarti HTML dari server berbeda dengan render pertama React di browser. Perbaikan tercepat: cari teks yang berubah nilainya, render versi netral dulu di server, lalu perbarui setelah mount di client.

Penyebab Text Content Berbeda antara Server dan Client

Next.js App Router me-render Server Component di server, lalu React melakukan hydration di browser. Selisih kecil memicu error.

  • new Date(), Date.now(), dan Intl.DateTimeFormat. Zona waktu server dan browser sering berbeda, jam berubah antar render.
  • Math.random(), ID acak, atau urutan acak. Server menghasilkan satu nilai, client menghasilkan nilai lain.
  • window, document, localStorage, navigator, atau matchMedia. API ini tidak ada di server, nilainya hanya tersedia setelah mount.
  • State auth, tema, bahasa, dan ekstensi browser. Ad blocker atau penerjemah dapat mengubah teks sebelum hydration selesai.

Tabel Diagnosis Cepat Hydration Error Ini

Baca pesan lengkap di console browser karena React menunjukkan teks server dibanding teks client.

Gejala Penyebab Paling Mungkin Pemeriksaan Pertama
Jam atau tanggal berbeda satu jam Timezone server dan client Format tanggal di Client Component
Angka atau banner berubah tiap refresh Konten acak saat render Pindah random ke event atau useEffect
Nama user muncul lalu hilang Auth hanya ada di browser Render loading dulu sebelum cookie dibaca
Data fetch berbeda Cache atau request ulang Samakan sumber data server dan client

Langkah Memperbaiki Error Hydration di App Router

  1. Reproduksi dengan production build. Jalankan build lalu start, jangan hanya mengandalkan mode dev.
  2. Baca diff server dan client. Console menunjukkan bagian HTML mana yang tidak cocok.
  3. Isolasi komponen tersangka. Komentari blok tanggal, random, auth, dan format locale satu per satu.
  4. Samakan render pertama. Tampilkan placeholder stabil, isi nilai browser setelah mount.
  5. Verifikasi ulang. Refresh tanpa cache, cek desktop dan mobile, lalu build ulang.
"use client";
import { useEffect, useState } from "react";

export default function JamClient() {
  const [jam, setJam] = useState("-");
  useEffect(() => {
    setJam(new Date().toLocaleTimeString("id-ID"));
  }, []);
  return <p>{jam}</p>;
}

Gunakan suppressHydrationWarning hanya untuk satu baris kecil seperti jam atau timezone yang memang sengaja berbeda. Jangan menutup seluruh halaman dengan atribut itu.

FAQ

Apakah suppressHydrationWarning menghapus penyebab error ini?

Tidak. Atribut itu hanya menahan peringatan untuk teks tersebut, selisih render tetap ada.

Kapan memakai useEffect untuk data jam atau localStorage?

Pakai saat nilai hanya valid di browser, render placeholder dulu lalu isi nilainya di useEffect.

Apakah use client memperbaiki semua hydration error?

Tidak. Client Component tetap di-render awal di server, jadi render pertamanya harus tetap sama.