Next.js App Router: Server vs Client Components, Routing & SSR Metadata
Membongkar Arsitektur Hibrida Next.js 16: Async Params, generateMetadata & Route Handlers
01. Target Pembelajar & Prasyarat
Developer web yang ingin menguasai arsitektur produksi Next.js 16 App Router (sebagaimana digunakan di Z-Automation).
02. Kompetensi Konseptual (Level 1ā2)
- āMembedakan kapan sebuah komponen harus dirender di server (RSC) vs kapan harus menggunakan direktif 'use client'.
- āMenjelaskan mengapa crawler WhatsApp/LinkedIn/X membutuhkan tag Open Graph yang dirender di server (generateMetadata).
03. Kompetensi Praktis & Artefak Nyata (Level 3ā4)
- āMengimplementasikan halaman dinamis di Next.js 16 dengan menangani params: Promise<{ slug: string }> secara asinkron (await params).
- āMembangun pasangan Server Page + Client Interactive Estimator + Route Handler API (POST /api/orders) lengkap.
04. Aplikasi Nyata & Verifikasi
Penerapan Industri: Arsitektur persis yang menggerakkan halaman /katalog dan rute edukasi Z-Automation.
Metode Verifikasi: Memeriksa output HTML mentah untuk memverifikasi tag og:image dan menguji pengiriman form.
Mengapa Subjek Ini Krusial dalam Rekayasa Nyata?
Pelajari cara memisahkan Server Components (Zero-Bundle Size) dan Client Components ('use client'), menghasilkan kartu Open Graph dinamis, dan menghubungkan REST API.
Dalam lingkungan produksi, kegagalan memahami batas-batas arsitektur sistem sering kali menyebabkan bug yang sulit dilacak, pemborosan biaya komputasi, atau antarmuka yang lambat bagi pengguna.
Bagaimana Sistem Sebenarnya Bekerja di Tingkat Protokol
Batas Arsitektur Server vs Client di Next.js 16
Salah satu lompatan terbesar dalam rekayasa web modern adalah pemisahan tegas antara Server Components dan Client Components.
Secara default, seluruh komponen di dalam direktori `src/app/` adalah Server Components. Kode di dalamnya dieksekusi murni di server node/edge: ia dapat membaca sistem file, menyambung ke database rahasia, dan menyusun tag `<meta>` untuk SEO. Yang dikirim ke browser hanyalah HTML dan data streaming ringan tanpa membengkakkan ukuran bundel JavaScript.
Ketika kita membutuhkan interaktivitas pengguna (seperti `useState`, slider kalkulator, atau klik tombol), kita membuat 'Pulau Interaktif' menggunakan direktif `'use client'` di baris teratas file tersebut.
Sesuai aturan AGENTS.md, pada Next.js 16, props `params` dan `searchParams` bersifat asinkron (`Promise`). Selalu tulis: `const { slug } = await params;` sebelum membaca propertinya.
Batas Arsitektur Server vs Client di Next.js 16 App Router
Browser meminta URL /edukasi-demo/paket-01 melalui HTTP GET.
{
"method": "GET",
"path": "/edukasi-demo/paket-01",
"headers": {
"accept": "text/html"
}
}Koreksi Asumsi Umum vs Realitas Rekayasa
āMenambahkan 'use client' berarti komponen tersebut hanya berjalan di browser dan tidak dirender di server sama sekali.ā
Client Component tetap dirender menjadi HTML awal di server (SSR untuk pre-render), lalu mengalami 'hydration' di browser untuk mengikat event listener.
āKita bisa mengakses params.slug secara sinkron seperti di Next.js 14 lama.ā
Di Next.js 15 dan 16, params dan searchParams adalah Promise asinkron dan wajib di-await.
Implementasi Langkah-demi-Langkah
Hasil akhir yang diharapkan: Halaman katalog dinamis berfitur SSR Open Graph dan kalkulator interaktif klien.
src/app/edukasi-demo/[slug]/ āāā page.tsx āāā EstimatorClient.tsx
1Membangun Server Page dengan Metadata Open Graph
Server component asinkron dengan penanganan Promise params.
| 1 | // src/app/edukasi-demo/[slug]/page.tsx |
| 2 | import type { Metadata } from 'next'; |
| 3 | import EstimatorClient from './EstimatorClient'; |
| 4 | |
| 5 | type PageProps = { |
| 6 | params: Promise<{ slug: string }>; |
| 7 | }; |
| 8 | |
| 9 | export async function generateMetadata({ params }: PageProps): Promise<Metadata> { |
| 10 | const { slug } = await params; |
| 11 | return { |
| 12 | title: `Paket ${slug.toUpperCase()} ā Z-Automation`, |
| 13 | description: 'Estimasi biaya pembuatan website interaktif modern.', |
| 14 | openGraph: { |
| 15 | title: `Paket ${slug.toUpperCase()} | Z-Automation`, |
| 16 | description: 'Dapatkan kalkulasi instan dan arsitektur 3D WebGL.', |
| 17 | images: ['/assets/images/katalog/paket-05-corporate-store.jpg'] |
| 18 | } |
| 19 | }; |
| 20 | } |
| 21 | |
| 22 | export default async function Page({ params }: PageProps) { |
| 23 | const { slug } = await params; |
| 24 | return ( |
| 25 | <main style={{ maxWidth: 800, margin: '0 auto', padding: 32 }}> |
| 26 | <h1>Konfigurasi Paket: {slug}</h1> |
| 27 | <EstimatorClient initialSlug={slug} /> |
| 28 | </main> |
| 29 | ); |
| 30 | } |
Halaman dengan metadata OG valid dan formulir interaktif responsif.
Mengantisipasi Masalah Umum & Tantangan Ekstensi
Hubungkan tombol submit ke endpoint POST /api/orders.
Uji Kompetensi Mandiri & Verifikasi Hasil
Standar kelulusan Z-Automation mewajibkan skor minimum 80 / 100 Poin dengan komponen Implementasi Praktis minimal 21 / 35 Poin (60%). Jawab soal diagnostik dan centang hasil pengujian praktis Anda.
BAGIAN A // PERTANYAAN DIAGNOSTIK KONSEPTUAL & TEKNIS (40 POIN)
01.Mengapa kita tidak boleh menambahkan 'use client' di baris paling atas file page.tsx yang memuat generateMetadata()?
BAGIAN B // DAFTAR PERIKSA HASIL IMPLEMENTASI PRAKTIS (35 POIN ā MIN. 21 POIN)
Centang item di bawah ini hanya jika Anda telah menjalankan kode di komputer Anda dan mengamati output yang benar: