Server-side rendering (SSR) is a web development technique where the server generates complete HTML for each page request before sending it to the browser. Unlike client-side rendering (CSR), where the browser receives an empty container and relies on JavaScript to populate it, SSR delivers fully rendered content immediately — visible to users and crawlers without any JavaScript execution required.
If your site relies on JavaScript to render content, Googlebot may never see it. SSR solves this by delivering complete HTML directly — the same content a user sees is what the crawler indexes, with no JS dependency.
What is server-side rendering?
Server-side rendering is a web architecture where a server generates the full HTML of a page — including all text, headings, and structured data — before sending the response to the browser. The browser receives a complete document it can immediately display.
The SSR request cycle works in six steps:
- User's browser requests a URL
- Server receives the request
- Server fetches data from databases or APIs
- Server renders the HTML with all content embedded
- Browser receives complete HTML and displays it immediately
- JavaScript hydrates the page to add interactivity (event listeners, state)
Google has confirmed that Googlebot may not wait for all JavaScript execution when crawling. Google processes JavaScript in a second wave, which can delay indexing by days or weeks. SSR eliminates this risk — Googlebot receives the complete HTML on the first crawl pass.
Why server-side rendering matters for SEO
SSR has direct consequences for crawlability, Core Web Vitals, and social sharing. Four reasons SEOs care:
- Full crawlability without JavaScript. Googlebot, Bingbot, and social crawlers receive complete HTML immediately. No second-wave JavaScript rendering required, which means content is indexed faster and more reliably.
- Better Largest Contentful Paint (LCP). With SSR, the LCP element is already in the initial HTML. The browser can begin painting it as soon as the HTML parses, without waiting for a JavaScript bundle to execute and inject content.
- Correct social sharing previews. Twitter, LinkedIn, and Facebook crawlers don't execute JavaScript. SSR ensures OG tags and page content are visible to these crawlers, so link previews display correctly.
- Accessibility. Users with JavaScript disabled or screen readers relying on static markup receive full content from an SSR page. CSR pages are blank or broken without JavaScript.
How server-side rendering works — SSR vs CSR
| Factor | SSR | CSR |
|---|---|---|
| Initial HTML | Complete content | Empty container |
| First Contentful Paint | Immediate | After JS bundle loads |
| JavaScript required | No (for content) | Yes (for all content) |
| TTFB | Slower (server renders) | Faster (minimal HTML) |
| Server load | Higher | Lower |
| Crawlability | Excellent | Dependent on JS execution |
SSR vs SSG vs CSR — when to use each
These three architectures cover different content and traffic patterns. Choosing the wrong one creates either a performance problem or an indexability problem.
| Scenario | Best choice | Reason |
|---|---|---|
| Blog or marketing site | SSG | Content rarely changes; pre-built HTML is fastest |
| E-commerce product pages | SSR | Prices and inventory change constantly |
| User dashboards | SSR | Personalised content per user |
| Documentation site | SSG | Stable content, speed priority |
| News site with live updates | SSR | Content changes by the minute |
| SPA needing SEO | SSR + hydration | Complex interactivity with crawler support |
SSR frameworks and implementations
Every major frontend framework now has an official SSR solution:
- Next.js (React) —
getServerSidePropsor App Router with server components. The most widely deployed SSR framework. - Nuxt.js (Vue) —
asyncDataandfetchhooks. Vue's official SSR layer. - SvelteKit — server routes and page endpoints with built-in SSR, ships minimal JS by default.
- Angular Universal — Google's official Angular SSR module.
- Astro — server-first architecture with hybrid SSR/SSG, ships zero JS by default for static content.
SSR challenges and how to mitigate them
SSR has real trade-offs. Understanding them prevents common implementation mistakes:
SSR advantages
- Full crawlability without JavaScript
- Better LCP and FCP metrics
- Correct social sharing previews
- Works for users with JS disabled
- Fresh content on every request
SSR trade-offs
- Higher TTFB (server must render first)
- More server resources per request
- Hydration complexity and mismatch errors
- Waterfall data fetching risk
- Harder to cache than static files
The TTFB trade-off is the most important: SSR adds 200-500 ms of server rendering time to TTFB compared to a static file serve. Mitigate this with CDN edge caching, streaming SSR, and stale-while-revalidate patterns.
5 best practices for SSR implementation
- Cache rendered pages at the CDN edge. For pages that don't change per user, cache the SSR output at the CDN for 60 seconds or more. This gives you SSR crawlability with SSG performance for most requests.
- Use streaming SSR. Send the HTML head and page shell immediately while streaming the body as it renders. Users see a fast first paint even if data fetching takes time.
- Implement stale-while-revalidate. Serve the cached SSR response immediately and re-render in the background. Avoids TTFB spikes on cache misses.
- Parallel data fetching. Don't chain API calls sequentially on the server. Fetch all data in parallel with
Promise.all()to minimise backend time. - Test with JavaScript disabled. Browse your key landing pages with JS turned off. If they're blank, you have a CSR problem disguised as SSR.
Dynamic rendering serves a fully rendered page to crawlers while showing the JavaScript SPA to users. Google officially labels this a workaround, not a long-term solution, and recommends moving to proper SSR or hybrid hydration. Sites relying solely on dynamic rendering face ongoing maintenance overhead and potential crawl inconsistencies.
Common SSR mistakes to avoid
- Hydration mismatches — server-rendered HTML differs from client-rendered HTML, causing flickering or broken interactivity
- Not caching SSR output — re-rendering unchanged pages for every visitor wastes server resources and increases TTFB
- Waterfall data fetching — sequentially awaiting API calls on the server multiplies TTFB with each dependency
- Confusing SSR with SSG — applying SSR to static pages that would serve better as pre-built HTML
- Skipping the JavaScript-disabled test — the only reliable way to verify SSR is actually serving real content
Frequently asked questions
Generally yes. SSR delivers fully rendered HTML to Googlebot immediately. CSR relies on JavaScript execution, which Google may delay or skip. For content-heavy pages, SSR ensures every piece of content is indexable without waiting for JavaScript.
SSR generates HTML on the server for each request, so content is always fresh. SSG pre-renders all pages at build time and serves them as static files. SSG is faster for stable content; SSR is necessary for frequently changing or personalised content.
Yes. SSR increases Time to First Byte because the server must render HTML before responding. Complex pages can add 200-500 ms to TTFB. The trade-off is better LCP and FCP once the first byte arrives, since all content is already in the HTML.
Major SSR frameworks include Next.js (React), Nuxt.js (Vue), SvelteKit, Angular Universal, and Astro. Each provides mechanisms to fetch data on the server and render HTML before sending to the browser.
Use SSR when content changes frequently (e-commerce prices, inventory), when pages are personalised per user (dashboards, accounts), or when you have too many pages to pre-build. Use SSG for blogs, documentation, and marketing pages where content is stable.
