CSR, SSG, SSR & ISR Rendering Strategies
A rendering strategy is the rule that decides, for a given URL, whether the HTML is produced at build time, on the server per request, on a revalidation schedule, or in the browser. It is the most consequential SEO decision in a JavaScript application because it determines whether content lands in the first wave of Googlebot’s rendering pipeline or waits in the deferred render queue. This guide gives you a per-route framework for choosing among the four modes and sits under the broader prerendering and SSR strategies section.
Prerequisites
- A meta-framework that supports per-route rendering (Next.js, Nuxt 3, SvelteKit, Remix/React Router 7) or a build pipeline that can prerender routes.
- A route inventory: a list of every public URL pattern and the data each depends on.
- Search Console access to measure time-to-index before and after changing a route’s mode.
- A baseline of which routes currently earn organic traffic, so you prioritize the highest-value pages.
The decision: two axes
Map each route against two questions — how fresh must the data be? and how important is this route for organic search? Those axes point you at a rendering mode.
How it breaks
The most common failure is treating rendering as a global setting. A team ships an entire storefront as a single-page app because the dashboard needed to be interactive, and the product pages — the routes that actually earn search traffic — inherit CSR and get indexed as empty shells. The symptom in Search Console is Crawled — currently not indexed on high-value URLs, or a rendered-HTML snapshot that shows only the loading skeleton.
<!-- ❌ Product page shipped as CSR: crawler sees no product data in the first wave -->
<div id="root"></div>
<script src="/bundle.js" defer></script>
Step-by-step fix
-
Inventory routes by data freshness. Tag each route
static,periodic, orlive. Anythingstaticis an SSG candidate;periodicmaps to ISR;livemaps to SSR or CSR. -
Set the per-route mode. In Next.js App Router, the fetch cache and
revalidateexpress the mode:// app/products/[id]/page.jsx export const revalidate = 0; // SSR: always fresh, rendered per request // export const revalidate = 3600; // ISR: regenerate at most hourly // export const dynamic = 'force-static'; // SSG: build onceThe same intent in Nuxt 3 is expressed through route rules:
// nuxt.config.ts export default defineNuxtConfig({ routeRules: { '/': { prerender: true }, // SSG '/blog/**': { isr: 3600 }, // ISR '/products/**': { ssr: true }, // SSR '/app/**': { ssr: false }, // CSR island }, }); -
Confirm content is in the response. For every route you changed,
curlthe URL and grep for the primary heading or price. If it is absent, the mode is not actually applying. -
Keep metadata aligned with the mode. Whatever mode you choose, titles, canonicals, and structured data must render in the same pass — coordinate with dynamic metadata management so the
<head>is never left to a later client update.
Gotchas & edge cases
- SSG with stale data. A statically generated price that changes daily will mismatch the live page; use ISR with a short revalidate window instead of full SSG.
- SSR personalization leaking into the cache. Rendering user-specific content on a cacheable SSR route can serve one user’s data to others or to the crawler. Keep personalized fragments client-side.
- CSR fallbacks that never fire for bots. A
<noscript>fallback is not a substitute for indexable content; crawlers execute JavaScript and ignore most<noscript>shells. - Choosing CSR for “speed.” CSR lowers TTFB but pushes Largest Contentful Paint to the client, often hurting Core Web Vitals more than SSR’s higher TTFB would.
Validation checklist
Performance & crawl-budget notes
Moving SEO-critical routes off CSR removes them from the render queue, so they index in the first wave and stop consuming the JavaScript execution budget on every change. On large catalogs this is the difference between hours-to-index and weeks-to-index, and it frees render capacity for the genuinely dynamic routes that still need it. Track the impact through crawl-budget signals.
Go deeper
- Choosing between CSR, SSR, SSG, and ISR — a head-to-head walkthrough with a decision checklist for real route types.
- Hydration strategies compared: full, partial, streaming — once you render on the server, how you hydrate determines interactivity cost and layout stability.
Frequently Asked Questions
Can I mix rendering strategies in one application? Yes. Meta-frameworks like Next.js, Nuxt, and SvelteKit let you set the rendering mode per route or per page. A typical app statically generates marketing pages, server-renders inventory pages, incrementally regenerates blog content, and leaves authenticated areas client-rendered.
Which rendering mode is best for SEO? Any mode that puts your primary content in the initial HTML response is good for SEO — SSG, SSR, and ISR all qualify. Pure CSR is the only mode that defers content to the rendering queue, so reserve it for routes that do not need to rank.
Related
- Client-Side vs Server-Side Rendering for SEO — the underlying CSR-versus-SSR trade-off in depth.
- Dynamic rendering and bot prerendering — how to make a CSR route crawlable without a full rewrite.
- Incremental and streaming SSR for SEO — reduce the server cost of SSR while keeping content crawlable.
← Back to Prerendering & SSR Strategies