K

Command Palette

Search for a command to run...

Daftar

Routing Dasar Next.js (App Router)

Pelajari bagaimana Next.js App Router secara ajaib membuat rute URL berdasarkan struktur folder dan file di direktori `app/` Anda. Pahami konvensi file spesial seperti `page.tsx` dan `layout.tsx`.

Bikin Halaman Baru di Next.js? Gampang Banget Pake App Router!

Udah berhasil nyalain proyek Next.js pertamamu? Keren! Sekarang, kamu pasti penasaran kan gimana caranya bikin halaman-halaman lain di websitemu, misalnya halaman "Tentang Kami", "Produk", atau "Kontak".

Di Next.js dengan App Router (yang jadi standar baru dan direkomendasiin), cara bikin rute (URL path) buat halaman-halaman itu super intuitif dan otomatis: yaitu pake File-System Routing (Routing Berbasis Sistem File). Artinya, struktur folder dan nama file di dalam direktori app/ (di dalam src/ kalau kamu pilih pake src/) itu yang bakal nentuin URL halamanmu!

Gak perlu lagi konfigurasi routing manual yang ribet di file terpisah.

Direktori app/: Jantung Routingmu

Semua yang berhubungan sama halaman dan layout di App Router itu tinggalnya di dalam folder app/.

  • Setiap folder di dalam app/ itu ngewakilin satu segmen URL.
  • Biar folder itu jadi rute yang bisa diakses publik, dia harus punya file page.tsx (atau page.jsx) di dalamnya.

Contoh Struktur Folder dan URL yang Dihasilkan:

bash
src/
└── app/
    ├── page.tsx         // Akan diakses di URL: / (halaman utama/root)
    ├── layout.tsx       // Layout utama buat semua halaman
    ├── about/
   └── page.tsx     // Akan diakses di URL: /about
    ├── products/
   ├── page.tsx     // Akan diakses di URL: /products
   └── [id]/        // Ini folder buat Rute Dinamis (dibahas nanti)
       └── page.tsx // Akan diakses di URL: /products/sepatu-keren, /products/123
    └── contact/
        └── page.tsx     // Akan diakses di URL: /contact

Simpel banget kan? Bikin folder, taro page.tsx di dalamnya, langsung jadi halaman baru!

File Spesial di App Router: page.tsx dan layout.tsx

