Opting in
Here is the counter from the React course, ported to Next.js:
// app/like-button.js "use client"; import { useState } from "react"; export default function LikeButton() { const [likes, setLikes] = useState(0); return ( <button onClick={() => setLikes(likes + 1)}> ♥ {likes} </button> ); }
Decode it:
"use client"must be the first line of the file, before imports. It is a directive, not a function call.- Everything below it is exactly the React you already know.
- Without the directive, the build fails:
useStateandonClickare not allowed in server components.
It marks a boundary, not one file
The rule that makes the directive matter: everything a client file imports becomes client code too, because the browser must be able to run the whole subtree that a client component renders. In that sense the directive is contagious in one direction — downward through imports. Picture the component tree. "use client" draws a line, and the whole subtree below that line ships to the browser.
That leads to the golden rule:
Put
"use client"as low in the tree as possible, on the small interactive leaves (a button, a search box), not on whole pages.
Mark a page-level component as client and you drag every component it imports into the bundle, throwing away the zero-JS benefit of server components for that entire page.
Quiz
Where must the "use client" directive appear?
Problem
Spot the bug. This file has no "use client" directive: ```jsx // app/newsletter/page.js import { useState } from "react"; export default function Newsletter() { const [email, setEmail] = useState(""); return <input value={email} onChange={(e) => setEmail(e.target.value)} />; } ``` What one line fixes it? (write the line)
Code exercise · javascript
Automate the client/server decision (pure JavaScript, runnable here). Write needsUseClient(features): it receives an array of strings describing what a component uses (like ["useState", "props"]) and returns true if any of them is client-only. Treat these as client-only: useState, useEffect, onClick, onChange, localStorage, window. Everything else (props, fetch, async) is fine on the server.