Server Components
Master React Server Components in Next.js — the paradigm that lets components run exclusively on the server, fetch data directly, and ship zero JavaScript to the browser.
Last reviewed: January 2025
🔍 What Is It?
React Server Components (RSC) are components that:
- →Run exclusively on the server — during the request (SSR) or at build time (SSG)
- →Can be async —
async function Page()is valid - →Access server-only resources — databases, file system, environment secrets
- →Ship zero JavaScript — only the rendered HTML/RSC payload reaches the browser
- →Cannot use browser APIs — no useState, no useEffect, no window, no document
In Next.js App Router, every component is a Server Component by default. You opt into client-side behaviour with 'use client' at the top of a file.
🎯 Why Do We Need It?
Before Server Components, React had a fundamental problem: all component logic shipped to the browser as JavaScript, even logic that only ever ran once during render.
- →A component that formats a date shipped moment.js to the browser
- →A component that rendered markdown shipped a markdown parser to the browser
- →A component that fetched from a database needed an API route as a proxy
Server Components eliminate this entirely:
- →Heavy libraries stay on the server — zero bundle impact
- →Direct database queries without API routes
- →Secrets never leave the server
- →Faster page loads — less JS to parse and execute
🏗️ What Happens in Real Projects?
Server Components handle the data-heavy, non-interactive parts of your UI:
- →Product listing pages — fetch from DB, render HTML, no client JS needed
- →Blog posts — fetch from CMS, render markdown, static HTML output
- →Dashboard metrics — query analytics DB directly, render charts as SVG
- →Navigation menus — fetch from CMS, render links, no interactivity needed
What stays as Client Components:
- →Search bars (user typing = state)
- →Shopping cart (add/remove = state)
- →Modals, dropdowns, tooltips (open/close = state)
- →Real-time data (WebSocket, polling)
⚙️ How It Works
Server Component rendering pipeline:
- Next.js receives a request for
/products - It renders the
ProductsPageServer Component on the server - The component runs
await db.query(...)— direct DB access - React renders the component tree to an RSC payload (not plain HTML)
- Next.js converts the RSC payload to HTML and streams it to the browser
- The browser displays the HTML immediately — no JS needed for static parts
- Client Components in the tree hydrate separately
The RSC payload is a JSON-like format that describes the component tree. On client-side navigation, Next.js fetches the RSC payload (not a full HTML page) and merges it into the existing React tree.
💻 Example
Server Component Patterns — Real patterns for Server Components in production — direct DB access, parallel fetching, and composition with Client Components.
🤔 Common Confusions
❓ Can I import a Client Component into a Server Component?
Yes — and this is the normal composition pattern. A Server Component can render Client Components as children. The Server Component fetches data and passes it as props to the Client Component. The boundary goes one way: Server can import Client, but Client cannot import Server (it would break the server-only guarantee).
❓ Are Server Components the same as SSR?
Related but different. SSR (Server-Side Rendering) renders the entire React tree on the server for every request, including Client Components. Server Components are a subset that ONLY runs on the server — they never hydrate. A page can have both: Server Components that never hydrate, and Client Components that do.
❓ Can I pass a function as a prop from a Server Component to a Client Component?
No. Props crossing the Server/Client boundary must be serialisable — plain objects, arrays, strings, numbers, booleans. Functions are not serialisable. To pass behaviour, use Server Actions (functions marked with "use server") or handle the logic in the Client Component itself.
🚨 Common Production Issues
N+1 query problem — rendering a list of Server Components where each fetches its own data causes N sequential DB queries. Use DataLoader, batch queries, or fetch all data at the parent level and pass it as props.
Secrets in shared modules — if a module imported by a Server Component is also imported by a Client Component, it may end up in the client bundle. Use the server-only package to throw a build-time error if a server module is accidentally imported client-side.
Missing Suspense boundaries — a Server Component that throws during data fetching will crash the entire page unless wrapped in an error.tsx boundary. Always add error boundaries around data-fetching components.
✅ Best Practices
Use the server-only package for modules that must never reach the client bundle
Fetch data as close to where it is used as possible — avoid prop drilling data through many layers
Use Promise.all for parallel fetching — never await multiple independent fetches sequentially
Wrap each independently-loading Server Component in Suspense for streaming
Keep Server Components pure — same input always produces same output (no random IDs, no Date.now() without care)
🏛️ Architect's Note
Server Components represent a fundamental shift in how we think about the client-server boundary. In the Pages Router era, the boundary was at the page level. In the App Router, the boundary is at the component level — you can have Server and Client Components interleaved in the same tree.
The architectural implication: API routes become optional for most use cases. If a Server Component can directly query the database, you don't need an API route to proxy that data. Reserve API routes for external consumers, webhooks, and truly public APIs. Internal data fetching belongs in Server Components.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
↗ Where this topic fits
Next.js Technology Guide
Return to the Next.js learning hub.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Next.js references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Next.js learning path
Browse the full Next.js topic collection and learning order on SplashRide.
Next.js Interview Prep
Practice Next.js interview questions and scenario-based answers.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Client Components
Understand Client Components in Next.js — when to use them, how they interact with Server Components, and how to keep your client bundle lean.
Next.js App Router Explained: Server Components, Layouts, and Routing
Learn the Next.js App Router with Server Components, nested layouts, streaming, Route Handlers, data fetching, and Pages Router migration guidance.