Next.js: Fullstack dalam Satu Proyek · 1/9
Routing dengan App Router
Folder adalah URL. Layout, page, segment dinamis, dan file-file dengan nama khusus.
Baca 30 menit
Setelah pelajaran ini kamu bisa
- Mengubah struktur folder jadi URL yang dihasilkannya
- Menyebutkan file-file khusus dan fungsi masing-masing
- Memakai segment dinamis dan membaca params-nya
- Menjelaskan apa yang dipertahankan layout tapi tidak oleh page
Di App Router, folder adalah URL. Sebuah folder jadi segment path, dan file bernama page.tsx di dalamnya membuat path itu bisa diakses. Tidak ada konfigurasi routing yang perlu ditulis.
app/
layout.tsx the root layout - wraps everything
[lang]/
layout.tsx wraps every route below it
page.tsx -> /en /id
dashboard/
page.tsx -> /en/dashboard
sign-in/
page.tsx -> /en/sign-in
modules/
[module]/
page.tsx -> /en/modules/react
[lesson]/
page.tsx -> /en/modules/react/state| File | Fungsinya |
|---|---|
page.tsx | Membuat route-nya bisa diakses publik. Tanpanya, foldernya bukan URL. |
layout.tsx | Membungkus route ini dan semua di bawahnya. Mempertahankan state-nya antar navigasi. |
loading.tsx | Ditampilkan saat segment ini memuat. Sebuah batas Suspense, ditulis untukmu. |
error.tsx | Menangkap error yang dilempar di segment ini. Harus berupa Client Component. |
not-found.tsx | Di-render oleh notFound(), atau untuk URL yang tidak cocok. |
route.ts | Sebuah endpoint HTTP alih-alih halaman. Tidak bisa berdampingan dengan page.tsx. |
template.tsx | Seperti layout, tapi mount ulang saat navigasi alih-alih bertahan. |
Segment dinamis
// app/[lang]/modules/[module]/[lesson]/page.tsx
export default async function LessonPage({
params,
}: PageProps<"/[lang]/modules/[module]/[lesson]">) {
// params is a PROMISE. This is the change that breaks old tutorials.
const { lang, module, lesson } = await params;
return <article>{lesson}</article>;
}params dan searchParams sekarang keduanya Promise. PageProps<"..."> adalah helper yang tersedia global untuk memberi type dari path route-nya — tidak perlu import.| Pola | Cocok dengan | params |
|---|---|---|
[id] | /venues/42 | { id: "42" } |
[...slug] | /docs/a/b/c | { slug: ["a","b","c"] } |
[[...slug]] | /docs dan /docs/a/b | opsional — bisa undefined |
(group) | tidak ada — ia tidak muncul di URL | hanya untuk berbagi layout |
Pencocokan route, diimplementasikan — termasuk aturan prioritas yang menentukan antara segment statis dan dinamis.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Navigasi
import Link from "next/link";
// Use Link, not <a>. It prefetches and navigates without a full page reload.
<Link href="/en/modules/react">React</Link>
// Programmatic navigation, from a Client Component:
"use client";
import { useRouter, usePathname } from "next/navigation";
const router = useRouter();
router.push("/en/dashboard"); // adds a history entry
router.replace("/en/sign-in"); // replaces it - good after a login
router.refresh(); // re-fetch server data, keep client state
// From a Server Component or Action, redirect() instead:
import { redirect } from "next/navigation";
redirect("/en/dashboard");redirect() bekerja dengan melempar error, jadi kode setelahnya tidak pernah jalan — itu sebabnya ia tidak butuh return.Tugas praktik
Di proyek ini, jalankan bun run build dan baca tabel route yang dicetaknya. Cocokkan setiap barisnya dengan folder di bawah app/. Identifikasi route mana yang ditandai ● (prerender) dan mana ƒ (dinamis), lalu jelaskan kenapa /[lang]/dashboard bersifat dinamis sementara /[lang]/modules/[module]/[lesson] tidak.
Hasil yang diharapkan
Dashboard-nya membaca cookie; halaman pelajarannya tidak.