Rendering strategy decides where your HTML gets built: on a server before the browser ever sees it, or in the browser after JavaScript runs. Both approaches ship working web apps, but they trade off differently on first-paint speed, SEO friendliness, server cost, and how complex your deployment becomes. In 2026, most serious frameworks default to a hybrid of the two rather than picking one dogmatically.
What changed in 2026
- Meta-frameworks (Next.js, Nuxt, SvelteKit, Remix) now default to per-route rendering mode selection, rather than a single global setting for a whole app.
- Streaming SSR (rendering and sending HTML in chunks as it becomes ready) is now standard, not experimental, cutting time-to-first-byte for slow database calls.
- Edge rendering matured: pushing SSR to points-of-presence close to the user, described in more detail in the edge computing guide, narrowed the latency gap between SSR and CSR for global audiences.
- React Server Components stabilized further, blurring the SSR/CSR line by letting individual components choose their own rendering location.
How server-side rendering works
The server executes your app code, builds the full HTML for the requested page, and sends it to the browser already rendered. The browser paints it immediately, then JavaScript "hydrates" the page to make it interactive. Search engines see complete content on the first request with no JavaScript execution required, which is why SSR remains the default recommendation for public, SEO-sensitive pages.
How client-side rendering works
The server sends a mostly empty HTML shell plus a JavaScript bundle. The browser downloads the bundle, executes it, fetches data, and builds the DOM in place. The first paint is slower because nothing is visible until JavaScript runs, but subsequent navigation inside the app can feel instant since only data — not full pages — needs to be fetched afterward.
Choosing a rendering strategy
| Scenario |
Recommended approach |
Why |
| Public marketing site, blog, product pages |
SSR or static generation |
SEO and fast first paint matter most |
| Internal dashboard behind login |
CSR |
No SEO requirement; interactivity matters more than first paint |
| E-commerce product listing |
Hybrid (SSR shell, CSR for filters) |
Needs both indexability and fast filtering |
| Real-time collaborative app |
CSR with WebSocket updates |
Constant re-rendering makes full SSR wasteful |
| API-driven mobile-style web app |
CSR or islands architecture |
Data-fetching pattern resembles a native app |
Common pitfalls
- Hydration mismatches. If the server-rendered HTML does not exactly match what the client would render, React and similar frameworks throw hydration warnings or silently re-render, wasting the SSR benefit.
- Treating SSR as free. Every SSR request costs server compute; a spike in traffic multiplies server load in a way CSR (mostly static assets) does not.
- Over-fetching on the server. SSR routes that call slow or numerous backend services (see the N+1 query problem for a related database version of this trap) can make time-to-first-byte worse than CSR.
- Ignoring caching. Cache SSR output at the CDN or edge layer wherever the page is not truly personalized; re-rendering the same HTML per request is wasted work.
FAQ
Does SSR guarantee better SEO than CSR?
Not automatically. Modern search crawlers do execute JavaScript, so CSR pages can be indexed. But SSR removes the dependency on crawler JS execution succeeding, and it is faster for real users, which is itself an SEO signal.
Can I mix SSR and CSR in the same app?
Yes, and most production apps do. Static or SSR for the initial page load, CSR for interactive widgets after hydration, is the common pattern in 2026 meta-frameworks.
Is static site generation the same as SSR?
No. Static generation renders HTML once at build time; SSR renders on every request. Static is cheaper and faster but cannot reflect per-request data without an additional fetch step.
What about GraphQL or REST for data fetching in SSR?
Either works; the rendering strategy is independent of your API layer. See the GraphQL vs REST caching guide for how caching behavior differs between the two.
Where to go next