Roadmap › Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server › Module: Getting Started
Lessons in this course (8)
2. Server Components vs Client Components
Basic★ Must knowLesson 2 of 8
| Server Component (default) | Client Component ("use client") | |
|---|---|---|
| Runs | On the server (build time or request) | Server-rendered to HTML, then hydrated in the browser |
| Can use | async/await, database, file system, secrets | useState, useEffect, event handlers, browser APIs |
| JavaScript sent to browser | None | Yes (bundle) |
| Typical | Pages, data loading, layouts, static content | Buttons, forms with state, modals, charts |
tsx
// app/products/page.tsx (Server Component)
import AddToCart from "./AddToCart";
import { listProducts } from "@/lib/products";
export default async function Products() {
const products = await listProducts(); // direct DB call, no API needed
return <ul>{products.map((p) => <li key={p.id}>{p.name} <AddToCart id={p.id} /></li>)}</ul>;
}
// app/products/AddToCart.tsx (Client Component)
"use client";
import { useState } from "react";
export default function AddToCart({ id }: { id: number }) {
const [added, setAdded] = useState(false);
return <button onClick={() => setAdded(true)}>{added ? "Added ✓" : "Add to cart"}</button>;
}Rules: push "use client" as far down the tree as possible; Server Components can render Client Components (props must be serialisable); Client Components can't import Server Components but can receive them as children; mark server-only modules with import "server-only" so secrets never reach the browser.