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
(ataupage.jsx
) di dalamnya.
Contoh Struktur Folder dan URL yang Dihasilkan:
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:
-
page.tsx
(ataupage.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 langsungasync/await
buat ngambil data. Kalau butuh interaktivitas sisi klien (pakeuseState
,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 dariAboutPage
ini yang bakal tampil. -
layout.tsx
(ataulayout.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 ngerenderchildren
itu di suatu tempat.children
ini nanti bakal diisi sama konten daripage.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). - File ini juga WAJIB ADA di direktori
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 ngerenderpage.tsx
dariapp/dashboard/settings/
. - Layout yang diterapin ke
/dashboard/settings
adalah gabungan dariapp/layout.tsx
(paling luar) terus dibungkus samaapp/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
, atausepatu-merah
itu bakal bisa kita ambil di dalam komponenpage.tsx
sebagai parameter.
- Ini bakal cocok sama URL kayak
- Contoh:
-
Cara Ngambil Parameter Dinamis di Komponen Page: Komponen
page.tsx
di dalam folder rute dinamis bakal nerima propparams
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
(dansearchParams
) di Pages dan Layouts (Server Components) sekarang asynchronous. Jadi, komponen Page/Layout perlu jadiasync
dan kita perluawait props.params
. Jika di Client Component, kita bisa menggunakan hookuseParams()
darinext/navigation
atauuse(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 kontenpage.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 daripage.tsx
atau komponen anak, dan nampilin UI error yang lebih ramah. (Perlu"use client"
).not-found.tsx
: Komponen React yang bakal dirender kalau fungsinotFound()
dipanggil di segmen rute itu, atau kalau rute gak ditemuin.template.tsx
: Miriplayout.tsx
, tapi dia bakal nge-re-render instance baru setiap kali navigasi (state-nya gak dijaga). Layout ngejaga state.default.tsx
: Mirippage.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`?