webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Tooling
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Forms
  12. 12Data and backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animations
  16. 16Testing
  17. 17Architecture
Next.js · Lesson 4 of 12

Server vs Client Components

When you need 'use client' and how data crosses the boundary.

Updated

What Server Components and Client Components are

In Next.js, every component runs either on the server or in the browser (and on the server, for the first render). The choice decides what the component can do and how much JavaScript reaches the user.

  • Server Component — runs only on the server. Its code never reaches the browser; the user only receives the resulting HTML.
  • Client Component — is sent to the browser as JavaScript, gets hydrated and can be interactive.

In app/, every component is a Server Component by default. It becomes a Client Component when the file starts with 'use client'.

The differences

Server Component Client Component
Runs only on the server the server (initial HTML) + the browser
JS sent to the browser zero the component's code + its dependencies
async / await directly yes no
Access to the DB, files, secrets yes no
useState, useEffect, hooks no yes
onClick, onChange no yes
window, localStorage no yes

When to use each

You need... Choice
to read data (a DB, an API) and display it Server
static content: text, layout, lists Server
secrets (API keys, the DB URL) Server
state, effects, event handlers Client
browser APIs (localStorage, geolocation) Client
libraries that use hooks (charts, editors) Client
// a Server Component — the default
export default async function Page() {
  const posts = await db.post.findMany()
  return <PostList posts={posts} />
}
'use client'
import { useState } from 'react'

export function LikeButton({ initial }: { initial: number }) {
  const [likes, setLikes] = useState(initial)
  return <button onClick={() => setLikes(likes + 1)}>♥ {likes}</button>
}

The golden rule

Keep 'use client' as low as possible in the tree. The page stays on the server; only the interactive button is a client one. 'use client' marks a boundary: the file and everything it imports become client code.

  • Pageserver
    • Headerserver
    • PostListserver
      • LikeButtonclient — only this reaches the browser as JS
    • Footerserver

The server → client boundary

Rule Details
Data crosses through props it must be serializable: strings, numbers, plain objects, arrays, Dates, Promises
No functions as props the exception: Server Actions
A Client Component can receive Server Components as children <ClientModal><ServerContent /></ClientModal>
A Client Component can't import a Server Component it only receives it as children / a prop

Server Actions — mutations from the client

'use server' functions you call from the client, but that run on the server — for forms and mutations. The Server Actions lesson.

Summary

  • A Server Component (the default): async, access to data and secrets, zero JS in the browser.
  • A Client Component ('use client'): state, effects, events, browser APIs.
  • 'use client' as low as possible; serializable props across the boundary.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.