Bikin halaman spesifik untuk tiap kue! Pelajari cara membuat dynamic route di Next.js App Router (misal, `/kue/[id]`), mengambil parameter ID, dan fetch data detail produk dari API.
17m bacaanKuis WajibMicro Badge Lesson
Tiap Kue Punya Cerita: Bikin Halaman Detail Produk Pake Dynamic Route!
Udah bisa nampilin semua kue enak kita di halaman utama? Keren! Sekarang, gimana caranya biar pas salah satu kartu kue diklik, kita bisa pindah ke halaman baru yang nampilin info lebih lengkap soal kue itu aja? Misalnya, deskripsi panjangnya, bahan-bahannya, mungkin gambar yang lebih gede.
Buat ini, kita perlu bikin Dynamic Route (Rute Dinamis). Artinya, kita bikin satu "template" halaman, tapi kontennya bisa berubah-ubah tergantung parameter yang ada di URL. Misalnya, /kue/kue-coklat-klasik-01 bakal nampilin detail kue coklat, sementara /kue/red-velvet-cupcake-04 bakal nampilin detail red velvet.
Langkah 1: Membuat Struktur Folder Dynamic Route
Di Next.js App Router, dynamic route dibuat dengan ngasih nama folder pake kurung siku [] yang diisi sama nama parameternya.
Di dalam folder src/app/, bikin folder baru namanya kue.
Di dalam folder src/app/kue/, bikin lagi folder baru yang namanya [idKue] (atau [slug], [productId], bebas, tapi sesuai sama properti di data kue kita).
Strukturnya jadi:
[idKue]
id
src/app/kue/[idKue]/
Nama idKue di dalam kurung siku itu yang bakal jadi nama parameter dinamis kita.
Langkah 2: Membuat Komponen Halaman Detail (page.tsx)
Sekarang, di dalam folder src/app/kue/[idKue]/, bikin file baru bernama page.tsx. Ini yang bakal jadi komponen buat nampilin UI halaman detail produk.
File src/app/kue/[idKue]/page.tsx:
tsx
// src/app/kue/[idKue]/page.tsximport React from 'react';import Image from 'next/image';import Link from 'next/link';import { Kue } from '@/types/kue'; // Impor tipe Kue// import tombol-tambah-keranjang from '@/components/tombol-tambah-keranjang'; // Akan kita buat nanti// Tipe untuk props yang diterima halaman ini (termasuk params dinamis)interface DetailKuePageProps { params: { idKue: string; // 'idKue' harus sama dengan nama folder dinamis '[idKue]'
Bedah src/app/kue/[idKue]/page.tsx:
interface DetailKuePageProps: Kita definisiin tipe buat props yang diterima halaman ini. Properti params itu objek yang isinya parameter dinamis dari URL. Nama properti di dalam params (idKue) harus sama persis sama nama folder dinamis kita ([idKue]).
async function getDetailKue(id: string): Promise<Kue | null>:
Fungsi async baru buat ngambil data satu kue spesifik dari API endpoint /api/kue/${id}.
Dia nerima id kue sebagai string.
Dia ngembaliin Promise<Kue | null>, artinya bisa objek Kue kalau ketemu, atau null kalau gak ketemu (misal, ID-nya salah).
Ada penanganan kalau response.status === 404.
export default async function HalamanDetailKue({ params }: DetailKuePageProps):
Komponen Page kita jadi async function lagi.
Dia nerima params dari props. Kita ambil idKue dari params.idKue.
PENTING SOAL params di Next.js 15+: Seperti disinggung di catatan kode, di versi terbaru Next.js, params (dan searchParams) yang diterima oleh Server Component bisa berupa Promise. Untuk contoh ini, kita asumsikan Next.js sudah me-resolve-nya. Jika saat dijalankan ada error terkait promise, maka params perlu di-await dulu: const resolvedParams = await params; const idKue = resolvedParams.idKue;. Namun, untuk kasus akses langsung di props komponen Page seperti ini, Next.js seringkali sudah menanganinya.
const kue = await getDetailKue(idKue);: Kita panggil fungsi fetch data dengan ID yang didapet.
Penanganan Kue Tidak Ditemukan:
Kalau getDetailKue ngembaliin null (artinya kuenya gak ada), kita nampilin pesan "Kue Tidak Ditemukan" dan link buat balik.
Alternatifnya, kita bisa manggil fungsi notFound() dari next/navigation yang bakal otomatis ngerender file not-found.tsx standar kita (kalau ada).
Tampilan Detail Produk:
Kalau data kuenya ada, kita tampilin semua informasinya: gambar (pake <Image> lagi, dan priority karena ini gambar utama), nama, kategori, harga, deskripsi lengkap, bahan utama (kalau ada, dirender pake .map()), rating (kalau ada).
Tombol "Tambah ke Keranjang" masih placeholder, nanti kita bikin jadi komponen interaktif (Client Component) yang bisa ngelola state keranjang.
Langkah 3: Update Link di Kartu Produk
Sekarang, kita perlu update komponen kartu-kue.tsx kita biar nge-link ke halaman detail yang bener.
File src/components/kartu-kue.tsx (Bagian <Link>-nya aja yang diubah):
tsx
// ... (import dan interface props sama) ...export default function KartuKue({ kue }: KartuKueProps) { return ( // Pastikan href-nya bener ke /kue/[idKue] <Link href={`/kue/${kue.id}`} className="block group ..."> {/* ... sisa kode KartuKue sama ... */} </Link> );}
Ubah href di <Link> jadi {\`/kue/${kue.id}\`}.
Jalankan dan Tes!
Pastikan dev server (npm run dev) jalan.
Buka halaman utama (http://localhost:3000) yang nampilin daftar kue.
Klik salah satu kartu kue.
Harusnya kamu sekarang dibawa ke halaman detail kue itu, dan URL di browser bakal jadi kayak http://localhost:3000/kue/kue-coklat-klasik-01 (atau ID kue lain yang kamu klik).
Coba juga masukin URL dengan ID kue yang gak ada, misal /kue/id-salah, harusnya kamu liat pesan "Kue Tidak Ditemukan".
Keren! Kamu udah berhasil bikin halaman yang kontennya dinamis tergantung URL, dan ngambil datanya dari API pake Server Component di Next.js. Ini adalah pola yang sangat umum dan powerful.
Di bagian studi kasus berikutnya, kita bakal mulai nambahin interaktivitas: bikin fungsi keranjang belanja pake state, context (mungkin), dan localStorage!
Checkpoint KuisTarget: 70%
Kuis Halaman Detail Produk Toko Kue (Next.js+TS)
Kuis ini wajib untuk sertifikat. Kamu tetap bisa lanjut ke pelajaran berikutnya dan mengerjakannya nanti.