In this post, I walk you through all the main rendering strategies in the Next.js App Router: CSR, SSR, SSG, ISR, and even the experimental PPR. We will look at when to use each one, with real examples and simple code you can try yourself. I will also share my experiences and best practices along the way.
This one is very similar to how we used to build classic React apps before frameworks like NextJS.
When you use full Client Side Rendering, Next.js sends an almost empty HTML page. Then the browser runs JavaScript, fetches the data, and builds the page on the client. So the browser does all the work. The server just gives it the basic tools.
You might choose CSR when:
You don’t need SEO (for example, in dashboards or admin panels),
The page is very interactive,
The content is personalized for the logged-in user.
One downside of CSR is that the user might see a loading spinner for a while, especially on slower networks. Also, SEO bots usually can’t read JavaScript, so these pages don’t work well for search engines.
Maybe your page is very heavy has a lots of data manipulation, re-renders, and first-build. It can be good to do it in a server.
But for dynamic apps with lots of interaction, CSR is a good choice. And of course, you can always mix CSR with other strategies.
2. Server-Side Rendering (SSR)
With SSR, Next.js runs your code on the server and sends back a fully rendered HTML page. It fetches data on every request and includes everything in the HTML, including dynamic metadata.
This is useful for SEO and when your data changes often.
Here, the { cache: 'no-store' } tells Next.js to fetch fresh data every time. This keeps the content up to date.
Just a quick tip: when using Server Components like this, you can't use hooks like useState, useEffect, or anything that depends on the browser (like accessing window or navigator). If you need those, you’ll need to use a Client Component. I’ll write more about workarounds for that in a future post, so feel free to subscribe if you’re interested.
3. SSR + CSR Components
Many pages need both good SEO and some interactive features. For example, maybe you want to show a blog post (static content) but also allow users to like it (interactive).
In Next.js, you can mix Server Components (for data fetching and layout) with Client Components (for interactivity). This is a really powerful combo.
The server renders the page with fresh data, and the client handles the like button’s interactivity.
4. Static Site Generation (SSG)
If your page doesn’t change often, and doesn’t use dynamic data — go with SSG.
Think of simple pages like Home Pages , About pages, Pricing tables, Static blog content.
Next.js will generate these pages at build time and serve them as pure HTML. This makes them super fast and great for SEO.
It also means zero* server cost, the server just returns the same file again and again, like a CDN.
@/app/ssg-example/page.tsx
1// No fetch, no revalidate, no dynamic params or searchParams. Just plain static content.2exportdefaultfunctionPage(){3return<div>
But what if you still need to fetch some data, like a list of features or testimonials, but that data rarely changes?
You can use cache: "force-cache" in a Server Component. This tells Next.js to fetch the data at build time and reuse the result on every request — just like classic SSG.
@/app/ssg-fetch-example/page.tsx
1import{Post}from"@/lib/types";23// A static page that fetches data at build time4exportdefault
✅ This fetch only runs once during the build. ✅ Great for rarely-changing content. ❌ You need to rebuild your app to see updated data.
If you want the same fast speed but want to update the content automatically after a while, check out ISR below 👇
5. Incremental Static Regeneration (ISR)
ISR is one of the best features of Next.js. It gives you the speed of static pages and the ability to update them without rebuilding your whole site.
Normally, if you use SSG (Static Site Generation), your page is built once when you deploy. If something changes in your data, you'd have to rebuild and redeploy your whole app to see the updates.
Here’s how it works:
The page is built and cached at build time (just like SSG).
You can set a revalidate time, like every 60 seconds.
While the cached version is served to users, Next.js checks if it’s time to update.
If it's time, the next user who visits the page will trigger a rebuild in the background.
That user still sees the old page, but the next one gets the updated version.
So, the page is regenerated quietly while your site stays online and fast.
Pages that change sometimes (like product listings, articles, events)
You want the performance of static and the freshness of dynamic
Great when rebuilding the site every time is too expensive
ISR is what makes scalable content possible, especially if you have hundreds or thousands of pages. You don’t need to rebuild the whole site. Just let Next.js handle it automatically in the background.
6. Partial Prerendering (PPR)
This one’s still experimental, but super interesting.
Imagine your page loads instantly with static HTML for the layout, header, footer, product info, but the personalized parts (like a shopping cart or profile info) or "how many product left?" sections can be loaded afterwards, with a loading spinner.
You can do that with PPR, using <Suspense>, Client Components, and React streaming.