Someone produced the HTML your browser receives. The question is: when did they produce it?
The answer is roughly one of four. At build time. When the user asked. It was produced earlier and refreshed in the background. Or it was never produced at all, and the browser drew it itself.
In modern Next.js this is less about "picking a strategy" and more about asking each piece of content "when should this be produced?". Below are the five approaches, in order.
CSR (Client-Side Rendering)
Writing "use client" in the App Router does not make a component CSR on its own. The component can still be rendered on the server on the first request and included in the HTML. If you genuinely want to turn server rendering off and move rendering to the client, you use a dynamic import with ssr: false.
CSR makes sense for interactive screens that use window / document, are browser-specific, or where SEO doesn't matter. But if SEO and a fast first render do matter, leaving everything to CSR is usually a bad trade: the browser first gets an empty shell, downloads and runs the JS, fetches the data in a separate request, and only then is the content drawn.

SSG (Static Site Generation)
The page is generated at build time. Data is fetched during the build, and the resulting HTML is produced statically and deployed to the CDN. When a user makes a request, no data is fetched on the server again; the CDN returns the ready HTML directly.
Because of this, TTFB (Time to First Byte) is not affected by how long a data fetch takes at request time.
The downside is that updating the content requires another build and deploy, and with very large datasets the build time can grow significantly.

ISR (Incremental Static Regeneration)
ISR sits between SSG and SSR by letting static pages be regenerated under certain conditions. The page is generated at build time, and revalidate sets its cache lifetime.
revalidate: 60 does not mean "refresh every 60 seconds". After the window expires, the first request to arrive gets the existing HTML and a new page is generated in the background. The next request gets the new content.
So ISR uses request-driven regeneration; no traffic means no regeneration.
revalidateTag can trigger cache invalidation without waiting for the window to expire.
The downside: for data that has to be accurate right now, like stock levels, live prices, or remaining seats, a user seeing stale data is not acceptable.

SSR (Server-Side Rendering)
When a user requests the page, Next.js fetches the data it needs on the server, produces the HTML, and sends it back as the response.
In the App Router, SSR matters especially for data that is request-dependent or needs to be current. When you use dynamic APIs like cookies(), headers(), searchParams, or an uncached data fetch, the route is rendered dynamically.
In return, because server-side work happens on every request, TTFB is affected by the data source's latency. SSR gives you current and personalized content, but the cost is server-side rendering per request.

PPR (Partial Prerendering)
PPR is a rendering approach that combines a page's static and dynamic sections in the same response.
The static shell is prepared during the build, with placeholders left for the dynamic sections. When a user makes a request, the shell is sent immediately; the dynamic parts are filled into the same response as the server prepares them.
In the earlier strategies a page was treated as static or dynamic as a whole. With PPR you can render only the part of the page that is genuinely dynamic at request time.
In Next.js 16, cacheComponents: true shifts the model further: you mark what should be cached explicitly with use cache.
Watch out: if dynamic content isn't separated by a Suspense boundary, it can block the whole shell. Fallback design also matters; the user sees the fallback first, then the real content.

TL;DR
In practice the question is no longer "which rendering strategy should I use?". You look at the content itself first:
- Is this content specific to the user?
- How often does it change, and is it acceptable for someone to see an old version?
- More importantly, does this dynamic part really need to hold up the rest of the page?
The answers decide whether the content is prepared at build time, cached and refreshed on some schedule, or rendered on every request. In the modern Next.js rendering approach the goal isn't to pick a single strategy, it's to render each piece of content at the right time for what it needs.
