NextjsClient Components

Client Components

A Client Component is any component that opts into running in the browser by adding the 'use client' directive at the very top of its file. You reach for one whenever a component needs state, effects, event handlers, or access to browser-only APIs — the things a plain Server Component is not allowed to do.

components/Counter.tsx

TSX
'use client'

import { useState } from 'react'

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>Increment</button>
      <button onClick={() => setCount((c) => c - 1)}>Decrement</button>
    </div>
  )
}

Drop that component into any Server Component page and it just works — the two component types compose freely as long as the data flows in the right direction (more on that on the composition patterns page):

app/page.tsx

TSX
import Counter from '@/components/Counter'

export default function HomePage() {
  return (
    <main>
      <h1>Welcome</h1>
      <Counter />
    </main>
  )
}
'use client' doesn't mean "browser only"
The name is genuinely misleading if you read it literally, and it trips up a lot of people learning the App Router. Marking a component with 'use client' does not mean that component only ever runs in the browser. It means the component can run in the browser — i.e. it's allowed to use state, effects, and browser APIs.
The surprising part: it still renders on the server first
For the initial page load, Next.js renders a Client Component on the server too — exactly like a Server Component would — and sends real HTML to the browser for the first paint. Then, once the JavaScript for that component arrives and runs, React "hydrates" that server-rendered HTML: it attaches event listeners and wires up state so the markup becomes interactive, without having to re-render everything from scratch. So a Client Component actually runs twice in a typical page load — once on the server (to produce initial HTML) and once in the browser (to hydrate and then handle subsequent interactions). Only after hydration does it behave the way the name suggests.
This server-render-then-hydrate behavior is why a Client Component can safely call fetch during that first server render, or why you'll sometimes see a brief flash where a button renders but doesn't yet respond to clicks — that gap is the window between HTML arriving and hydration finishing.
When you actually need one
  • StateuseState, useReducer, or any hook that holds values that change over time in response to user interaction.

  • EffectsuseEffect, useLayoutEffect, subscribing to something after mount.

  • Event handlersonClick, onChange, onSubmit, and friends.

  • Browser-only APIswindow, document, localStorage, navigator.geolocation, and so on.

  • Custom hooks or third-party libraries that themselves rely on any of the above (a charting library that measures the DOM, a hook from a UI kit that reads window.innerWidth, etc.).

Tip
If a component doesn't need any of the above, leave it as a Server Component — that's the default, and it's the cheaper option. Add 'use client' only where interactivity is actually required, and prefer adding it to small, focused components rather than entire pages. The Server vs Client Components page covers this "push it down the tree" guidance in detail.
  • 'use client' at the top of a file opts a component into being a Client Component.

  • Client Components still render on the server for the initial HTML, then hydrate in the browser to become interactive.

  • 'use client' means "can run in the browser," not "only runs in the browser."

  • Reach for a Client Component specifically when you need state, effects, event handlers, or browser APIs.