DEV Community

Mittal Technologies
Mittal Technologies

Posted on

SSR vs CSR vs SSG: How to Pick the Right Rendering Strategy


I once shipped a marketing site as a pure client-side React app. It looked great in demos. Then we checked how Google saw it, and the answer was basically "a blank div and a JavaScript file." Two weeks of rework later, I had a much better understanding of why rendering strategy is an architecture decision, not a framework setting.

If you're weighing SSR vs CSR vs SSG for a new project, here's how I'd think about it. No dogma, just trade-offs I've actually run into.

The three strategies in plain terms

The only real difference is when and where the HTML gets built.

  • CSR (client-side rendering): The server sends a nearly empty HTML shell plus JavaScript. The browser fetches data and builds the page.
  • SSR (server-side rendering): The server builds the HTML on every request and sends it ready to display. The browser then "hydrates" it to make it interactive.
  • SSG (static site generation): The HTML is built once at build time and served as a static file, usually from a CDN.

That's it. Everything else (caching, SEO, cost, complexity) follows from that one choice.

CSR: great for apps, risky for pages people need to find

CSR is what you get from a default Vite + React setup or a classic SPA.

Where it works well:

  • Dashboards and admin panels behind a login
  • Internal tools
  • Highly interactive apps (editors, design tools, trading UIs)

Where it hurts:

  • Slower first paint, since the browser must download, parse, and run JS before showing content
  • Weaker out-of-the-box SEO for public pages
  • Performance varies a lot on low-end phones

If nobody needs to discover the page through search, CSR is completely fine. I've built plenty of behind-login dashboards this way and never regretted it.

Is SSR better than CSR for SEO?

For public pages, yes, in most cases. SSR hands crawlers complete HTML on the first request. Google can render JavaScript, but it does that in a second pass, and it's not something I'd bet a landing page's rankings on. CSR pages can still get indexed; it's just slower and less predictable.

SSR: fresh HTML on every request

SSR shines when content is personalized or changes constantly, and you still want it indexable and fast to first paint.

// Next.js (Pages Router) example
export async function getServerSideProps({ params }) {
  const product = await getProduct(params.id);
  return { props: { product } };
}
Enter fullscreen mode Exit fullscreen mode

Good fits:

  • Product pages with live pricing or stock
  • Search results pages
  • News feeds and anything where staleness is a bug
  • Pages that depend on cookies or request headers

The costs nobody mentions in the tutorial:

  • Every request hits your server, so you're paying for compute and managing latency
  • A slow database query directly delays the whole page (your TTFB is now your problem)
  • Hydration mismatches. I've lost an afternoon to a Date.now() rendering differently on server and client. It happens to everyone once.

SSR isn't automatically faster than CSR. A slow backend behind SSR feels worse than a snappy SPA with a good loading skeleton.

SSG: the underrated default

For content that doesn't change every minute, static generation is hard to beat. Pages are pre-built, sit on a CDN, and load almost instantly. Your server barely works, and your hosting bill stays tiny.

Perfect for:

  • Blogs and documentation
  • Marketing sites and landing pages
  • Portfolio and company sites
  • Help centers

Is SSG faster than SSR?

Usually, yes. Static files come straight from a CDN, while SSR has to generate HTML per request unless you cache it. The catch is build time. Rebuilding 50,000 pages because someone fixed a typo is miserable. That's where incremental static regeneration (ISR) comes in, and it's one of the more practical ideas in modern frameworks:

// Next.js: regenerate this page at most once every 60 seconds
export async function getStaticProps() {
  const posts = await getPosts();
  return { props: { posts }, revalidate: 60 };
}
Enter fullscreen mode Exit fullscreen mode

You get static speed with content that stays reasonably fresh. For a lot of projects, that hybrid covers 80 percent of needs.

A decision framework I actually use

Ask these in order:

  1. Does the page need to rank in search or be shared with previews? If no, CSR is fine. If yes, go to 2.
  2. Does the content change per user or per request? If yes, SSR. If no, go to 3.
  3. Does it change rarely (hours, days)? SSG, or SSG with ISR.
  4. Is part of the page personalized and the rest static? Render the static shell, then fetch the personalized bit on the client.

That last point matters. Rendering strategy doesn't have to be one choice for the whole app. Modern frameworks (Next.js, Nuxt, Astro, SvelteKit, Remix) let you decide per route, so mixing is normal. Marketing pages on SSG, product pages on SSR, account area on CSR. Same repo, three strategies.

Real-World Examples of CSR, SSR, and SSG

Say you're building an e-commerce store:

  • Home and category pages: SSG with short revalidation
  • Product detail pages: SSR or ISR, depending on how often stock and prices change
  • Cart and checkout: CSR, because it's private, interactive, and doesn't need indexing
  • Blog and guides: SSG (static is the best fit for content that rarely changes)

This kind of split affects design and engineering together. If your front end has to look right on every screen while also loading fast, responsive website design and rendering choices need to be planned as one thing. A layout that shifts while hydrating hurts your Core Web Vitals no matter how clean the code is.

Mistakes that keep showing up

  • Picking SSR "because it's better for SEO" without needing it. A static page is often faster and cheaper.
  • Ignoring Core Web Vitals. LCP, INP, and CLS are affected by how you render, not just how you code.
  • Fetching everything client-side on public pages and wondering why crawlers see thin content.
  • Forgetting cache headers. SSR without caching (CDN or edge) can melt under a traffic spike.
  • Over-hydrating. Shipping a huge JS bundle for a page that's mostly text. Islands architecture (Astro) or React Server Components can trim this down.
  • Testing only on a fast laptop. Throttle the CPU and network, and the picture changes quickly.

Workflow tips for teams

A few habits that have saved me time:

  • Decide rendering per route during planning, and write it down in the ticket
  • Run Lighthouse and check real-user metrics, not just local scores
  • View the page source (not the inspector) to confirm what crawlers actually receive
  • Put a CDN in front of SSR routes where content can be cached even briefly
  • Keep a shared component library so rendering changes don't force redesigns

If your team is small or stretched across product work, bringing in a website development company that already understands framework trade-offs can shorten the learning curve. It's especially useful when performance, SEO, and maintainability all matter at once.

And when the project involves more than a front end (design systems, CMS integration, hosting setup, ongoing optimization), working with web design and development services that cover the whole pipeline keeps decisions consistent from wireframe to deployment.

What I'd tell my past self

Start with the question "who needs to see this page, and how fresh must it be?" instead of "which framework feature is trending?" Default to static where you can, server-render where freshness demands it, and keep CSR for the parts that behave like an app.

Most rendering headaches aren't technical. They come from picking one strategy for everything and then fighting it for months.

Top comments (0)