Blog by Fadil Rumasoreng

Saya menulis tentang pengalaman saya membangun aplikasi, eksperimen teknologi, dan ide-ide seputar web development. Semua ini saya bagikan atau saya tulis murni dari pengalaman yang saya dapatkan ketika mengembangkan perangkat lunak.

Hydration di Next.js: Cara “Menghidupkan” Halaman Statis Menjadi Interaktif

CNFadil Rumasoreng· 19 Oct 2025· 0
Hydration di Next.js: Cara “Menghidupkan” Halaman Statis Menjadi Interaktif

Pelajari konsep hydration di Next.js, cara kerjanya, penerapannya di Server dan Client Components, serta best practice agar halaman React tetap sinkron antara server dan browser.


Sebuah Cerita Tentang Halaman yang “Mati”

Bayangkan kamu membuat halaman React yang cantik — tombolnya animatif, form-nya dinamis, dan semuanya tampak interaktif.
Kamu men-deploy website-mu menggunakan Next.js dengan SSR (Server-Side Rendering). Begitu dibuka, halaman langsung muncul dengan cepat.
Namun... tombolnya tidak bisa diklik, animasi tidak jalan, state hilang.

Di sinilah hydration mulai berperan.

Hydration adalah proses yang membuat halaman statis dari server menjadi “hidup” di browser.
Proses ini yang membuat React bisa mendeteksi state, menjalankan event handler, dan membuat UI benar-benar interaktif. Tanpa hydration, halaman Next.js hanyalah kumpulan HTML mati — seperti poster tanpa fungsi.


Apa Itu Hydration di Next.js?

Hydration adalah proses menggabungkan HTML statis hasil render server (SSR/SSG) dengan JavaScript React di client.
Tujuannya sederhana: membuat halaman yang awalnya statis menjadi interaktif di sisi browser.

Bayangkan alurnya seperti ini:

  1. Server merender React menjadi HTML murni dan mengirimkannya ke browser.

  2. Browser menampilkan HTML itu secepat mungkin (agar user melihat sesuatu duluan).

  3. Setelah JavaScript bundle React dimuat, React mencocokkan HTML yang sudah ada dengan virtual DOM miliknya.

  4. Begitu cocok, React “menghidupkan” event handler, state, dan efek — dan halaman pun aktif sepenuhnya.

Proses pencocokan ini disebut hydration karena secara metaforis, React “memberi nyawa” ke HTML yang tadinya kering.


Mengapa Hydration Penting di Next.js?

Next.js dibangun di atas dua dunia:

  • Server Components — komponen yang dijalankan di server.

  • Client Components — komponen yang dijalankan di browser.

Keduanya bekerja sama untuk membentuk halaman. Namun, hanya komponen client-lah yang bisa memiliki interaktivitas (seperti useState, onClick, useEffect, dsb).

Tanpa proses hydration:

  • HTML akan tampil, tapi interaksi tidak berfungsi.

  • Event seperti onClick tidak akan bereaksi.

  • State management (Redux, Zustand, Context API) tidak berjalan.

Dengan kata lain, hydration adalah jembatan antara render statis server dan dinamika React di browser.


Bagaimana Proses Hydration Terjadi?

Untuk memahaminya lebih dalam, mari lihat alur dasarnya:

  1. Render di Server (SSR / SSG)
    Server merender React menjadi HTML lengkap, beserta data awal (biasanya lewat props).

  2. HTML Dikirim ke Browser
    Browser menampilkan halaman lebih cepat karena hanya memproses HTML tanpa menunggu JavaScript.

  3. Bundle React Dimuat
    File JavaScript (client bundle) mulai diunduh.

  4. React Mencocokkan DOM
    React membaca struktur HTML yang sudah ada dan mencocokkannya dengan virtual DOM hasil render client.

  5. Hydration Selesai
    Setelah sinkron, React mengaktifkan semua event handler dan state. Kini halaman benar-benar “hidup”.

Jika HTML hasil render di server tidak sama dengan hasil render di client, React akan memberi peringatan:
“Hydration failed because the initial UI does not match what was rendered on the server.”


