SSR, or server-side rendering, is the technique in which a web application produces the complete HTML for a page on the server at request time and sends that markup to the browser, instead of sending an empty shell that JavaScript fills in later. The browser can display meaningful content as soon as the HTML arrives.
In modern web applications, SSR usually means rendering the same component code on the server and in the browser. The server renders the initial view, and the client then attaches interactivity through hydration. This hybrid model combines the fast first view of traditional server pages with the rich interaction of a single-page application.
How server-side rendering works
An SSR request follows a fixed sequence of server and client steps. The server receives the request, fetches the data the page needs, executes the component tree to produce HTML, and streams or sends that HTML to the browser together with links to the client JavaScript.
- The request arrives at a Node.js, edge or other server runtime that hosts the application.
- Data is loaded from databases or APIs, often in parallel, before or during rendering.
- Components render to HTML using functions such as
renderToStringor streaming equivalents. - The browser paints the markup immediately, so text and images become visible early.
- Client JavaScript hydrates the page, attaching event handlers and state to the existing DOM.
Modern frameworks support streaming SSR, in which the server flushes the page shell first and sends slower sections as their data resolves. Streaming reduces the time the browser waits for the first byte and lets FCP and LCP improve even when one data source is slow.
SSR compared with other rendering strategies
SSR is one of several rendering strategies that decide where and when HTML is produced. Choosing among them is a central architectural decision for any web application, because it shapes performance, hosting costs and data freshness.
| Strategy | When HTML is produced | Typical strength | Typical weakness |
|---|---|---|---|
| SSR | On the server for each request | Fresh, personalized content with fast first view | Server cost and higher TTFB |
| SSG | At build time | Very fast delivery from a CDN | Content is stale until rebuilt |
| Client-side rendering | In the browser after JavaScript runs | Simple hosting, rich interaction | Slow first view on weak devices |
| Incremental regeneration | At build time, refreshed on a schedule | Static speed with periodic updates | Short windows of stale data |
| Classic MPA templates | On the server, no hydration | Minimal JavaScript | Full page reloads on navigation |
The distinction from a classic multi-page application is subtle but important. A traditional server template engine also renders on the server, but the term SSR in current practice usually implies isomorphic or universal rendering, where the same components later run in the browser as an SPA.
Benefits and costs of SSR
The main benefit of SSR is that content is visible before JavaScript finishes. Search engine crawlers, social media preview bots and users on slow devices all receive ready HTML, which improves indexing reliability and perceived speed.
| Quality | Effect of SSR | Reason |
|---|---|---|
| First Contentful Paint | Usually better | Markup paints without waiting for bundles |
| Time to First Byte | Often worse | The server must fetch data and render first |
| Search indexing | More reliable | Content exists in the initial HTML |
| Interactivity | Delayed until hydration | Event handlers attach only after JavaScript loads |
| Server load | Higher | Rendering consumes CPU on every request |
| Caching | Harder for personalized pages | Responses vary by user or session |
The most misunderstood cost is the uncanny valley of interactivity. A server-rendered page looks ready, yet buttons do not respond until hydration completes. On a mid-range phone, hydrating a large page can take several hundred milliseconds to a few seconds, which can harm INP and frustrate users who click early.
When to choose SSR
SSR is the right choice when content changes per request and must be visible quickly. It is less suitable for pages that are identical for every visitor, where static generation achieves the same first view at a fraction of the cost.
| Situation | Recommended approach | Why |
|---|---|---|
| Product page with live price and stock | SSR with short caching | Data must be current at request time |
| Marketing or documentation page | SSG | Content changes rarely and caches perfectly |
| Logged-in dashboard behind authentication | Client-side rendering or SSR shell | Search indexing is irrelevant |
| News front page | SSR or frequent regeneration | Freshness and fast first view both matter |
| Highly interactive editor | Client-side rendering | Interaction dominates over first paint |
Many frameworks now allow per-route rendering choices, so a single application can combine SSR, SSG and client-side rendering. Treating rendering as a route-level decision rather than an application-wide one usually gives the best balance.
Common SSR mistakes
Most SSR problems come from differences between the server and browser environments. Code that assumes a browser API, a specific time zone or random values can produce output on the server that does not match the client.
- Hydration mismatches occur when server and client render different markup, for example from dates, random IDs or
windowchecks, forcing costly re-rendering. - Data waterfalls on the server arise when components fetch sequentially, multiplying TTFB; parallel or hoisted data loading avoids them.
- Shipping too much JavaScript cancels the benefit, because the page still waits for large bundles to become interactive.
- Leaking user data through shared caches happens when personalized responses are cached without varying by session.
- Accessing browser-only APIs during render crashes the server process or throws errors that degrade to client-side rendering.
Techniques such as partial hydration, islands architecture and server components address the hydration cost by sending JavaScript only for the interactive parts of a page, while the rest stays static HTML.
A non-technical view
With SSR, the website prepares the finished page before sending it to your browser. You receive something you can read right away, rather than a box of parts that your phone must assemble first.
It is like ordering furniture already assembled instead of flat-packed. The delivery takes slightly more effort from the shop, but you can sit down immediately. A few moments later, the page also becomes fully interactive, so buttons and menus begin to respond.
A concrete example
A travel booking site originally rendered its hotel search results entirely in the browser. On mid-range Android phones, visitors saw a blank screen with a spinner for about 4 seconds while a 600 KB JavaScript bundle loaded and fetched availability data. Search engines also indexed some result pages inconsistently.
The team moved the results route to streaming SSR, fetching availability on the server in parallel and caching city-level data for 60 seconds. The page shell now arrives in roughly 300 ms, the hotel list appears at about 1.5 seconds, and interactive filters hydrate shortly after. Because personalized prices vary by user, the team kept those responses out of the shared cache and cached only the anonymous version.