Back to Blogs

Mastering Server Components: When to Use Server vs Client in Next.js 14+Mastering Server Components: When to Use Server vs Client in Next.js 14+

10 months ago
Mastering Server Components: When to Use Server vs Client in Next.js 14+

Mastering Server Components in Next.js 14+

Next.js 13+ introduced a paradigm shift with React Server Components (RSC). It's powerful, but it introduced a new question for every component: "Should this be a Client or Server Component?"

The Problem I Faced

I initially migrated a dashboard app and made everything "use client" just to make errors go away. The app worked, but I lost all the performance benefits of RSC—fetching data was slower, and the bundle size remained huge.

Understanding the Split

  • Server Components (Default): Fetch data, access backend resources, keep sensitive keys safe, reduce client bundle size.
  • Client Components ("use client"): Handle interactivity (onClick, onChange), use React hooks (useState, useEffect), use browser APIs.

Code Example 1: The Server Component (Data Fetching)

tsx
// app/dashboard/page.tsx // Defaults to Server Component import { db } from "@/lib/db"; import ProjectList from "./project-list"; export default async function DashboardPage() { // Direct database access! No generic API needed. const projects = await db.project.findMany(); return ( <main> <h1>My Projects</h1> {/* Pass data to client component */} <ProjectList initialProjects={projects} /> </main> ); }

Code Example 2: The Client Component (Interactivity)

tsx
"use client"; import { useState } from "react"; export default function ProjectList({ initialProjects }) { const [projects, setProjects] = useState(initialProjects); return ( <div> {projects.map(p => ( <div key={p.id} onClick={() => alert(p.name)}> {p.name} </div> ))} </div> ); }

Common Pitfalls

  • Mistake 1: Importing Server Components into Client Components.
    • Don't: Import a heavy server component directly inside a client file (it effectively becomes a client component or breaks).
    • Do: Pass Server Components as children props to Client Components.

Pro Tips

  1. Leaf Interaction: Push the "Client Boundary" as far down the tree as possible. Only the specific button or form needs to be client-side.
  2. Composition: Use the children pattern to wrap server parts inside client context providers without converting everything.

Wrapping Up

Mastering this split is the key to building fast Next.js apps. Fetch on the server, interact on the client.

Tech Stack: Next.js, React, Server Components