When to use
- Adding a client component in Next.js or React Server Components.
- Fixing hook, event handler, browser API, or async component errors.
- Deciding where a client boundary belongs.
- Removing redundant
"use client"directives.
Goal
Place the smallest useful client boundary. Keep server components as server components.
Rules
"use client"marks an import boundary.- All components imported below that boundary become client components.
- Add it only to files imported by a server component and needing client features.
- Do not add it to child components already inside a client boundary.
- Do not add it to pure presentational components.
- Keep data fetching in server components when possible.
- Do not pass server functions as client event handlers.
Add It When
Add the directive when ALL of these are true:
- Component is imported by a server component.
- Component needs hooks, event handlers, browser APIs, or client-only libraries.
Do Not Add It When
- Parent/importer is already a client component.
- Component only renders props.
- Component only uses
children. - Component can stay shared between server and client.
- The reason is "just in case".
Flow
- Trace the import chain upward.
- Find first server-to-client crossing.
- Check whether that component needs client features.
- Put
"use client"there. - Remove redundant directives below it.
- Move async data fetching above the boundary when possible.
Pattern
"use client";
import { FilterDropdown } from "./filter-dropdown";
export function SearchFilters() {
const [filters, setFilters] = useState({});
return (
<FilterDropdown value={filters.category} onChange={setFilters} />
);
}
// No directive needed.
export function FilterDropdown({ value, onChange }) {
return <select value={value} onChange={(e) => onChange(e.target.value)} />;
}
Common Errors
- Hook only works in Client Components: add boundary at the hook owner or move hook lower.
- Event handlers cannot be passed from server to client: move handler into client component.
- Async not supported in Client Components: keep async data component on server and pass data down.
Output
- Boundary location.
- Directives to add or remove.
- Data-fetching placement.
- Any server/client prop issues.