Memindahkan Section Antar Halaman di Next.js App Router
Section UI tidak pernah pindah sendirian di App Router: jalur fetch, fallback, dan pembersihan jalur data mati harus ikut berpindah.
Ringkasan
Section hero lama dipindahkan ke halaman pariwisata. Data section tidak ikut pindah karena dilapari oleh fetch di halaman utama. Fetch dipindahkan ke halaman pariwisata untuk memperbaiki masalah.
Halaman utama portal KotaPortal semula menampilkan dua hero sekaligus: slider hero yang isinya dikelola lewat CMS, lalu di bawahnya satu section hero lama berisi badge, blok judul kota, karusel promo, dan deretan tautan cepat. Halaman pariwisata di /pariwisata hanya menampilkan slider-nya saja, lalu langsung breadcrumb dan daftar konten. Permintaan yang masuk singkat: pindahkan section hero lama itu ke halaman pariwisata, tepat di bawah slider halaman tersebut, tanpa mengubah desain.
Perbaikan pertamanya terlihat sepele: potong blok JSX section hero dari berkas halaman utama, tempel di berkas halaman pariwisata, simpan. Kode ter-compile, tidak ada error. Tapi begitu halaman dibuka, section hero tersebut tampil kosong: karusel promo tidak ada, blok judul memakai nilai default, deretan tautan cepat menghilang. JSX-nya sama, datanya tidak ikut pindah.
Menelusuri dari mana data section itu berasal
Di Next.js App Router, halaman adalah Server Component: kode berkas halaman berjalan di server dan bebas melakukan pengambilan data sebelum HTML dirender [2]. Artinya sebuah section yang tampil di halaman tidak pernah berdiri sendiri; ia dilapari oleh fetch yang ditulis di berkas halaman tempat ia dirender. Section hero lama tadi dilapari tiga fetch di berkas halaman utama: daftar promo dari getEntities dengan limit 3, pengaturan halaman dari getSettings("homepage") untuk isi badge dan judul, serta menu tautan cepat dari getMenus("related_links").
URL segmen mengikuti struktur folder: folder mendefinisikan segmen URL, dan menyarangkan folder berarti menyarangkan segmen [3]. Memindahkan section dari app/page.tsx (route /) ke app/pariwisata/page.tsx (route /pariwisata) berpindah antar dua route segment yang berbeda. Artinya bukan sekadar memindahkan tampilan; seluruh jalur data section tersebut harus ikut pindah.
Memindahkan fetch ke halaman tujuan
Tiga fetch tanda dipindahkan ke berkas halaman pariwisata, digabung dalam satu Promise.all yang sama dengan fetch lain halaman itu. Setiap fetch diberi .catch dengan nilai kosong sebagai fallback, supaya halaman tetap ter-render ketika salah satu endpoint sedang tidak sehat.
const [promoRaw, settingsRaw, menusRaw] = await Promise.all([
getEntities({ limit: 3 }).catch(() => []),
getSettings("homepage").catch(() => []),
getMenus("related_links").catch(() => []),
]);
Bentuk per-halaman seperti ini memang bentuk yang benar di App Router. Request fetch yang identik di dalam satu tree komponen React di-memoize per request, sehingga komponen yang membutuhkan data boleh melakukan fetch sendiri tanpa harus menerima props dari atas [1]. Konsekuensinya perlu diakui: memindahkan fetch berarti endpoint yang sama kini dipanggil dari dua halaman berbeda. Memoization tersebut hanya berlaku dalam satu render halaman, bukan lintas route. Halaman pariwisata juga harus siap menerima data kosong, karena fetch yang tidak di-cache akan menahan render halaman sampai selesai [1]; fallback .catch menjaga halaman tetap tampil ketika request gagal.
Menghapus jalur data mati di halaman asal
Setelah blok render pindah, berkas halaman utama menyisakan jalur data yang tidak lagi dipakai: state promoSlides, dua slot fetch di Promise.all, konstanta daftar tautan cepat statis beserta logika penggabungnya dengan menu related_links, serta import getMenus dan HeroSection yang tak terpakai. Tidak ada yang error karena sisa ini; halaman hanya diam-diam mengambil data yang tidak pernah dirender. Beban seperti ini tidak terlihat di review visual, hanya muncul kalau dibaca ulang kodenya.
Pembersihan sekaligus menjadi alat verifikasi pertama. Perintah npx tsc --noEmit selesai tanpa error dan menangkap import maupun variabel yang tertinggal. Terakhir, susunan kedua halaman diperiksa lewat screenshot headless: halaman utama kini menampilkan slider lalu langsung section Empat Pilar; halaman pariwisata menampilkan slider, section hero lama, baru breadcrumb dan konten.
Checklist memindahkan section antar halaman
Dari satu permintaan kecil itu, pola yang bisa dipakai ulang setiap kali sebuah section perlu pindah halaman di App Router:
- Pindahkan blok render ke berkas halaman tujuan, lalu pastikan route segment tujuan memang sesuai keinginan [3].
- Audit fetch yang melapari section tersebut dan pindahkan semuanya ke halaman tujuan, lengkap dengan fallback untuk tiap request [2].
- Hapus jalur data mati di halaman asal sampai
tscbersih, supaya tidak ada fetch tersisa yang hasilnya tidak pernah dirender. - Verifikasi kedua halaman: typecheck, test komponen yang terdampak, dan screenshot kedua route.
Section tidak pernah berpindah sendirian. Ia selalu menyeret jalur datanya, dan pekerjaan pemindahan yang baik diukur dari apa yang ikut pindah, bukan hanya dari blok kode yang berhasil ditempel.
Sources
[1] Next.js Documentation — Fetching Data: nextjs.org/docs/app/getting-started/fetching-data
[2] Next.js Documentation — Server and Client Components: nextjs.org/docs/app/building-your-application/rendering/composition-patterns
[3] Next.js Documentation — Project structure and organization: nextjs.org/docs/app/getting-started/project-structure