Contoh Kasus: Hydration pada Komponen Client

Misalnya kamu punya halaman seperti ini:

// app/page.tsx (Server Component)
import Counter from "./Counter";

export default function Page() {
  return (
    <div>
      <h1>Halaman Counter</h1>
      <Counter />
    </div>
  );
}

Dan komponen Counter:

// app/Counter.tsx (Client Component)
"use client";
import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      Klik Saya ({count})
    </button>
  );
}

Ketika halaman diakses:

  1. Server merender <button> dengan teks “Klik Saya (0)”.

  2. Browser menampilkan HTML statis itu duluan.

  3. Setelah JavaScript bundle dimuat, React melakukan hydration.

  4. Tombol baru bisa diklik — dan angka mulai bertambah.

Itulah momen di mana hydration membuat React bekerja penuh di browser.


Hydration untuk State Global (Zustand, Redux, Context, dll.)

Banyak developer menggunakan state management library seperti Zustand atau Redux. Namun, masalah muncul saat data berasal dari server (SSR) dan harus diteruskan ke client.

Karena state global hidup di memori browser, data dari server harus di-hydrate ke store agar konsisten di kedua sisi.

Berikut contoh umum pola hydrasi Zustand:

// Server Component
export default async function Page() {
  const user = await getUserFromServer(); // SSR fetch
  return <ClientPage user={user} />;
}

// Client Component
"use client";
import { useEffect } from "react";
import { useUserStore } from "@/store/user";

export default function ClientPage({ user }) {
  const setUser = useUserStore((s) => s.setUser);

  useEffect(() => {
    setUser(user); // Hydration ke store
  }, [user]);

  return <div>Halo, {user.name}!</div>;
}

Dalam pola ini:

  • Server mengambil data user.

  • Data dikirim ke Client Component melalui props.

  • Client “menyuntikkan” data itu ke global store.
    Hasilnya, user data tetap sinkron tanpa perlu re-fetch ulang di client.


Hydration vs Re-fetch: Mana yang Lebih Baik?

Sering kali developer bingung: lebih baik hydrate data atau fetch ulang di client?

Pendekatan

Deskripsi

Kelebihan

Kekurangan

Hydration

Data dari SSR dikirim langsung ke client

Cepat, tidak ada flicker/loading

Data bisa kadaluarsa

Re-fetch

Client memanggil API lagi setelah load

Data paling baru

Ada jeda loading, UX kurang mulus

Best practice: gunakan hydration untuk data penting yang sudah tersedia dari SSR, dan gunakan re-fetch hanya untuk data dinamis yang sangat cepat berubah.


Masalah Umum dalam Hydration

Hydration adalah proses sensitif — dan terkadang rewel. Berikut beberapa masalah klasik yang sering muncul:

Masalah

Penyebab

Solusi

Hydration mismatch

Hasil HTML dari server ≠ hasil render client

Pastikan render deterministik, hindari Math.random(), waktu, atau data tak terprediksi di client

Event tidak aktif

Komponen client tidak diberi "use client"

Tambahkan "use client" di file paling atas

Data tidak tersinkronisasi

Store tidak di-hydrate dengan data SSR

Oper data dari server via props lalu hydrate di client

Error re-render loop

useEffect menyebabkan setState tanpa kontrol

Gunakan dependency array dengan benar untuk mencegah loop


Hydration di Era Server Components

Next.js 13 memperkenalkan React Server Components (RSC) yang mengubah paradigma lama.

Dulu, semua komponen React dijalankan di client, lalu di-hydrate satu per satu. Sekarang, hanya komponen yang butuh interaktivitas yang di-hydrate.

Artinya:

  • Komponen statis (misalnya header, footer) bisa tetap di-render di server tanpa bundle JavaScript.

  • Komponen client hanya di-hydrate jika perlu event, efek, atau state.

Ini membuat ukuran JavaScript di client jauh lebih kecil — meningkatkan performa sekaligus efisiensi.


Bagaimana Menghindari Hydration Mismatch

