The great rendering debate has three players: Static Site Generation (SSG), Server-Side Rendering (SSR), and Single-Page Apps (SPA). Each one solves a different problem. Each one has a cost. The catch: you're not picking one for your entire site anymore. You're picking per-route, per-page, per-use-case. A marketing landing page? Static. A user dashboard? SPA. A blog post that needs dynamic metadata? SSR. The old assumption — "pick one rendering strategy and build everything there" — is dead. Welcome to hybrid rendering in 2026.
The Three Modes Defined
SSG — Static Site Generation
Generate all pages at build time. You run `npm run build`, Astro (or Next.js or any SSG tool) pre-renders every route to plain HTML files. Upload to a CDN. That's it. The HTML is already done. When a user requests `/pricing`, they get instant HTML — no waiting for a server to think.
Pros: Blazing fast (CDN-edge serving, zero server cost), perfect SEO (search engines see complete HTML), simple deployment (upload static files), zero runtime overhead.
Cons: Can't show personalised data ("Hi, [user name]"), can't generate unique meta tags per product variant, slow iteration (rebuild the whole site on every content change), no real-time data on the page.
Deploy: Netlify, Vercel, S3 + CloudFront, Cloudflare Pages. Cheapest option. Sometimes free tier covers it.
SSR — Server-Side Rendering
Render pages on the server when the user requests them. Node.js (or another runtime) generates the HTML in-flight, adds personalised data, and ships it to the browser. By the time the browser receives the HTML, it's already got the user's name, their recent orders, their preferences baked in.
Pros: Personalisation built-in, dynamic meta tags (perfect for SEO when you have product variants or dynamic pages), real-time data on first load, incremental builds (don't have to rebuild the whole site on every content change).
Cons: Slower than static (server has to think), higher operational cost (you're running a server 24/7), more complexity (caching strategy, database connections, error handling), can feel slower than SPA once hydrated because page transitions require a server round-trip.
Deploy: Netlify Functions, Vercel Serverless, AWS Lambda + API Gateway, anything Node.js. Costs scale with traffic.
SPA — Single-Page App
Ship a JavaScript bundle that runs in the browser. The initial load fetches HTML + JavaScript. Then the browser takes over. Every navigation is instant (no server round-trip). You click a link, the JavaScript router handles it, the page transitions without reloading. Once hydrated, interactions feel snappy. Click and go.
Pros: Instant page transitions (no server round-trip latency), rich interactivity (animations, live data, real-time updates), perfect for dashboards and authed content (everything's in the browser, protected by auth logic).
Cons: Slower initial load (user waits for JavaScript to download), bad SEO (crawlers see an empty shell, not the rendered content), more JavaScript in the browser (larger bundle size), hydration overhead (the browser has to hydrate the entire app on first load).
Deploy: Any static host (Netlify, Vercel, S3). Client-side routing means no server logic needed, but you still need a backend for data (API).
The Three-Mode Decision Tree
Here's the mental model: ask three questions.
- Does this page need personalisation or dynamic data on first load? Yes → SSR. No → keep going.
- Is this content behind an auth wall (dashboard, member area)? Yes → SPA. No → keep going.
- Does this page benefit from instant transitions? Yes → SPA (if authed) or SSR with progressive enhancement. No → SSG.
Applied:
- Marketing landing page: No personalisation, no auth, no need for instant transitions. → SSG. Build once, serve from CDN forever.
- Blog post: Public content, SEO matters, no personalisation needed. → SSG. Same deal.
- Product page with dynamic reviews/ratings: Needs personalised "your rating" badge, dynamic star count. → SSR or SSG with client-side data fetch. If SEO is critical (and it usually is for product pages), → SSR.
- User dashboard: Everything is personalised, only visible to authed users, needs instant navigation. → SPA with React Router. Auth check on client, no SEO value anyway (it's behind a login).
- Blog post with personalized recommendations: Public for SEO, but shows personalised "related articles for you" below the fold. → SSG the main post (for SEO), load recommendations client-side (SPA hydration) after auth.
Real-World Hybrid Pattern: Astro + React + API
Here's the pattern that wins in 2026: Astro (SSG by default), flip to SSR per-route, ship islands (React) as SPA hydration inside static pages, and use a backend API for real-time data.
The architecture:
Most pages are SSG. `/` (home), `/pricing`, `/blog/*` — all static. Built at deploy time, served instant. Then for dynamic pages, flip the switch:
// src/pages/products/[slug].astro
export const prerender = false; // ← SSR mode on this route only
const { slug } = Astro.params;
const product = await fetch(`/api/products/${slug}`).then(r => r.json());
// Page renders with dynamic data
That one file now server-renders. Astro generates each product page on-demand, caches it (usually), and serves it. The rest of your site is still static.
For the dashboard, you export a React Router SPA:
// src/pages/dashboard/[...route].astro
export const prerender = false;
// Ship the React Router app directly
import Dashboard from '../../components/Dashboard.tsx';
<Dashboard client:only />
Now `/dashboard/*` is a true SPA. The user sees a loading state, JavaScript loads, React Router takes over, the dashboard renders client-side. Auth is checked in the browser. All navigation is instant.
Your marketing site is fast (SSG CDN edge serving). Your product pages are SEO-friendly (SSR). Your dashboard is snappy (SPA). One codebase. Three rendering modes.
Performance Comparison at a Glance
First Contentful Paint (FCP):
- SSG: ~500ms (pre-rendered HTML served from CDN edge)
- SSR: ~1000ms (server has to query DB, render, send HTML)
- SPA: ~2000ms (download JS, parse, hydrate, render)
Largest Contentful Paint (LCP):
- SSG: ~800ms (all content is in HTML)
- SSR: ~1500ms (depends on server latency + DB latency)
- SPA: ~2500ms+ (JS, hydration, then render)
Time to Interactive (TTI):
- SSG: ~1500ms (HTML is interactive immediately, islands hydrate on schedule)
- SSR: ~2000ms (HTML is interactive, but hydration happens after)
- SPA: ~3000ms+ (nothing is interactive until JS loads and hydrates)
Page Transitions (after initial load):
- SSG → SSG: ~500ms (browser requests pre-rendered HTML)
- SSR → SSR: ~1500ms (server round-trip + render)
- SPA: ~50ms (client-side routing, instant)
The insight: SSG is fastest for initial load, but every page transition requires a server round-trip (even between static pages, the browser has to fetch). SPA is slowest initially, but fastest for transitions. SSR is the middle ground — slower than SSG initially, but you get personalisation and SEO.
Six FAQs
Can I hybrid-render a single page?
Yes. SSG the page, then load personalised data client-side after auth. The blog post loads instantly (static), then your React island fetches recommendations client-side (SPA hydration). Content is public, personalisation is private.
Doesn't SSR hurt SEO because it's dynamic?
No. Google crawls server-rendered pages just fine. It sees the full HTML (because you rendered it server-side before sending it). SSR is actually great for SEO because you can set dynamic meta tags, canonical URLs, and structured data per-page.
What about incremental static regeneration (ISR)?
ISR (supported in Vercel, Netlify) lets you rebuild pages on a schedule without rebuilding the whole site. A blog post rebuilds every hour, so it's fresh but still fast. It's SSG with a revalidation timer. Use it when you want static speed but can't wait for a full build.
Should my dashboard be SSG, SSR, or SPA?
SPA. Dashboards are behind auth, content is personalised per-user, and instant transitions matter. No point in server-rendering a page that's going to be different for every user. Render it client-side, protect it with auth, and let the user navigate without server latency.
How do I pick between SSR and SPA for a personalised page?
Ask: Is this page public and SEO-critical? Yes → SSR (render server-side, set meta tags, crawlers see full HTML). No → SPA (render client-side, check auth in browser, faster transitions after initial load).
Can I use View Transitions with SSG, SSR, and SPA?
Yes. View Transitions work with any rendering mode — they just make the page transition animate. SSG pages transition crisp. SSR pages transition with server latency. SPA pages transition instant. The animation layer is agnostic.
The Bottom Line
There's no one-size-fits-all rendering mode in 2026. You mix them. Marketing sites are SSG (fast, cheap, CDN-edge serving). Personalised content is SSR (dynamic data, great SEO). Dashboards are SPA (instant transitions, client-side auth). One codebase, three strategies, each playing to its strengths.
The decision tree is simple: Does this page need personalisation on first load? No → SSG. Yes and it needs SEO? → SSR. Yes and it's authed? → SPA. Does it need instant transitions? → SPA. Otherwise → SSG.
This is how Aidxn Design sites scale. Static sites for marketing (under 50KB), server rendering for product catalogs (with personalized SEO tags), SPAs for logged-in users (instant interactions). One architecture, three modes, zero waste.
Building your next site and unsure which rendering strategy to pick? Let's design it together — we'll architect it for your users, not the framework.