intermediate
Server Components
Render components on the server, keep secrets and heavy dependencies off the client, and serialize only supported values.
Server Components render on the server and send a compact RSC payload to the client — not a full interactive component tree. They can await async data, read secrets, and import server-only modules without shipping that code to the browser.
Children can be Server or Client Components; Client children receive serializable props only.
// Server Component — no 'use client'
import { db } from '@/lib/db';
export default async function ProductList() {
const items = await db.product.findMany();
return <ul>{items.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}
On interviews: explain bundle size impact, async components, and composition with client islands.
Common pitfalls: adding `use client` at the root, trying to use hooks in server components, and passing non-serializable props to clients.
The trade-off is smaller client bundles versus no browser APIs on the server tree.
Checklist:
- Async fetch directly in server components.
- Keep interactive leaves as client children.
- Never import client-only hooks server-side.
- Audit serialized props at boundaries.