Software

Next.js Server vs Client Components: Panduan Lengkap

June 10, 2026 at 02:33 PM
Next.js Server vs Client Components: Panduan Lengkap

Next.js App Router memperkenalkan dua jenis komponen yang berbeda cara kerjanya: Server Components dan Client Components. Memahami perbedaannya adalah kunci untuk membangun aplikasi Next.js yang cepat dan efisien.

Apa Itu Server Components?

Server Components adalah komponen yang dirender sepenuhnya di server. HTML-nya sudah jadi sebelum dikirim ke browser — browser tidak perlu menjalankan JavaScript untuk menampilkannya.

Di Next.js App Router, semua komponen adalah Server Component secara default.

// app/page.tsx
// Ini Server Component — tidak perlu deklarasi apapun

async function BlogPage() {
  const posts = await fetch('https://api.example.com/posts').then(r => r.json())

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

export default BlogPage

Perhatikan: kita bisa langsung async/await di dalam komponen, tanpa useEffect atau state management.

Apa Itu Client Components?

Client Components adalah komponen yang dirender di browser (seperti React biasa). Diperlukan saat komponen butuh interaktivitas — event handler, state, atau browser API.

Untuk mengubah komponen menjadi Client Component, tambahkan 'use client' di baris paling atas file.

'use client'

import { useState } from 'react'

function Counter() {
  const [count, setCount] = useState(0)

  return (
    <button onClick={() => setCount(count + 1)}>
      Klik: {count}
    </button>
  )
}

export default Counter

Perbedaan Utama

Server Component Client Component
Render Di server Di browser
Default? ✅ Ya ❌ Perlu 'use client'
Bisa async/await? ✅ Ya ❌ Tidak langsung
Bisa useState/useEffect? ❌ Tidak ✅ Ya
Bisa akses database langsung? ✅ Ya ❌ Tidak
Bisa pakai event handler? ❌ Tidak ✅ Ya
Dikirim ke browser sebagai JS? ❌ Tidak ✅ Ya

Kapan Pakai yang Mana?

Gunakan Server Component ketika:

  • Mengambil data dari database atau API
  • Menampilkan konten statis atau semi-statis
  • Perlu akses ke resource server (env variables, filesystem)
  • Ingin menjaga bundle size tetap kecil

Gunakan Client Component ketika:

  • Butuh useState atau useReducer
  • Butuh useEffect atau lifecycle hooks
  • Ada event handler (onClick, onChange, dll.)
  • Menggunakan browser API (localStorage, window, navigator)
  • Menggunakan library yang bergantung pada DOM

Pola Komposisi yang Tepat

Kuncinya adalah mendorong Client Components sejauh mungkin ke "daun" (leaf) dari component tree.

// ✅ Pola yang benar
// app/product/page.tsx — Server Component
async function ProductPage({ params }) {
  const product = await getProduct(params.id) // fetch langsung di server

  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <AddToCartButton productId={product.id} /> {/* Client Component */}
    </div>
  )
}

// app/product/AddToCartButton.tsx — Client Component
'use client'

function AddToCartButton({ productId }) {
  function handleClick() {
    // logika tambah ke cart
  }

  return <button onClick={handleClick}>Tambah ke Keranjang</button>
}

Dengan pola ini, hanya AddToCartButton yang dikirim sebagai JavaScript ke browser — bukan seluruh halaman.

Yang Sering Salah: Membungkus Terlalu Lebar

// ❌ Hindari ini
'use client'

async function ProductPage() { // Seluruh halaman jadi Client Component
  const product = await getProduct() // Ini tidak bisa di Client Component!
  // ...
}

Server Components Bisa Menjadi Parent dari Client Components

Ini konsep penting: Server Component bisa menjadi parent dari Client Component, tapi tidak sebaliknya — Client Component tidak bisa mengimport Server Component.

// ✅ Ini valid
// Server Component sebagai parent
function Layout({ children }) {
  return <div>{children}</div>
}

// Di dalamnya ada Client Component
<Layout>
  <InteractiveWidget /> {/* Client Component */}
</Layout>

// ❌ Ini tidak valid
'use client'

import ServerComponent from './ServerComponent' // Error!

function ClientComponent() {
  return <ServerComponent /> // Tidak bisa
}

Contoh Nyata: Halaman Blog

// app/blog/page.tsx — Server Component
async function BlogPage() {
  const posts = await db.post.findMany() // Akses DB langsung

  return (
    <main>
      <h1>Blog</h1>
      <SearchBar /> {/* Client Component untuk fitur search */}
      <PostList posts={posts} /> {/* Server Component */}
    </main>
  )
}

// components/SearchBar.tsx — Client Component
'use client'

import { useState } from 'react'

function SearchBar() {
  const [query, setQuery] = useState('')

  return (
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      placeholder="Cari artikel..."
    />
  )
}

// components/PostList.tsx — Server Component (tidak perlu 'use client')
function PostList({ posts }) {
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>
          <a href={`/blog/${post.slug}`}>{post.title}</a>
        </li>
      ))}
    </ul>
  )
}

Kesimpulan

Aturan sederhananya:

  1. Mulai dengan Server Component— ini defaultnya, dan lebih efisien
  2. Tambah 'use client' hanya saat dibutuhkan — ketika ada interaktivitas atau browser API
  3. Pisahkan logika interaktif ke komponen kecil — jangan buat seluruh halaman jadi Client Component hanya karena satu tombol butuh onClick

Dengan memahami pola ini, aplikasi Next.js kamu akan lebih cepat karena JavaScript yang dikirim ke browser jadi jauh lebih sedikit.

FAQ

Apakah semua komponen di Next.js harus jadi Server Component?

Tidak. Server Component adalah default, tapi kamu bebas mengubahnya jadi Client Component dengan menambahkan 'use client' di bagian atas file. Gunakan Client Component hanya saat benar-benar dibutuhkan — misalnya saat ada interaktivitas atau penggunaan browser API.

Bisakah Server Component dan Client Component dipakai bersamaan?

Bisa. Bahkan ini adalah pola yang dianjurkan. Server Component bisa menjadi parent dari Client Component. Yang tidak bisa adalah sebaliknya — Client Component tidak bisa mengimport Server Component.

Apakah Client Component tidak dirender di server sama sekali?

Tetap dirender di server untuk menghasilkan HTML awal (ini disebut SSR), tapi JavaScript-nya juga dikirim ke browser untuk proses hydration agar interaktivitas bisa berjalan. Berbeda dengan Server Component yang JavaScript-nya tidak dikirim ke browser sama sekali.

Kenapa bundle size bisa lebih kecil dengan Server Components?

Karena kode Server Component tidak dimasukkan ke dalam JavaScript bundle yang dikirim ke browser. Hanya Client Component yang masuk ke bundle. Semakin sedikit Client Component yang dibuat, semakin kecil bundle-nya.

Apakah Server Components bisa dipakai di Next.js Pages Router?

Tidak. Server Components hanya tersedia di App Router (Next.js 13+). Jika masih menggunakan Pages Router, semua komponen berperilaku seperti Client Component.

Bagaimana cara mengakses cookies atau headers di Server Component?

Gunakan fungsi bawaan Next.js seperti cookies() atau headers() dari next/headers. Fungsi ini hanya bisa dipanggil di Server Component atau Server Action.

#NextJS

Wanna Know More About Us?

Contact us via WhatsApp

Have any questions? Message us directly on WhatsApp for the fastest response.