Server vs Client Components — How to Decide

▲ Next.js 15+ (App Router) 🟢 Chapter 12 of 43 📂 Phase 5: Server & Client Components 📅 2026 Edition
📌 Covered in this chapter: Decision Framework · Static vs Interactive Content · Component Boundary Placement · Passing Serializable Props · Reducing Client JS
Previous rendu chapters లో Server, Client Components ఎలా pని చేస్తాయో chusాము. Ee chapter lో, real projects lo eవి ఎప్పుడు వాడాలో decide చేసే practical framework నేర్చుకుందాం.
1The Simple Decision Rule

Component design చేసేటప్పుడు, ఈ ఒక్క question అడగండి: "ఈ component కి interactivity (state, event handlers, browser APIs) కావాలా?"

  • NO → Server Component గా ఉంచండి (default, ఏమీ చేయనవసరం లేదు)
  • YES → ఆ specific piece ni "use client" Component గా extract చేయండి
2Decision Table with Real Examples
Use CaseComponent TypeWhy
Blog post content, product descriptionsServerStatic, no interactivity needed
Like button, add-to-cart buttonClientNeeds onClick + state
Search bar with live filteringClientNeeds useState for input value
Navigation bar (static links)ServerJust renders links, no state
Dropdown menu (open/close toggle)ClientNeeds useState for open state
Database-driven data table (read-only)ServerJust fetches & displays data
3Pattern: Server Wrapper + Client Island

Most common real-world pattern — page mొత్తం Server Component గా ఉంచి, interactivity అవసరమైన చిన్న "islands" matrame Client Components గా extract చేయడం:

💻 Example 1: Product Page (Server) + Add-to-Cart (Client)
app/products/[id]/page.tsx ▶ Run in Compiler
import AddToCartButton from "./AddToCartButton";

export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const product = await fetch(`https://api.example.com/products/${id}`).then((r) => r.json());

  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <AddToCartButton productId={id} />
    </div>
  );
}
🔍 Breakdown:

Page itself Server Component — data fetching direct ga జరుగుతుంది. productId (string, serializable) matrame AddToCartButton (separate "use client" file) కి pass అవుతుంది — cart logic client meedhа pని చేస్తుంది.

Server Component (Product Page) ├── Product Title ← rendered on server ├── Product Description ← rendered on server └── AddToCartButton ← "use client" island └── onClick handler, useState (cart count)
⚠️ Common Mistake: Making Parent Client Just for One Child

Page లో ఒక్క button కి interactivity కావాలని, page.tsx మొత్తం top లో 'use client' pెట్టడం — chాలా common mistake. బదులు, ఆ button ని matrame separate client component గా extract చేసి, parent Server Component గానే ఉంచాలి.

💻 Hands-on Interactive Practice Challenge

Given a blog post page that fetches content from an API, extract just the 'Share' button into its own client component, keeping the rest server-rendered.

app/blog/[slug]/ShareButton.tsx ▶ Run in Compiler
"use client";

export default function ShareButton({ url }: { url: string }) {
  return (
    <button onClick={() => navigator.clipboard.writeText(url)}>
      Share This Post
    </button>
  );
}
Run This Challenge in Online Node.js IDE →
Frequently Asked Questions (FAQ)

Q Small projects lో anni components Client గా pెట్టవచ్చా?

Technically avunu, kani performance benefits (small bundle, fast load, SEO) anni pోతాయి. Production apps కి, ఈ decision framework follow చేయడం strongly recommended.

Q Server Component నుండి Client Component కి function pass చేయవచ్చా?

Ledు, functions serializable కావు (except pre-defined Server Actions, Chapter 21 లో చూద్దాం). Strings, numbers, objects, arrays matrame pass చేయవచ్చు.

Q ఈ decision framework ప్రతి project కి same గా apply అవుతుందా?

Core principle (static → Server, interactive → Client) ఎప్పుడూ apply అవుతుంది, kani exact boundary placement project UX requirements meedha depend అవుతుంది.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on Next.js 15+ (App Router) · Last updated August 2026