Tandai Menu Sedang Dibuka dengan Cara Membuat Link Active Next Js

Cara membuat link active Next.js paling tepat adalah membaca pathname lewat usePathname dari next/navigation di Client Component khusus navigasi. Layout dan halaman tetap Server Component, hanya navbar yang memakai use client. Pola ini mencegah seluruh layout ikut menjadi client.

Pola Link Active yang Benar di App Router

App Router memisahkan rendering server dan browser. Link biasa bisa dirender dari Server Component, tetapi pengecekan menu aktif butuh pathname saat ini.

  • Gunakan Server Component untuk layout.tsx dan konten halaman.
  • Buat Client Component kecil bernama NavLinks khusus menu.
  • Ambil rute dengan usePathname() dari next/navigation.
  • Jangan pakai useRouter gaya Pages Router untuk kebutuhan ini.
  • Gunakan pencocokan exact untuk /, startsWith untuk segmen induk.

Langkah Membuat Navbar dengan Link Aktif

1. Buat array berisi href dan label, misalnya /, /tentang, /blog.

2. Buat file NavLinks.tsx dengan use client di baris pertama.

3. Panggil const pathname = usePathname() di dalam komponen tersebut.

4. Bandingkan setiap href dengan pathname untuk menentukan class aktif seperti text-blue-600 font-semibold.

5. Render Link dari next/link dengan class kondisional, lalu pasang NavLinks di layout.tsx.

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";

const menus = [
  { href: "/", label: "Beranda" },
  { href: "/blog", label: "Blog" },
];

function isActive(pathname: string, href: string) {
  if (href === "/") return pathname === "/";
  return pathname === href || pathname.startsWith(href + "/");
}

export default function NavLinks() {
  const pathname = usePathname();
  return (
    <nav>
      {menus.map((m) => (
        <Link
          key={m.href}
          href={m.href}
          className={isActive(pathname, m.href) ? "active" : ""}
        >
          {m.label}
        </Link>
      ))}
    </nav>
  );
}

Perbandingan Pencocokan Pathname

Masalah Penyebab Solusi
Semua menu aktif di Home /tentang dianggap cocok Pakai exact untuk /
/blog/slug tidak aktif Hanya cek sama persis Pakai startsWith("/blog/")
Trailing slash tidak cocok /blog/ beda string Normalisasi slash akhir
  • Rute / hanya aktif bila pathname persis /.
  • Rute /blog aktif untuk /blog dan /blog/slug-pertama.
  • Rute /dashboard aktif untuk /dashboard, /dashboard/settings, dan subrute lain.

FAQ

Apakah usePathname bisa dipakai di Server Component?

Tidak. Bungkus menu dalam Client Component tersendiri, biarkan layout tetap server.

Bagaimana handle dynamic route seperti /produk/[id]?

Cek dengan startsWith("/produk/") agar semua ID produk tetap menyalakan menu Produk.

Kenapa active state tidak update saat pindah halaman?

Komponen membaca pathname dari props lama atau state basi, panggil usePathname() langsung di komponen menu.