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.