Error ini hilang setelah hook useRouter dipindah ke Client Component. Di App Router, page.js dan layout.js berjalan sebagai Server Component secara default, jadi pemanggilan useRouter() dari next/navigation langsung di sana pasti ditolak. Perbaikannya bukan menumpuk "use client" di page, melainkan mengisolasi tombol atau menu yang butuh navigasi ke komponen kecil.
Penyebab useRouter Only Works in Client Component Muncul
Next.js membedakan kode server dan kode browser. useRouter membaca history browser dan memicu navigasi client-side, sehingga hanya valid di Client Component.
useRouterdarinext/navigationmemakai state dan event browser.- Server Component tidak menyimpan state, tidak menerima
onClick, dan tidak mengakseswindow. - Pola yang memicu error:
import { useRouter } from "next/navigation"lalurouter.push()di dalampage.jstanpa batas client.
Tabel Diagnosis Cepat Berdasarkan Lokasi Kode
Periksa dulu kebutuhan navigasinya sebelum memilih pengganti.
| Masalah | Penyebab | Solusi |
|---|---|---|
| useRouter di page | Page masih Server Component | Pindah ke komponen tombol client |
| useRouter di layout | Layout ikut ter-render di server | Buat UserMenu client, kirim user via props |
| Hanya butuh redirect awal | Navigasi tidak butuh klik | Pakai redirect() di server |
| Hanya butuh path aktif | Salah pilih hook | Pakai usePathname() di komponen client |
Cara Memperbaiki dengan Batas Client yang Tepat
Biarkan page tetap server agar fetching dan metadata tetap efisien. Bungkus hanya bagian interaktifnya.
- Buat file baru khusus interaksi, misalnya
BackButton.jsatauUserMenu.js. - Tulis
"use client"di baris pertama file kecil tersebut. - Panggil
useRouter()hanya di dalam file itu, lalu sambungkan keonClick. - Kirim data dari server lewat props, jangan fetch ulang token atau data sensitif di client.
"use client";
import { useRouter } from "next/navigation";
export default function BackButton() {
const router = useRouter();
return <button onClick={() => router.back()}>Kembali</button>;
}
Untuk redirect server tanpa klik, pakai redirect("/login") dari next/navigation di Server Component atau baca header lewat headers() dari next/headers.
FAQ
Apakah cukup tambah use client di page?
Bisa menghilangkan error, tetapi page kehilangan keuntungan Server Component dan semua import ikut terkirim ke browser.
Apa pengganti useRouter untuk redirect di Server Component?
Gunakan redirect() dari next/navigation untuk navigasi server sebelum halaman dikirim.
Kapan pakai usePathname bukan useRouter?
Pakai usePathname() ketika hanya perlu membaca URL aktif untuk menu aktif atau breadcrumb.