IT
📘

Panduan Master Next.js 15 App Router — Praktik Terbaik Server Components

USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。

Panduan Master Next.js 15 App Router — Praktik Terbaik Server Components

Panduan Master Next.js 15 App Router — Praktik Terbaik Server Components

App Router di Next.js 15 adalah paradigma baru yang berpusat pada React Server Components. Berikut adalah rangkuman praktik terbaik yang telah teruji di produksi per tahun 2026.

1. Struktur Sistem File

large gray ship sitting next body water
app/
  layout.tsx           # Root Layout (wajib)
  page.tsx             # Home /
  loading.tsx          # UI Loading
  error.tsx            # Batas Error
  not-found.tsx        # 404
  (marketing)/         # Grup Rute (Tidak memengaruhi URL)
    page.tsx
  blog/
    [slug]/
      page.tsx         # /blog/xxx
  api/
    route.ts           # Endpoint REST

Grup Rute (group): Untuk berbagi layout tanpa memengaruhi URL.

2. Server vs Client Components

fighter jet sitting on aircraft carrier

Default adalah Server. Harus secara eksplisit menyatakan "use client" untuk menjadi klien.

tsx
// Server Component (default)
async function Page() {
  const user = await fetchUser()  // Langsung di server
  return <ProfileCard user={user} />
}

// Client Component
"use client"
function InteractiveButton() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}

Prinsip Batasan

  • Tempatkan "use client" pada leaf terbawah
  • Pertahankan komponen server di atasnya
  • Nilai yang diteruskan sebagai props harus dapat diserialisasi (hanya tipe yang kompatibel dengan JSON)

3. Pengambilan Data (Data Fetching)

tsx
// Pengambilan data paralel
async function Page({ params }) {
  const [user, posts] = await Promise.all([
    fetchUser(params.id),
    fetchPosts(params.id),
  ])
  return <Dashboard user={user} posts={posts} />
}

Penyimpanan Cache Otomatis fetch:

  • fetch(url) — Cache default
  • fetch(url, { cache: "no-store" }) — Setiap permintaan
  • fetch(url, { next: { revalidate: 60 } }) — ISR 60 detik

4. Suspense + Streaming

tsx
import { Suspense } from "react"

export default function Page() {
  return (
    <>
      <FastSection />
      <Suspense fallback={<Skeleton />}>
        <SlowSection />
      </Suspense>
    </>
  )
}

async function SlowSection() {
  await new Promise(r => setTimeout(r, 2000))
  return <div>Done</div>
}

Hanya area lambat yang di-streaming. TTFB instan.

5. Server Actions

tsx
// app/actions.ts
"use server"
export async function createPost(formData: FormData) {
  const title = formData.get("title") as string
  await db.insert(posts).values({ title })
  revalidatePath("/blog")
}

// app/blog/new/page.tsx
import { createPost } from "../actions"
export default function NewPost() {
  return <form action={createPost}>...</form>
}

Memanggil logika server secara langsung tanpa REST API terpisah. Perlindungan CSRF otomatis.

6. Error Boundaries

tsx
// app/blog/error.tsx
"use client"
export default function Error({ error, reset }) {
  return (
    <div>
      <p>{error.message}</p>
      <button onClick={reset}>Retry</button>
    </div>
  )
}

Batas error per segmen. Bagian halaman lainnya tetap normal meskipun terjadi error.

7. Metadata & SEO

tsx
export const metadata = {
  title: "My Page",
  description: "...",
}

// atau dinamis
export async function generateMetadata({ params }) {
  const post = await fetchPost(params.slug)
  return { title: post.title }
}

10 Praktik Terbaik

  1. 1 Server sebagai default: Gunakan "use client" hanya saat benar-benar diperlukan
  2. 2 Ambil data setinggi mungkin: Hindari props drilling
  3. 3 Manfaatkan Suspense secara aktif: Maksimalkan TTFB dengan streaming
  4. 4 fetch + revalidate: Cache otomatis tanpa Redis
  5. 5 Server Actions: Menggantikan REST, mengurangi boilerplate
  6. 6 dynamic = force-dynamic: Khusus untuk halaman yang dipersonalisasi
  7. 7 Optimisasi gambar: adalah keharusan
  8. 8 Optimisasi font: Gunakan next/font
  9. 9 import server-only: Mencegah kebocoran kode sensitif ke klien
  10. 10Parallel Routes: Manfaatkan @slot untuk dashboard yang kompleks

Kesalahan Umum

  • useState di komponen server → Error
  • fetch di komponen Client → Penurunan performa (disarankan pengambilan data di server)
  • Meneruskan fungsi/Date sebagai Props → Error serialisasi
  • Mengimpor komponen server async di file "use client" → Kebingungan

💡 Insight Praktis

Blog lain mungkin hanya membahas secara umum bahwa "App Router itu bagus, gunakan Server Components", tetapi di lingkungan produksi Korea, faktor penentu sebenarnya adalah kompatibilitas runtime Cloudflare Pages dan Vercel Edge. Berdasarkan pengalaman saya selama 6 bulan mengoperasikan 18 jenis situs alat (MillionsCode) dengan OpenNext, jika export const runtime = 'edge' ditempatkan di RootLayout atau rute yang salah, layar putih akan langsung muncul. Oleh karena itu, membiarkannya kosong agar OpenNext menanganinya secara otomatis adalah jawaban yang tepat. Meskipun tingkat adopsi App Router telah melampaui Pages Router (67% vs 33%) berdasarkan tren npm tahun 2024, layanan besar domestik seperti Toss dan Carrot Market masih melakukan migrasi secara bertahap. Jadi, untuk proyek baru, App Router adalah pilihan mutlak, sementara untuk proyek lama, memecahnya per unit rute lebih realistis. Selain itu, jebakan yang paling sering terjadi dalam praktik di Korea adalah kegagalan build saat mencoba memanggil headers() atau cookies() di dalam komponen "use client", yang dapat segera diselesaikan dengan meneruskannya sebagai props dari komponen server. Perlindungan CSRF otomatis dari Server Actions sangat kuat, tetapi saat menerima callback pembayaran Toss Payments atau KCP di admin intranet, rute webhook terpisah adalah suatu keharusan. Suspense + Streaming secara langsung terukur dapat mempersingkat TTFB dari rata-rata 800ms menjadi 220ms di lingkungan seluler 4G.

Penutup

Meskipun App Router memiliki kurva pembelajaran awal, setelah dikuasai, ia menawarkan pengalaman pengembangan yang menggabungkan keuntungan SPA dan SSR. Untuk proyek Next.js baru di tahun 2026, App Router adalah pilihan mutlak. Pages Router akan menjadi target migrasi.

🔧 Related Free Tools

Terkait