First off, why should you care about rendering? It’s all about how and when your app’s HTML gets generated and shipped to the user. Get it right, and your app feels fast, ranks high on Google, and keeps folks coming back. Mess it up, and you’re dealing with slow loads or a janky experience.
Hey everyone! Today, I’m diving deep into a topic that’s honestly a game-changer if you’re building web apps with Next.js: mastering rendering strategies. Whether you’re using the classic Pages Router or the shiny new App Router (introduced in Next.js 13), this framework gives you a ton of flexibility with Server-Side Rendering (SSR), Static Site Generation (SSG), Incremental Static Regeneration (ISR), and Client-Side Rendering (CSR). Each method has its own vibe, and knowing when to use them can level up your app’s performance, SEO, and user experience. I’m going to break it all down—Pages Router and App Router styles—with clear, practical examples so you can see how it works in real life. Let’s get into it!
First off, why should you care about rendering? It’s all about how and when your app’s HTML gets generated and shipped to the user. Get it right, and your app feels fast, ranks high on Google, and keeps folks coming back. Mess it up, and you’re dealing with slow loads or a janky experience. Next.js hands you a toolbox—SSR, SSG, ISR, CSR—and even lets you mix them up. So, let’s explore each one, starting with the Pages Router and then layering in the App Router goodness.
SSR is where the server generates HTML for every request. User hits your page, server fetches data, builds the HTML, and sends it over. It’s perfect for dynamic, ever-changing content like news feeds or personalized profiles.
Data updates constantly (think live scores or social media).
SEO matters for dynamic pages.
You want content visible fast without relying on client-side JavaScript.
// pages/profile/[id].js
export async function getServerSideProps(context) {
const { id } = context.params;
const res = await fetch(`https://api.example.com/users/${id}`);
const user = await res.json();
return {
props: { user },
};
}
function Profile({ user }) {
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
}
export default Profile;
// app/profile/[id]/page.js
async function fetchUser(id) {
const res = await fetch(`https://api.example.com/users/${id}`);
return res.json();
}
export default async function ProfilePage({ params }) {
const user = await fetchUser(params.id);
return (
<div>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
}
Pros: SEO-friendly, always fresh data.
Cons: Slower first load, server gets busy.
SSG pre-renders pages at build time, creating static HTML files served via a CDN. It’s like baking a cake once and handing it out—no per-request cooking required.
Content is mostly static (blogs, marketing pages).
You want lightning-fast load times.
SEO’s key, but data doesn’t change often.
// pages/posts/[slug].js
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`);
const post = await res.json();
return {
props: { post },
};
}
export async function getStaticPaths() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
const paths = posts.map(post => ({ params: { slug: post.slug } }));
return { paths, fallback: false };
}
function Post({ post }) {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
}
export default Post;
// app/posts/[slug]/page.js
async function fetchPost(slug) {
const res = await fetch(`https://api.example.com/posts/${slug}`);
return res.json();
}
export async function generateStaticParams() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return posts.map(post => ({ slug: post.slug }));
}
export default async function PostPage({ params }) {
const post = await fetchPost(params.slug);
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
}
Pros: Crazy fast, cheap hosting, SEO-ready.
Cons: No real-time data, rebuilds needed for updates.
ISR blends SSG’s speed with periodic updates. Pages are static at build time, but Next.js regenerates them in the background after a set interval—perfect for semi-static content.
Content updates occasionally (product pages, news).
You want static speed with some freshness.
// pages/products/[id].js
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/products/${params.id}`);
const product = await res.json();
return {
props: { product },
revalidate: 60, // Regenerate every 60 seconds
};
}
// app/products/[id]/page.js
async function fetchProduct(id) {
const res = await fetch(`https://api.example.com/products/${id}`, {
next: { revalidate: 60 },
});
return res.json();
}
Pros: Fast like SSG, updates without full rebuilds.
Cons: Slight data staleness, more complex than pure SSG.
SEO first? SSR or SSG (both routers).
Speed king? SSG or ISR.
Real-time? SSR or CSR.
Budget-friendly scaling? SSG/ISR with a CDN.
Test with Lighthouse to see what sticks!
Mastering Next.js rendering is about matching your app’s needs—speed, freshness, interactivity, SEO—to the right strategy. Pages Router gives you getServerSideProps
, getStaticProps
, and friends, while App Router streamlines it with Server Components, generateStaticParams
, and 'use client'
. SSR keeps things dynamic, SSG and ISR deliver static speed with flexibility, and CSR handles the fancy client-side bits. Mix them up, experiment, and you’ll build apps that feel polished and fast.
So, Pages Router or App Router? What’s your go-to rendering trick? Drop it below—I’d love to hear how you’re rocking Next.js!
Get the latest posts delivered right to your inbox!