Errors involving a missing 'use client' directive — often surfacing as "You're importing a component that needs useState. This React hook only works in a client component" or similar — mean you're using client-only React features (hooks, browser APIs, event handlers) inside a component that Next.js's App Router is treating as a Server Component by default.
This error means a component using interactive, client-side-only React functionality doesn't have the 'use client' directive at the top of its file, and Next.js's App Router defaults every component to a Server Component unless explicitly marked otherwise — Server Components can't use hooks, browser APIs, or event handlers, since they execute only on the server and never re-render or handle interaction in the browser.
Why This Error Happens
The App Router introduced Server Components as the default rendering model, running component code on the server and shipping only rendered output (plus minimal JS for client parts) to the browser — a genuine architectural shift from the Pages Router's fully client-rendered model. Any component needing useState, useEffect, event handlers (onClick, onChange), or browser-only APIs (window, localStorage) must explicitly opt into client-side rendering via the 'use client' directive, since none of those things are meaningful or executable during server-side rendering.
Reproducing the Error
A component using useState without the directive:
// components/Counter.tsx
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
// Error: You're importing a component that needs `useState`.
// This React Hook only works in a Client Component.
// Add the "use client" directive at the top of the file to use it.
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Core Concepts Behind This Error
The 'use client' directive must be the very first line of the file (before imports, only preceded by comments), and it marks that file's boundary as the start of the client-rendered module tree — every component imported from that file becomes part of the client bundle, along with any components it imports.
'use client' marks a boundary, not every individual component that needs it — once a file has the directive, every component defined or exported from it (and everything it imports and renders) becomes client-rendered from that point down the tree; you don't need to add the directive to child components already living within a client boundary.
Server Components remain the better default for anything not requiring interactivity — pure data-fetching and static-content components should stay as Server Components rather than reflexively adding 'use client' everywhere, since Server Components reduce client bundle size and can directly access server-only resources (databases, filesystem, secrets) without an API layer.
A common mistake is adding 'use client' too high in the component tree, converting large swaths of otherwise-static content into client-rendered code just because one small interactive piece needs it — isolating the interactive part into its own small client component and keeping the surrounding structure as Server Components is the better pattern.
Fixing "'use Client' Directive Missing"
Fix 1: Add the directive as the first line of the file needing client-side features:
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Fix 2: Isolate interactive pieces into their own small client components, keeping surrounding layout/content as Server Components:
// app/page.tsx — stays a Server Component, fetches data directly
import { Counter } from "@/components/Counter"; // the client component
export default async function Page() {
const data = await fetchServerData();
return (
<div>
<h1>{data.title}</h1>
<Counter /> {/* only this small piece is client-rendered */}
</div>
);
}
Fix 3: If a large component genuinely needs both server-fetched data and client interactivity, pass server-fetched data down as props into a client component, rather than converting the whole tree to client-rendered:
// app/page.tsx (Server Component)
export default async function Page() {
const initialData = await fetchServerData();
return <InteractiveDashboard initialData={initialData} />; // client component receives server data as props
}
Should You Just Add "use client" to Every Component to Avoid Dealing With This?
No — that defeats the primary benefit of the App Router's Server Component architecture, converting your application back into something closer to the fully client-rendered Pages Router model while losing the reduced bundle size and direct server-resource access Server Components provide. Isolate interactivity into the smallest possible client component boundaries, and keep data-fetching and static structure as Server Components by default.
Preventing This Error in Production
Design components with a clear sense of which pieces genuinely need interactivity versus which are purely presentational or data-driven, adding 'use client' deliberately at the smallest reasonable boundary rather than defensively at every file. Structure server-fetched data to flow down as props into focused client components, keeping the bulk of your component tree as Server Components by default and reserving the client boundary for actual interactive functionality.
If you hit this error, add 'use client' to the specific file using the hook/browser API, but first consider whether that interactive piece could be isolated into a smaller, separate client component instead of converting a larger surrounding tree unnecessarily.