Episode ini mengupas routing di App Router: file page dan layout, dynamic routes, catch-all routes, optional catch-all, komponen Link dan useRouter untuk navigasi, serta metadata API untuk SEO dan deskripsi halaman.

Setelah project kalian berdiri di episode 3, waktunya memberi aplikasi lebih dari satu halaman. Routing menentukan bagaimana URL memetakan ke kode, dan navigation menentukan bagaimana pengguna berpindah antar halaman.
Episode 4 mengupas sistem routing App Router: konsep segment, file page.tsx dan layout.tsx, dynamic routes dengan parameter, catch-all routes yang menangkap banyak segment, komponen Link untuk navigasi client-side, serta metadata API untuk SEO.
Setiap folder di dalam app adalah segment yang berkorespondensi dengan bagian URL. Folder app/about/page.tsx otomatis menjadi halaman /about, tanpa perlu registrasi router manual. Ini pola routing berbasis filesystem yang membuat struktur aplikasi langsung terlihat dari folder.
Layout adalah kerangka yang dipakai bersama. Layout di folder app/blog membungkus semua halaman di bawahnya:
export default function BlogLayout({ children }) {
return (
<section>
<nav>Navigasi Blog</nav>
{children}
</section>
)
}File di atas adalah app/blog/layout.tsx. Konten children diisi halaman aktif — jadi navbar blog muncul di semua halaman blog tanpa ditulis ulang.
Untuk halaman yang bergantung pada nilai dinamis seperti slug artikel, buat folder dengan kurung siku. File app/blog/[slug]/page.tsx menerima params berisi slug:
export default async function BlogPost({ params }) {
const { slug } = await params
return (
<article>
<h1>Artikel dengan slug: {slug}</h1>
</article>
)
}await params di atas wajib di Next.js 15 karena params menjadi Promise. Saat kalian membuka /blog/pengenalan-react, nilai slug adalah pengenalan-react.
Jika satu halaman harus menangani sejumlah segment berapa pun, gunakan catch-all dengan tiga titik. Folder app/docs/[...slug]/page.tsx menangkap URL seperti /docs/getting-started/intro. Untuk menangkap juga /docs tanpa segment, pakai optional catch-all: folder app/docs/[[...slug]]/page.tsx. Perbedaannya hanya pada kurung siku tambahan di sekeliling parameter.
Untuk halaman dinamis yang memakai SSG, daftarkan semua nilai parameter saat build:
export async function generateStaticParams() {
return [
{ slug: "pengenalan-react" },
{ slug: "panduan-nextjs" },
]
}Fungsi generateStaticParams mengembalikan daftar parameter yang akan di-prerender saat npm run build. Detail lengkapnya kita bahas di episode 6.
Untuk berpindah halaman tanpa memuat ulang seluruh dokumen, gunakan komponen Link. Import dari next/link dan gunakan prop href:
import Link from "next/link"
export default function Navbar() {
return (
<nav>
<Link href="/">Beranda</Link>
<Link href="/blog">Blog</Link>
<Link href="/blog/pengenalan-react">Artikel</Link>
</nav>
)
}Link memicu prefetching: Next.js memuat halaman tujuan lebih dulu ketika link terlihat di viewport, sehingga navigasi terasa instan. Saat pengguna klik, transisi terjadi tanpa reload penuh.
Untuk navigasi yang dipicu dari kode — misalnya setelah form dikirim — gunakan hook useRouter:
"use client"
import { useRouter } from "next/navigation"
export default function LoginButton() {
const router = useRouter()
return (
<button onClick={() => router.push("/dashboard")}>
Masuk Dashboard
</button>
)
}router.push("/dashboard") mengarahkan pengguna secara terprogram. Perhatikan direktif "use client" di baris pertama — hook seperti useRouter hanya berjalan di komponen klien, konsep yang akan kita bedah di episode 7.
App Router menyediakan metadata API untuk mengontrol judul, deskripsi, dan tag meta setiap halaman. Ekspor objek metadata dari layout.tsx atau page.tsx:
import type { Metadata } from "next"
export const metadata: Metadata = {
title: "Beranda | Aplikasi Saya",
description: "Halaman beranda aplikasi Next.js",
openGraph: {
title: "Aplikasi Saya",
description: "Halaman beranda aplikasi Next.js",
},
}Objek metadata di atas menghasilkan tag title dan description untuk SEO serta tag Open Graph untuk media sosial. Untuk halaman dinamis, fungsi generateMetadata bisa menghasilkan metadata berdasarkan params — topik lanjut di episode 17.
Inti yang harus dibawa pulang:
generateStaticParams menetapkan daftar parameter untuk SSG.Link menyediakan navigasi client-side dengan prefetching.useRouter menangani navigasi terprogram dari kode.Di episode 5 selanjutnya kita akan membahas komponen dan layouts — komponen reusable, nested layouts dan template, shared layout untuk segment dinamis, loading UI dengan file loading, serta styling dengan CSS modules, Tailwind CSS, dan styled-components. Struktur UI aplikasi kalian mulai matang.