Bangun route /campaigns/[slug] sebagai halaman detail campaign yang membaca data published, memakai notFound untuk slug/draft, dan memberi CTA donasi yang benar.
35m bacaanKuis WajibMicro Badge Lesson
Halaman Detail Campaign
Homepage memberi daftar. Tapi sebelum donasi, pengunjung sering butuh membaca detail campaign: programnya apa, targetnya berapa, dan langkah berikutnya apa.
Di starter awal, route yang sudah ada adalah halaman donasi:
text
src/app/campaigns/[slug]/donate/page.tsx
Route detail belum ada:
text
src/app/campaigns/[slug]/page.tsx
Kita akan membuat route detail, tetapi dengan aturan penting: slug yang benar belum tentu boleh tampil. Campaign harus published. Draft tidak boleh dibaca publik walaupun slug-nya diketahui.
params di route ini berbentuk Promise, jadi di-await;
query memakai slug dan status;
.maybeSingle() cocok untuk slug yang mungkin tidak ada;
notFound() menyembunyikan detail internal. Slug salah dan campaign draft sama-sama 404.
Halaman detail harus mengikuti pola yang sama.
Buat route detail dengan scope sempit
File target:
text
src/app/campaigns/[slug]/page.tsx
Data yang perlu dipilih:
text
id, title, slug, summary, description, target_amount, status
Kenapa status tetap dipilih padahal query sudah filter published? Karena UI boleh menampilkan badge “Published” atau setidaknya kamu bisa memverifikasi data yang dirender memang dari state yang tepat.
Render minimal:
judul campaign;
summary;
description;
target Rupiah;
badge status published;
CTA ke /campaigns/{slug}/donate.
Jangan tambah cover image, progress terkumpul, share button, atau komentar di tahap ini. Itu bisa jadi fitur lain, tapi bukan tugas detail route pertama.
Prompt untuk Antigravity
text
Mulai dari AGENTS.md, DESIGN.md, dan docs/README.md.Tugas: buat halaman detail campaign baru.Baca:- src/app/campaigns/[slug]/donate/page.tsx- docs/project-rules.md- docs/data-contract.mdBuat file:- src/app/campaigns/[slug]/page.tsxRequirement:1. Gunakan Server Component.2. Ikuti pola params async seperti halaman donate.3. Query tabel campaigns berdasarkan slug dan status published.4. Gunakan .maybeSingle().5. Jika error atau data tidak ada, panggil notFound().6. Render title, summary, description, target_amount berformat Rupiah, status published, dan CTA "Donasi sekarang" ke /campaigns/{slug}/donate.7. Jangan mengubah homepage, donation form, server action donasi, migration, atau file auth.8. Jangan memakai data placeholder.Acceptance criteria:- /campaigns/paket-pangan-keluarga menampilkan detail campaign dari database.- /campaigns/slug-tidak-ada menghasilkan 404.- Draft campaign tidak tampil publik jika slug-nya diakses langsung.- CTA mengarah ke /campaigns/paket-pangan-keluarga/donate.- npm run lint dan npm run build berhasil.Laporkan file yang dibuat dan cara verifikasinya.
Perhatikan bagian “jangan memakai data placeholder”. Ini penting. Halaman yang terlihat bagus tapi memakai data statis adalah hasil yang salah.
Kalau kamu punya campaign draft di database, uji juga slug draft. Ia harus 404 di halaman publik.
Kenapa 404 untuk draft?
Mungkin kamu berpikir: kenapa tidak tampilkan pesan “campaign belum dipublish”?
Untuk halaman publik, 404 lebih aman. Ia tidak memberi tahu pengunjung bahwa ada draft internal dengan slug tertentu. Ini bukan keamanan besar seperti authorization admin, tapi kebiasaan baik: jangan bocorkan state internal yang tidak perlu.
Admin nanti boleh melihat draft lewat jalur admin. Publik tidak.
Prinsip yang perlu dibawa
Dynamic route bukan sekadar folder [slug]. Ia adalah kontrak antara URL, database, dan state.
Untuk halaman publik berbasis slug:
slug dipakai untuk mencari record;
state menentukan apakah record boleh tampil;
notFound() dipakai untuk state yang tidak boleh dibuka;
CTA harus membawa user ke langkah berikutnya yang benar.
Kalau agent membuat halaman yang tampil tapi tidak memfilter status, itu belum benar.
Checkpoint
src/app/campaigns/[slug]/page.tsx ada.
Query memakai slug dan status = published.
Data kosong/error memanggil notFound().
Detail campaign seed tampil dari database.
Slug salah menghasilkan 404.
CTA menuju /campaigns/{slug}/donate.
npm run lint dan npm run build berhasil.
Nah, detail campaign sekarang punya pagar yang lebih jelas: bukan cuma “slug ada”, tapi “slug ada dan layak tampil publik”. Pola ini nanti kepakai terus setiap kamu membuat halaman yang datanya punya status atau visibility.
Checkpoint KuisTarget: 70%
Kuis 03.2 — Halaman Detail Campaign
Kuis ini wajib untuk sertifikat. Kamu tetap bisa lanjut ke pelajaran berikutnya dan mengerjakannya nanti.