Stop Build Gagal: Cara Mengatasi Document Is Not Defined Next Js dengan Cek Server

Error document is not defined muncul karena kode memanggil DOM padahal Next.js merender halaman di server. Perbaikannya bukan menambah "use client" sembarangan, melainkan memastikan baris document hanya jalan di browser lewat useEffect, event handler, atau dynamic import dengan ssr: false.

Penyebab Document Is Not Defined di App Router

App Router merender Server Component di server secara default. Objek document belum ada di sana, jadi satu baris saja cukup membuat build gagal.

  • Server Component membaca document.getElementById, document.querySelector, atau document.title langsung di body render.
  • Library pihak ketiga seperti editor teks, chart, date picker, atau modal mengakses DOM saat import atau render pertama.
  • Kode browser ditaruh di body komponen, padahal seharusnya menunggu mount lewat useEffect atau menunggu interaksi lewat event handler.

Tabel Diagnosis Cepat Berdasarkan Lokasi Error

Baca stack trace build, lalu cocokkan lokasinya sebelum mengubah kode.

Gejala Penyebab Solusi
Error menunjuk file page.tsx Server Component Akses document langsung saat prerender Pindah ke Client Component dan bungkus useEffect
Error menunjuk file dengan "use client" document dipanggil di body render Tambah guard typeof document atau pindah ke effect
Error menunjuk node_modules library UI Package butuh DOM saat SSR Import dengan dynamic(..., ssr: false)

Perbaiki Akses Document agar Hanya Jalan di Browser

Gunakan pola paling ringan dulu. Dynamic import hanya untuk library, bukan untuk satu baris document.

  1. Salin baris error dari log build dan cari pemanggilan document persisnya.
  2. Jika baris itu milik komponen sendiri, pindahkan komponen tersebut menjadi Client Component.
  3. Pindahkan pembacaan DOM ke useEffect, useLayoutEffect, atau handler seperti onClick.
  4. Jika penyebabnya library pihak ketiga, bungkus dengan dynamic import ssr: false.
  5. Jalankan ulang npm run build tanpa menghapus cache bila build sebelumnya belum terbukti korup.
"use client";
import { useEffect, useState } from "react";

export default function TitleReader() {
  const [title, setTitle] = useState("");

  useEffect(() => {
    if (typeof document !== "undefined") {
      setTitle(document.title);
    }
  }, []);

  return <p>Judul halaman: {title}</p>;
}
"use client";
import dynamic from "next/dynamic";

const Editor = dynamic(() => import("./Editor"), {
  ssr: false,
  loading: () => <p>Memuat editor...</p>,
});

export default function Page() {
  return <Editor />;
}

FAQ

Apakah use client otomatis memperbaiki error document?

Tidak. Direktif itu hanya mengizinkan browser API, pemanggilannya tetap harus menunggu mount atau interaksi.

Kapan memakai dynamic import dengan ssr false?

Pakai hanya ketika library memang membutuhkan DOM saat inisialisasi dan tidak punya mode SSR.

Kenapa error hanya muncul saat build padahal dev aman?

Mode dev kadang menunda prerender, sedangkan next build mengeksekusi semua route statis di server.