NextjsThe "use client" Directive

The "use client" Directive

'use client' is a one-line directive — not an import, not a function call, just a string literal on its own line — that marks a file's module boundary as belonging to the client. Its placement rules and its actual scope of effect are both stricter than they first appear, and both are worth nailing down precisely.
It must be the very first line of the file

Correct placement

TSX
'use client'

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}
A common mistake: putting it after imports
'use client' must appear before any import statements (and before any other code, including comments in some tooling setups). Writing your imports first and the directive second looks harmless, but the directive is only recognized when it's the literal first statement in the file — put it anywhere else and Next.js silently treats the file as a Server Component, which then fails at build or runtime the moment it tries to use a hook.

Incorrect — this will NOT work as a Client Component

TSX
import { useState } from 'react'

'use client' // Too late — imports already came first.

export default function Counter() {
  const [count, setCount] = useState(0) // Error: hooks require a Client Component
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}
It marks a boundary, not just one component
This is the subtlety that catches people off guard: adding 'use client' to a file doesn't only affect the component defined in that file. It marks the entry point of a client module boundary — every module that file imports (that doesn't itself already belong to a different, more specific boundary) is pulled into the client bundle along with it, all the way down the import tree.

components/Panel.tsx

TSX
'use client'

import { useState } from 'react'
import Icon from './Icon'          // pulled into the client bundle too
import formatLabel from './format'  // this helper is now client code as well

export default function Panel() {
  const [open, setOpen] = useState(false)
  return (
    <div>
      <button onClick={() => setOpen(!open)}>
        <Icon name={open ? 'chevron-up' : 'chevron-down'} />
        {formatLabel('Details')}
      </button>
      {open && <p>Panel contents…</p>}
    </div>
  )
}
Note
In the example above, neither Icon nor format declares 'use client' itself — but because they're imported from inside a file that does, they become part of the client bundle for this boundary too. Think of 'use client' less as "this component is a Client Component" and more as "this file, and everything it pulls in beneath it, crosses into client territory."
It doesn't mean "browser only"
As covered on the Client Components page, this directive does not mean the component skips server rendering. Next.js still renders a 'use client' component on the server for the initial HTML — the directive's job is only to say "this component is allowed to also run in the browser, use hooks, and attach event handlers," not "this component never touches the server."
When you actually need it
  • Using any React hook that involves state or lifecycle: useState, useReducer, useEffect, useContext (in many setups), etc.

  • Attaching event handlers — onClick, onChange, onSubmit, and so on.

  • Reading browser-only globals — window, document, localStorage, navigator.

  • Using a third-party library that itself depends on any of the above (many UI/animation libraries fall into this bucket).

  • 'use client' must be the first line in the file, before any imports.

  • It marks a module boundary — everything imported beneath it (without its own more specific directive) joins the client bundle.

  • It does not mean "browser only" — the component still renders on the server first, then hydrates.

  • Use it for hooks, event handlers, and browser APIs; nothing else needs it.