Next.js 15 memperkenalkan App Router yang menyederhanakan routing dan layout dalam aplikasi React modern. Artikel ini akan menjelaskan konsep utama, struktur file, data fetching, perbandingan dengan Pages Router, serta contoh langkah demi langkah untuk membuat halaman dasar hingga deployment.
Mengapa App Router Penting untuk Aplikasi Modern?
App Router memecahkan tiga masalah nyata: komposisi layout yang konsisten, nested routing yang ekspresif, serta pemisahan jelas antara server components dan client components. Bayangkan struktur halaman seperti bangunan bertingkat: setiap lantai bisa punya tata letak sendiri tanpa menyalin kode; itu yang dilakukan App Router secara native. Pendekatannya mengurangi boilerplate dan memudahkan cache serta streaming pada level komponen.
Dibandingkan dengan Pages Router, App Router unggul pada nesting layout, model data fetching yang lebih deklaratif, dan dukungan penuh untuk React Server Components (RSC), sehingga rendering awal lebih efisien. Namun, Pages Router masih ringkas untuk situs sederhana dan punya ekosistem plugin yang matang.
💻 Mulai Belajar Pemrograman
Belajar pemrograman di Dicoding Academy dan mulai perjalanan Anda sebagai developer profesional.
Daftar SekarangDashboard multi-level dengan sidebar dan tab, situs content-heavy yang butuh partial rendering, atau e‑commerce dengan dynamic routes untuk produk yang memiliki banyak varian; semua ini lebih mudah ditangani oleh App Router.
Trade-off: kurva belajar lebih curam, beberapa library pihak ketiga butuh adaptasi, dan migrasi incremental sering kali paling praktis. Contoh struktur minimal:
|
1 2 3 4 5 6 7 8 9 10 11 |
// app/layout.tsx export default function RootLayout({ children }) { return <html><body>{children}</body></html>; } // app/dashboard/page.tsx (server component) export default async function Page() { const res = await fetch('https://api.example.com/stats'); const data = await res.json(); return <div>{JSON.stringify(data)}</div>; } |
Memahami Arsitektur App Router di Next.js 15 untuk Pemula
App Router mengandalkan folder-based routing dan prinsip convention over configuration: struktur folder membentuk URL, sementara segments memungkinkan layout dan loading terpisah per bagian aplikasi. Cara ini menyederhanakan pemetaan rute dan memudahkan komposisi layout secara deklaratif.
Beberapa file kunci mengendalikan perilaku global dan lokal: app/layout.tsx menyediakan kerangka HTML dan shared UI, app/page.tsx adalah entry point untuk setiap rute, app/loading.tsx ditampilkan selama data RSC dimuat, dan app/error.tsx menangani exception serta reset UI.
|
1 2 3 4 5 6 7 8 |
src/app/ layout.tsx page.tsx loading.tsx error.tsx dashboard/ layout.tsx page.tsx |
Contoh minimal:
|
1 2 3 4 5 6 |
// app/layout.tsx export default function RootLayout({ children }: { children: React.ReactNode }) { return (<html><body>{children}</body></html>); } // app/page.tsx export default function Home(){ return <main>Halo</main> } |
request → RSC rendering → client component hydration → navigation
Alur ini menjelaskan kenapa sebagian besar data fetching tetap di server sementara interaktivitas di-handle oleh client component; pemahaman ini penting untuk memilih strategi caching dan deployment yang optimal.
Instalasi, Struktur Folder, dan File Kunci App Router
Mulai dengan memasang Node.js versi LTS (misal delapan belas atau dua puluh) lalu buat proyek baru dengan
|
1 |
npx create-next-app@latest my-app --experimental-app |
atau pilihan paket manager setara; di package.json pastikan skrip standar:
|
1 2 3 |
{ "dev": "next dev", "build": "next build", "start": "next start" } . |
Dalam akar proyek buat folder app/ dan tiga file dasar: layout.tsx untuk struktur global dan Provider, page.tsx untuk konten setiap route, serta head.tsx untuk metadata. Layout adalah tempat ideal menempatkan Theme atau Auth Provider sehingga state dan styling konsisten antarhalaman.
Contoh sederhana (server components):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* app/layout.tsx */ export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {/* Theme/Auth providers */} {children} ); } /* app/page.tsx */ export default function Page() { return Halo dari App Router; } /* app/head.tsx */ export default function Head() { return ; } |
Untuk migrasi dari Pages Router, pindahkan route satu per satu, pakai rewrites sementara di next.config.js agar URL tidak berubah, dan lakukan testing incremental.
Checklist deployment: tetapkan versi Node.js di platform, konfigurasikan variabel lingkungan, jalankan next build, dan verifikasi route serta data fetching sebelum mengarahkan traffic produksi.
Routing Dinamis, Segments, dan Layout dengan React Server Components
[id] menangkap satu segmen dinamis, sedangkan [[…slug]] adalah optional catch‑all yang cocok untuk nol atau lebih segmen; pola ini berjalan di atas folder‑based App Router sehingga setiap nama folder menjadi satu segment dalam pohon routing. Segments bertindak seperti pintu dalam rumah: setiap pintu bisa punya layout sendiri yang mewarisi atau menimpa elemen tata letak tingkat atas sehingga navigasi terasa konsisten dan modular.
Contoh struktur sederhana dan layout nested:
|
1 2 3 4 5 6 7 8 9 10 11 |
app/ layout.tsx dashboard/ layout.tsx settings/ page.tsx posts/ [id]/ page.tsx loading.tsx error.tsx |
Perbedaan utama: Server Components default di App Router dan ideal untuk akses data langsung, tanpa bundle browser; Client Components (pakai “use client”) diperlukan untuk interaktivitas, state, dan hooks seperti useState. Pilih server untuk performance dan security, klien hanya bila butuh event handlers atau DOM APIs.
Polanya: proteksi route bisa dilakukan di layout.tsx atau middleware dengan redirect server‑side; gunakan loading.tsx untuk skeleton pada setiap segment dan error.tsx sebagai boundary yang menampilkan fallback spesifik segment. Praktik ini memudahkan migrasi dan menyiapkan transisi ke bagian tentang data fetching berikutnya.
Data Fetching, Rendering Modes SSR SSG ISR, dan Edge Functions
Di App Router ada tiga pola utama untuk mengambil data: panggil fetch langsung di Server Components, gunakan hooks seperti useEffect atau SWR di Client Components, atau manfaatkan async server components untuk menulis logika async serupa API tanpa bundling di klien. Pilih server-side untuk konsistensi data dan performa SEO; pilih klien untuk interaksi yang bergantung pada browser.
SSR cocok bila konten berubah sering dan penting untuk SEO; SSG ideal untuk konten stabil dengan latensi rendah; ISR menggabungkan keduanya—generate statis lalu revalidate secara periodik. Di Next.js, kontrol lewat export const revalidate atau opsi fetch seperti { next: { revalidate: 60 } }, sementara SSR bisa pakai { cache: ‘no-store’ }.
Edge Functions atau Edge Runtime berguna untuk personalization dan latensi rendah—tempatkan logic dekat pengguna, misalnya geo‑routing atau A/B test. Ingat batasan: hanya Web APIs, ukuran runtime terbatas, dan debugging lebih sulit.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
export const runtime = 'edge' export const revalidate = 60 export default async function Page() { try { const res = await fetch('https://api.example.com/data', { next: { revalidate: 60 } }) if (!res.ok) throw new Error('Network') const data = await res.json() return {data.title} } catch (err) { return Gagal memuat data. Silakan coba lagi. } } |
Debugging, Performance, Best Practices, dan Deployment Produksi
Checklist debugging singkat: periksa server logs dan gunakan React DevTools untuk memisahkan error yang muncul di client vs Server Components. Saat baca stack trace RSC, cari boundary marker dan jalur file server; aktifkan source maps untuk memetakan ke kode sumber dan gunakan correlation-id pada logs agar tracing lebih mudah.
Optimasi yang berdampak cepat meliputi code splitting otomatis, image optimization, dan streaming untuk mengirim HTML parsial lebih cepat. Terapkan strategi caching: header Cache-Control, opsi revalidate, serta CDN/edge cache untuk assets dan API responses.
|
1 2 3 4 5 6 7 8 9 |
export async function GET() { const data = await fetch('https://api.example.com/items', { next: { revalidate: 60 }}); return new Response(JSON.stringify(data), { headers: { 'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=30' } }); } // build & deploy // npm run build && vercel --prod // export DATABASE_URL="..." |
Untuk layout dan komponen: buat Server Components sesederhana mungkin, hindari panggilan DOM atau client-only APIs, dan bungkus interaktivitas dalam client components yang lazy-load.
Saat deploy, gunakan platform yang mendukung SSR/Edge seperti Vercel, Netlify, atau Cloudflare Workers, jalankan e2e testing dengan Playwright atau Cypress, lalu pasang monitoring seperti Sentry dan Prometheus untuk observability pasca-deploy.
Penutup
Setelah mengikuti panduan ini, pembaca akan memahami cara kerja App Router, pola file layout, dan strategi data fetching di lingkungan produksi.
Gunakan contoh, best practice, dan checklist deployment untuk mempercepat migrasi atau memulai proyek baru dengan pendekatan yang lebih modular dan cepat.