Hydration mismatch sering menjadi “mimpi buruk” pemula Next.js. Peringatan ini biasanya muncul karena HTML server dan hasil render client berbeda.
Beberapa penyebab umum:

  1. Kode yang bergantung pada waktu atau browser API.

    <p>{new Date().toLocaleTimeString()}</p>
    

    Waktu di server bisa beda dengan di client → mismatch.
    Solusi: jalankan di client-only menggunakan "use client" dan useEffect.

  2. Penggunaan random number di SSR.

    <p>ID: {Math.random()}</p>
    

    Solusi: hindari Math.random() di server render.

  3. Perbedaan kondisi lingkungan.
    Misal: environment variable, cookie, atau localStorage hanya tersedia di client.

    Gunakan conditional render:

    if (typeof window === "undefined") return null;
    

Best Practice untuk Hydration di Next.js

  1. Pisahkan Server dan Client Components dengan jelas.
    Jangan menambahkan "use client" di seluruh halaman jika hanya sebagian kecil yang interaktif.

  2. Hydrate hanya data penting.
    Hindari membawa seluruh dataset besar dari SSR ke client tanpa alasan kuat.

  3. Gunakan caching dan revalidate dengan bijak.
    Untuk data semi-statis, gunakan fetch(..., { next: { revalidate: 10 } }).

  4. Pastikan render deterministik.
    Semua komponen harus menghasilkan output yang sama di server dan client sebelum hydration.

  5. Uji di Production Mode.
    Mode development sering tidak menunjukkan mismatch yang muncul di production.


Contoh Kasus Lengkap: Hydration Data User

Misalnya kamu punya halaman profil user yang diambil lewat SSR. Kamu ingin agar data itu tetap sinkron di store client tanpa fetch ulang.

// app/profile/page.tsx (Server Component)
import ProfileClient from "./ProfileClient";

export default async function ProfilePage() {
  const user = await getUserFromDatabase();
  return <ProfileClient user={user} />;
}
// app/profile/ProfileClient.tsx (Client Component)
"use client";
import { useEffect } from "react";
import { useUserStore } from "@/store/user";

export default function ProfileClient({ user }) {
  const { setUser, user: currentUser } = useUserStore();

  useEffect(() => {
    if (!currentUser) setUser(user);
  }, [user]);

  return (
    <section>
      <h1>Profil {user.name}</h1>
      <p>Email: {user.email}</p>
    </section>
  );
}

Hasilnya:

  • Server menyiapkan data user.

  • Client langsung punya data tanpa loading ulang.

  • Global state ter-hydrate dengan data yang sama.


FAQ

1. Apa bedanya hydration dan rehydration?
Secara teknis sama. Istilah “rehydration” sering digunakan untuk menggambarkan proses React menyambungkan kembali HTML statis dengan JavaScript di client.

2. Apakah semua halaman di Next.js perlu hydration?
Tidak. Hanya halaman dengan komponen client ("use client") yang membutuhkan proses hydration.

3. Bagaimana cara mendeteksi hydration mismatch?
Buka DevTools Console, perhatikan peringatan:
Warning: Text content did not match. Server: "A" Client: "B"

4. Apakah hydration memperlambat load?
Sebaliknya — hydration membuat HTML tampil lebih cepat (karena SSR), lalu membuatnya interaktif setelah JavaScript dimuat.

5. Apakah ada alternatif tanpa hydration?
Jika aplikasimu sepenuhnya statis atau murni server-rendered tanpa interaktivitas, kamu tidak butuh hydration sama sekali.


Kesimpulan

Hydration adalah jantung dari pengalaman React modern — terutama di framework seperti Next.js.
Tanpanya, halaman yang tampak sempurna dari server hanyalah tampilan statis tanpa interaksi.

Dengan memahami bagaimana hydration bekerja, bagaimana cara menghindari mismatch, serta bagaimana menyalurkan data SSR ke store client, kamu bisa membangun aplikasi yang cepat sekaligus interaktif dengan cara yang efisien.

Ingat rumus sederhana ini:

SSR memberi struktur, hydration memberi nyawa.

Komentar

Belum ada komentar.