Cara Membuat Optional Catch All Route Next Js untuk URL Satu dan Banyak Segmen

Buat folder bernama [[…slug]] di dalam App Router agar satu file page.tsx menangani URL tanpa segmen, satu segmen, dan banyak segmen. Kesalahan yang paling sering terjadi adalah memakai […slug] lalu bingung kenapa /docs menampilkan 404. Pola tanpa kurung ganda wajib punya minimal satu segmen.

Bedanya Catch All dan Optional Catch All di App Router

Next.js menyediakan dua pola untuk URL dinamis bertingkat. […slug] hanya cocok untuk URL yang sudah pasti punya isi. [[…slug]] menambahkan kemampuan menangkap induknya sendiri.

  • […slug] pada /docs/[…slug] menolak /docs dan hanya menerima /docs/a atau /docs/a/b.
  • [[…slug]] pada /docs/[[…slug]] menerima /docs, /docs/a, dan /docs/a/b dalam satu page.
  • params.slug selalu berupa array string. Pada optional catch all, nilainya undefined saat pengguna membuka URL induk.
  • Pakai pola opsional untuk dokumentasi, kategori bertingkat, atau halaman bantuan dengan struktur tidak tetap.

Langkah Membuat Folder [[…slug]] Sampai Page Terbaca

Struktur ini memakai Server Component bawaan App Router, jadi tidak perlu use client atau useParams.

  1. Buat folder app/docs/[[…slug]]/page.tsx. Nama kurung ganda wajib tepat.
  2. Baca params.slug dengan nilai default array kosong untuk menghindari error saat undefined.
  3. Buat percabangan render untuk nol segmen, satu segmen, dan lebih dari satu segmen.
  4. Buka /docs, /docs/a, lalu /docs/a/b dan pastikan ketiganya me-render page yang sama dengan konten berbeda.

Contoh Kode Page dan Tabel Pola URL

type Props = {
  params: { slug?: string[] };
};

export default function DocsPage({ params }: Props) {
  const slug = params.slug ?? [];

  if (slug.length === 0) {
    return <h1>Dokumentasi utama</h1>;
  }

  if (slug.length === 1) {
    return <h1>Topik: {slug[0]}</h1>;
  }

  return <h1>Jalur: {slug.join(" / ")}</h1>;
}
URL Nilai slug Hasil render
/docs undefined Halaman induk
/docs/a [“a”] Satu topik
/docs/a/b [“a”, “b”] Jalur bertingkat
  • Nama folder harus [[…slug]], bukan […slug] atau [slug].
  • Normalisasi params.slug ke array kosong sebelum memanggil length, map, atau join.
  • Jangan menaruh file page.tsx statis di /docs/page.tsx bersamaan tanpa rencana, karena route statis mendapat prioritas lebih tinggi.

FAQ

Apakah [[…slug]] bisa menangani / tanpa segmen?

Ya, slug bernilai undefined lalu tampilkan halaman induk.

Kapan optional catch all tidak cocok?

Bila hanya satu level ID, pakai [id] agar route lebih tegas.

Kenapa route statis tidak terpanggil?

Karena ada folder statis dengan nama sama yang prioritasnya lebih tinggi.