The use client Directive — Marking the Server-Client Boundary
In this tutorial, you will learn about The use client Directive. We cover key concepts, practical examples, and best practices to help you master this topic.
The 'use client' directive tells React to treat all components in the file as Client Components, marking the boundary where server rendering stops and client rendering begins.
What You'll Learn
You will understand how 'use client' works, where to place it, how it affects imported components, and best practices for keeping the boundary as deep as possible.
Why It Matters
Misplacing 'use client' either breaks your app (missing interactivity) or defeats the purpose of RSC (sending too much JavaScript to the client). Correct placement is critical.
Real-World Use
DodaTech's tutorial platform uses 'use client' only on interactive components like the code sandbox, search bar, and theme toggle, keeping the article content and navigation as Server Components.
flowchart LR
A[Server Component File] --> B{Has use client?}
B -->|No| C[Default: Server Component]
B -->|Yes| D[Client Component Boundary]
D --> E[All exports become Client Components]
D --> F[Cannot import Server Components]
C --> G[Can import Client Components]
C --> H[Can use async/await]
style A fill:#1e293b,color:#fff
style D fill:#0f172a,color:#fff
How the Directive Works
The 'use client' string must be the very first line of the file, before any imports. It is a literal string literal, not a comment or a function call.
'use client';
import { useState } from 'react';
import { formatDate } from '../utils';
export default function CommentForm({ postId }) {
const [text, setText] = useState('');
return (
<form>
<textarea value={text} onChange={e => setText(e.target.value)} />
<button type="submit">Post Comment</button>
</form>
);
}
Expected output: The CommentForm component runs on the client, supports useState, and handles user input. The file can import utility functions that do not use server-only features.
Where the Boundary Applies
The boundary applies to the entire file. Every component exported from a 'use client' file is a Client Component. You cannot selectively mark individual components within the same file.
'use client';
// Both of these are Client Components
export function InteractiveButton({ onClick, label }) {
return <button onClick={onClick}>{label}</button>;
}
export function InteractiveInput({ value, onChange }) {
return <input value={value} onChange={onChange} />;
}
Expected output: Both InteractiveButton and InteractiveButton render on the client. They can use hooks and browser APIs because they are in a 'use client' file.
Pushing the Boundary as Low as Possible
The goal is to keep the boundary deep in the component tree. Instead of marking a whole page as a Client Component, extract only the interactive leaf components.
// app/page.js — Server Component (no use client)
import InteractiveLikeButton from './InteractiveLikeButton';
import CommentList from './CommentList'; // Could be Server or Client
export default async function BlogPost({ params }) {
const post = await db.posts.findById(params.id);
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
<InteractiveLikeButton postId={post.id} initialLikes={post.likes} />
<CommentList postId={post.id} />
</article>
);
}
Expected output: The BlogPost renders on the server with data from the database. Only the InteractiveLikeButton is a Client Component. The article content stays as Server Components.
Common Mistakes
Putting use client in the root layout: The root layout rarely needs interactivity. Only add
'use client'to the root layout if it uses hooks or browser APIs.Missing the directive and wondering why hooks fail: If you use useState without
'use client', React throws an error at build time. Always add the directive when using hooks.Putting the directive after imports:
'use client'must be the first line of the file. Placing it after imports causes it to be ignored.Assuming the directive is inherited by children: Children of a Client Component can be Server Components if passed as props or children. The directive does not propagate to imported components.
Marking utility files with use client: Utility files that export pure functions do not need
'use client'. Only mark files that contain interactive React components.
Practice Questions
- What does
'use client'do at the file level?
It marks all exported components in the file as Client Components, establishing a boundary between server and client rendering.
- Can you have Server Components and Client Components in the same file?
No. A file is either entirely Server Components (no
'use client') or entirely Client Components (with'use client').
- What happens if you omit
'use client'but use useState in a component?
React throws a build or runtime error because useState requires client-side rendering.
- How can you pass a Server Component as a child to a Client Component?
Import the Server Component in a parent Server Component and pass it as a child prop. The Client Component renders it.
- Why should you push
'use client'as deep as possible?
To minimize the amount of JavaScript sent to the browser. Only the deep interactive leaves need client-side code.
Challenge
Take a page where the entire file is marked with 'use client' and refactor it so that only two small interactive components use the directive, while the rest remains as Server Components.
Frequently Asked Questions
Mini Project
Create a blog post page with a Server Component fetching the post content, a Client Component for the comment form (with use client), and another Client Component for the like button. Keep the directive only in the interactive files.
What's Next
Learn how to Server Component Data Fetching using async/await and direct database queries.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro