Next.js 13: Choosing Server vs Client
easy⏱ 5 mincoursenextjs
Ask what the component needs, not what it renders
The split isn't about what a component looks like — a button can live on either side. It's about capabilities: useState/useReducer, useEffect, onClick/onChange, window/localStorage → Client. Direct DB/filesystem access, secrets/API keys, await at the top of the component, zero interactivity → Server.
// Server: fetches directly, no interactivity, secret stays on the server
async function OrderSummary({ orderId }) {
const order = await db.order.findUnique({ where: { id: orderId } });
return <p>Total: {order.total}</p>;
}
// Client: needs useState + onClick
'use client';
function QuantityStepper({ initial }) {
const [qty, setQty] = useState(initial);
return <button onClick={() => setQty(qty + 1)}>{qty}</button>;
}
When in doubt, default to server
A common mistake is slapping 'use client' on a whole page because one button needs onClick. Instead, keep the page a Server Component and extract just the interactive piece — like QuantityStepper above — into its own small Client Component. Push the client boundary as far down the tree as possible.
Sort the features
For each feature card, click Server or Client. useState, onClick, localStorage, and useEffect belong on the client; await db.query(), reading process.env.SECRET, and static markup belong on the server. Your score updates live.