Next.js Client Components
Add interactivity with use client, hooks, and browser APIs
Overview
Client Components run in the browser. Add the 'use client' directive at the top of a file to use React state, effects, event handlers, and browser-only APIs. Keep them as small as possible at the leaves of your component tree.
Syntax / Usage
'use client'
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount((c) => c + 1)}>
Count: {count}
</button>
)
}
Import a Client Component into a Server Component:
// app/page.tsx — Server Component
import { Counter } from '@/components/Counter'
export default function Page() {
return (
<main>
<h1>Dashboard</h1>
<Counter />
</main>
)
}
Examples
Form with client-side validation:
'use client'
export function ContactForm() {
const [error, setError] = useState<string | null>(null)
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const form = new FormData(e.currentTarget)
const email = String(form.get('email'))
if (!email.includes('@')) {
setError('Invalid email')
return
}
await fetch('/api/contact', { method: 'POST', body: form })
}
return (
<form onSubmit={onSubmit}>
<input name="email" />
{error && <p>{error}</p>}
<button type="submit">Send</button>
</form>
)
}
Common Mistakes
- Adding
'use client'to files that only render static markup - Importing server-only modules (
fs, DB clients) into Client Components - Bundling large libraries in client components without dynamic import
- Prop drilling server secrets through client props
See Also
server-components app-router use-state use-effect