Server-side rendering (SSR) addresses the performance and search engine optimization issues of single-page JavaScript applications. In contrast to client-side rendering, it generates static content on the server before sending it over to the user’s browser.
Server-side rendering improves site speed and results in better Core Web Vitals scores. However, sometimes it can be difficult to implement and might also increase Interaction to Next Paint (INP).
In this article, we’ll look into server-side rendering in detail. We’ll see how it works, what problems it solves, how it compares to client-side rendering, and what pros and cons it comes with.
An overview of single-page applications
Single-page applications (SPAs) are a web app architecture that appeared as an alternative to traditional websites and multi-page applications. SPAs, also known as client-side apps, became possible with the introduction of asynchronous JavaScript (AJAX), which makes it possible to update smaller parts of the user interface without reloading the full page.
Modern-day SPAs are often built with frontend UI frameworks such as React, Vue, and Angular. They consist of reusable JavaScript components fully rendered on the client side.
The main goal of this architecture is to make web apps similar to native mobile and desktop applications in terms of interactivity. As SPAs only have a single HTML page that fetches data from the server asynchronously, users can see updates instantly, without having to wait for the whole page to refresh.
How does client-side rendering work?
Client-side rendering (CSR) is the default rendering method for single-page applications.
In web development, rendering means the process of converting application code into interactive web pages. The page HTML is generated by a JavaScript engine. With client-side rendering, this is always done on the frontend. The browser then takes the generated HTML to visually render the page.
If you use client-side rendering, it’s the user’s browser that generates the entire app, including the user interface (UI), data, and functionality. No server is involved in the process, except to store the client-side code and data and transfer it to the browser.
As the following code example shows, in CSR apps, the HTML file only contains a blank root
(often also named app
) element and a script
tag. The root element is populated by the browser that downloads and processes the JavaScript bundle to render all the other elements:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>CSR</title>
</head>
<body>
<div id="root"><!-- blank --></div>
<script src="/bundle.js"></script>
</body>
</html>
Since the browser needs to download and run the whole application code before the content appears on the screen, the first page load is usually slow with client-side rendering (server-side rendering splits this process between the client and server).
As a result, users see a blank screen or loading spinner for a relatively long time. This leads to a poorer user experience and higher bounce rates (see Google’s discussion of how page load time impacts bounce rates).
Image credit: React PWA
Server-side rendering provides a solution to this problem.
What is server-side rendering (SSR)?
Server-side rendering, also known as universal or isomorphic rendering, is an alternative rendering method for single-page applications. SSR generates the static HTML markup on the server so that the browser gets a fully rendered HTML page. This is done by using a backend runtime such as Node.js that can run the JavaScript code to build the UI components.
Here’s an example HTML file, containing a simple newsletter signup form, that the browser could receive with server-side rendering. All HTML elements inside the root
element were rendered on the server:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>SSR</title>
</head>
<body>
<div id="root">
<div class="container">
<h2>Stay Updated</h2>
<form method="post">
<input
type="email"
name="email"
placeholder="Enter your email"
required
/>
<button type="submit">Subscribe</button>
</form>
</div>
</div>
<script src="/bundle.js"></script>
</body>
</html>
As the browser doesn’t have to render the HTML, static content appears on the page faster with server-side rendering. However, the browser still needs to download and process the JavaScript file to add interactivity to the HTML elements. As a result, users will need to wait more before they can interact with the app, e.g. click buttons or fill input fields.
Faster-loading static content versus less time between content visibility and interactivity is a trade-off between server-side and client-side rendering — but more on that later.


Run A Free Page Speed Test
Test Your Website:
- No Login Required
- Automated Recommendations
- Google SEO Assessment
Steps in the server-side rendering process
An SSR app processes the same JavaScript code on both the client and server side — this is why it’s also called universal rendering.
In brief, server-side rendering consists of the following steps:
- Client’s HTTP request – When the user enters the URL into the browser’s address bar, it establishes an HTTP connection with the server, then sends the server a request for the HTML document.
- Data fetching – The server fetches any required data from the database or third-party APIs.
- Server-side pre-rendering – The server compiles the JavaScript components into static HTML.
- Server’s HTTP response – The server sends this HTML document to the client.
- Page load and rendering– The client downloads the HTML file and displays the static components on the page.
- Hydration – The client downloads the JavaScript file(s) embedded into the HTML, processes the code, and attaches event listeners to the components. This process is also called hydration or rehydration.
Here’s how server-side rendering looks from the browser’s perspective. Note that the flowchart below starts with Step 4 when the browser gets the server’s response:
Image credit: React PWA
Server-side rendering frameworks and tools
Popular frontend UI frameworks all have their own features that make it possible to write universal JavaScript code that also runs on the server side, respectively:
- React uses the
ReactDomServer
object together with thehydrateRoot()
method. - Vue has a
createSSRApp()
method and a corresponding server-side rendering API. - Angular has its in-house server-side rendering tool called Angular Universal.
Processing server-side JavaScript also needs a backend JavaScript framework that runs on the Node.js server, such as Express.js or Hapi. These backend frameworks handle network requests, render the components on the server, and return the pre-rendered HTML to the browser. You can use them together with any frontend JavaScript framework.
There are also full-stack JavaScript frameworks for creating universal applications, such as Next.js for React or Nuxt.js and Quasar for Vue.
What are the advantages of server-side rendering?
Server-side rendering can make your website load more quickly and make it easier for search engines to index.
How big the positive impact will be depends heavily on how your website is built. Use a site speed testing tool to check if server side rendering is a good way to speed up your website.