Ada beberapa nama file yang punya makna khusus di App Router. Dua yang paling penting buat dipahami di awal adalah:

  1. page.tsx (atau page.js, page.jsx):

    • Ini adalah file yang WAJIB ADA di dalam folder rute biar rute itu bisa diakses publik dan punya UI.
    • Isinya adalah React Component (biasanya Functional Component) yang bakal nge-render antarmuka pengguna (UI) buat halaman/rute tersebut.
    • Secara default di App Router, komponen di page.tsx itu adalah Server Component. Artinya, dia di-render di server (atau pas build time) dan bisa langsung async/await buat ngambil data. Kalau butuh interaktivitas sisi klien (pake useState, useEffect, event listener), kamu perlu nambahin directive "use client"; di paling atas file-nya.

    Contoh src/app/about/page.tsx:

    tsx
    // src/app/about/page.tsx
    import React from 'react';
     
    export default function AboutPage() {
      return (
        <div>
          <h1>Tentang Kami</h1>
          <p>Mahir.dev adalah platform untuk belajar web development dengan cara yang asyik!</p>
        </div>
      );
    }

    Kalau kamu buka /about di browser, konten dari AboutPage ini yang bakal tampil.

  2. layout.tsx (atau layout.js, layout.jsx):

    • File ini juga WAJIB ADA di direktori app/ paling atas (root layout). Isinya adalah React Component yang jadi template atau "bungkus" UI bersama buat semua halaman di segmen rute itu dan anak-anaknya.
    • Biasanya, layout.tsx ini tempat kamu naro tag <html>, <head> (termasuk <title> default, <meta>, dll.), dan <body>.
    • Dia harus nerima prop children dan ngerender children itu di suatu tempat. children ini nanti bakal diisi sama konten dari page.tsx atau layout anak lainnya.
    • Layout itu sifatnya nested (bersarang). Artinya, layout di segmen rute yang lebih dalam bakal "dibungkus" sama layout dari segmen rute di atasnya.

    Contoh src/app/layout.tsx (Root Layout):

    tsx
    // src/app/layout.tsx
    import React from 'react';
    import './globals.css'; // Impor CSS global
     
    // export const metadata = { ... } // Metadata bisa didefinisiin di sini (dibahas nanti)
     
    export default function RootLayout({
      children, // Ini WAJIB ada buat nampilin konten page.tsx atau layout anak
    }: {
      children: React.ReactNode;
    }) {
      return (
        <html lang="id">
          <body>
            <header style={{ background: 'lightgray', padding: '1rem' }}>
              Ini Header Global dari Root Layout
            </nav>
            <main>
              {children} {/* Konten dari page.tsx bakal masuk sini */}
            </main>
            <footer style={{ background: 'lightgray', padding: '1rem', marginTop: '2rem' }}>
              Ini Footer Global dari Root Layout
            </footer>
          </body>
        </html>
      );
    }

    Semua halaman di aplikasimu bakal punya header dan footer dari RootLayout ini.

    Kamu juga bisa bikin layout.tsx di dalam sub-folder rute (misal, app/dashboard/layout.tsx) kalau mau segmen rute /dashboard/* punya layout khusus yang beda (tapi tetep dibungkus sama Root Layout).

Nested Routes (Rute Bersarang)

Bikin rute bersarang (kayak /dashboard/settings atau /blog/tahun/bulan/judul-artikel) itu gampang banget, tinggal bikin folder di dalam folder di direktori app/.

Contoh Struktur Nested Routes:

src/
└── app/
    ├── dashboard/
    │   ├── layout.tsx     // Layout khusus buat semua halaman /dashboard/*
    │   ├── page.tsx       // UI buat /dashboard
    │   └── settings/
    │       └── page.tsx   // UI buat /dashboard/settings
    └── layout.tsx         // Root Layout (ngebungkus semua)
    └── page.tsx           // UI buat / (Halaman Utama)
  • Halaman /dashboard/settings bakal ngerender page.tsx dari app/dashboard/settings/.
  • Layout yang diterapin ke /dashboard/settings adalah gabungan dari app/layout.tsx (paling luar) terus dibungkus sama app/dashboard/layout.tsx (lebih dalam).

Dynamic Routes (Rute Dinamis): Bikin Halaman dari Data

Seringkali, kita punya halaman yang polanya sama tapi kontennya beda-beda tergantung parameter di URL. Misalnya, halaman detail produk (/produk/sepatu-lari atau /produk/baju-keren), atau halaman detail postingan blog (/blog/judul-artikel-ini).

Buat ini, kita pake Dynamic Routes. Caranya adalah dengan ngasih nama folder (atau file kalau di Pages Router lama) pake kurung siku [].

  • Sintaks Folder Dinamis: [namaParameter]

    • Contoh: app/produk/[idProduk]/page.tsx
      • Ini bakal cocok sama URL kayak /produk/123, /produk/abc, /produk/sepatu-merah.
      • Nilai 123, abc, atau sepatu-merah itu bakal bisa kita ambil di dalam komponen page.tsx sebagai parameter.
  • Cara Ngambil Parameter Dinamis di Komponen Page: Komponen page.tsx di dalam folder rute dinamis bakal nerima prop params yang isinya objek dengan parameter dari URL.

    tsx
    // src/app/blog/[slug]/page.tsx 
    // (Misal URL-nya /blog/artikel-pertama-saya)
     
    import React from 'react';
     
    // Perhatikan tipe props 'params' di Next.js 15+ (App Router)
    // 'params' sekarang adalah sebuah Promise jika komponennya async,
    // atau objek biasa jika komponennya Client Component yang menggunakan hook use(params).
    // Untuk Server Component, kita buat async dan await params.
    export default async function BlogPostPage({ 
        params 
    }: { 
        params: Promise<{ slug: string }> // 'slug' harus sama kayak nama folder [slug]
    }) {
      const resolvedParams = await params; // Ambil nilai params
      const { slug } = resolvedParams;
     
      // Di sini kamu bisa fetch data blog post berdasarkan slug
      // Misalnya: const post = await getPostBySlug(slug);
     
      return (
        <div>
          <h1>Menampilkan Artikel: {slug}</h1>
          {/* Tampilkan konten artikel di sini */}
          <p>Ini adalah konten untuk artikel dengan slug "{slug}".</p>
        </div>
      );
    }

    PENTING (Next.js 15+ Update): Seperti yang kita bahas, akses ke params (dan searchParams) di Pages dan Layouts (Server Components) sekarang asynchronous. Jadi, komponen Page/Layout perlu jadi async dan kita perlu await props.params. Jika di Client Component, kita bisa menggunakan hook useParams() dari next/navigation atau use(props.params).

  • Catch-all Routes ([...namaParameter]): Kalau mau nangkep semua segmen URL setelah path tertentu (misal, /docs/.../semua/path/ini).

  • Optional Catch-all Routes ([[...namaParameter]]): Mirip catch-all, tapi segmennya opsional.

Dynamic Routes ini super powerful buat bikin website yang datanya banyak dan dinamis.

File-File Spesial Lainnya (Sekadar Tahu Dulu)

Selain page.tsx dan layout.tsx, App Router punya beberapa file spesial lain dengan konvensi nama tertentu:

  • loading.tsx: Komponen React yang bakal otomatis ditampilin sebagai UI placeholder (misal, spinner loading) pas konten page.tsx di segmen itu lagi di-load (terutama data fetching di Server Component).
  • error.tsx: Komponen React buat nanganin error yang terjadi di segmen rute itu. Dia bakal nangkep error dari page.tsx atau komponen anak, dan nampilin UI error yang lebih ramah. (Perlu "use client").
  • not-found.tsx: Komponen React yang bakal dirender kalau fungsi notFound() dipanggil di segmen rute itu, atau kalau rute gak ditemuin.
  • template.tsx: Mirip layout.tsx, tapi dia bakal nge-re-render instance baru setiap kali navigasi (state-nya gak dijaga). Layout ngejaga state.
  • default.tsx: Mirip page.tsx tapi untuk rute paralel (fitur advance).
  • route.ts (atau .js): Buat bikin API Endpoint (Route Handlers), bukan buat UI.

Kamu gak perlu langsung nguasain semua ini. page.tsx dan layout.tsx itu yang paling fundamental buat mulai.


File-System Routing di Next.js App Router ini bener-bener nyederhanain cara kita bikin halaman dan ngatur struktur URL. Gak ada lagi konfigurasi routing yang njelimet! Cukup atur folder dan kasih nama file yang bener, Next.js yang urus sisanya.

Ini bikin proses development jadi lebih cepet dan struktur proyek jadi lebih gampang dipahami. Di materi berikutnya, kita bakal liat gimana cara bikin link antar halaman ini pake komponen <Link> dan ngelakuin navigasi pake JavaScript.

Kuis Routing Dasar Next.js (App Router)

Pertanyaan 1 dari 5

Dalam Next.js App Router, bagaimana cara Anda membuat halaman baru yang akan dapat diakses melalui URL `/profil`?