Understanding how Next.js renders your pages is crucial for building fast, scalable, and SEO-friendly web applications. In this article, we’ll explore Client-Side Rendering (CSR), Server-Side Rendering (SSR), Static Site Generation (SSG), and Incremental Static Regeneration (ISR) — their differences, pros/cons, and when to use them.
🔍 Overview
Next.js offers four main rendering strategies:
- CSR (Client-Side Rendering): Rendering happens in the browser.
- SSR (Server-Side Rendering): HTML is rendered on each request.
- SSG (Static Site Generation): HTML is generated at build time.
- ISR (Incremental Static Regeneration): Pages are pre-built but can be revalidated after deployment.
Key Concepts
- Hydration: Turning static HTML into an interactive React app.
- FCP (First Contentful Paint): When first content appears.
- TTI (Time To Interactive): When page is fully usable.
- SEO: How search engines crawl and index your content.
⚡ Client-Side Rendering (CSR)
How it Works
- Minimal HTML is served.
- Browser downloads JavaScript.
- JavaScript fetches data and renders UI.
✅ Pros & ❌ Cons
- ✅ Great for interactivity
- ✅ Light on the server
- ❌ Poor SEO (blank HTML initially)
- ❌ Slower first load
Example
import { useState, useEffect } from 'react';
export default function CSRExample() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('/api/posts').then(res => res.json()).then(setPosts);
}, []);
return (
<div>
<h1>Posts (CSR)</h1>
{posts.map(p => <p key={p.id}>{p.title}</p>)}
</div>
);
}
👉 Best For: Dashboards, private content, real-time apps.
🌐 Server-Side Rendering (SSR)
How it Works
- Request comes in.
- Server fetches data.
- HTML is generated and sent.
- Browser hydrates the page.
✅ Pros & ❌ Cons
- ✅ Fresh data every request
- ✅ Great SEO
- ❌ Slower response time
- ❌ Higher server load
Example
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return { props: { posts } };
}
export default function SSRExample({ posts }) {
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}
👉 Best For: E-commerce, news, personalized content.
🚀 Static Site Generation (SSG)
How it Works
- At build time, Next.js generates HTML.
- Pages are cached on CDN.
- Super-fast delivery.
✅ Pros & ❌ Cons
- ✅ Fastest load times
- ✅ Great SEO
- ✅ Very scalable
- ❌ Stale content until rebuild
Example
import { notFound } from "next/navigation";
async function getPost(id) {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`,
);
if (!res.ok) {
return null;
}
return res.json();
}
export async function generateStaticParams() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
return posts.map((post) => ({
id: post.id.toString(),
}));
}
export default async function PostPage({ params }) {
const post = await getPost(params.id);
if (!post) {
notFound();
}
return (
<main>
<h1>{post.title}</h1>
<p>{post.body}</p>
</main>
);
}
👉 Best For: Blogs, docs, marketing pages.
🔄 Incremental Static Regeneration (ISR)
How it Works
- Pages are generated at build time (like SSG).
- Pages are revalidated in the background.
- Next visitors get the fresh content.
✅ Pros & ❌ Cons
- ✅ Speed of SSG + freshness of SSR
- ✅ No full rebuilds needed
- ❌ Temporary stale content
Example
export const revalidate = 60
import { notFound } from "next/navigation";
async function getPost(id) {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`,
);
if (!res.ok) {
return null;
}
return res.json();
}
export async function generateStaticParams() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
return posts.map((post) => ({
id: post.id.toString(),
}));
}
export default async function PostPage({ params }) {
const post = await getPost(params.id);
if (!post) {
notFound();
}
return (
<main>
<h1>{post.title}</h1>
<p>{post.body}</p>
</main>
);
}
👉 Best For: E-commerce catalogs, news sites, frequently updated blogs.
📊 Comparison Chart
Feature | CSR | SSR | SSG | ISR |
---|---|---|---|---|
Initial Load | Slow | Medium | Fastest | Fast |
SEO | Poor | Excellent | Excellent | Excellent |
Freshness | High | High | Low | Medium |
Server Load | Low | High | Very Low | Low |
Best For | Apps | Dynamic pages | Blogs, docs | Hybrid needs |
💡 When to Use What
- CSR: Dashboards, authenticated apps, real-time updates.
- SSR: SEO + fresh content, e-commerce, user-specific pages.
- SSG: Marketing sites, blogs, documentation.
- ISR: Large sites, e-commerce catalogs, news portals.
🎯 Exercises for You
- Pick a blog and implement SSG with dynamic routes.
- Create a dashboard with CSR (fetch on client).
- Build a news site homepage with ISR.
- Compare performance using Lighthouse.
📌 Final Thoughts
Each rendering strategy in Next.js serves different needs:
- CSR = Flexibility
- SSR = Real-time + SEO
- SSG = Performance
- ISR = Balance between speed and freshness
By mixing them wisely, you can build fast, SEO-friendly, and scalable apps.
Top comments (0)