Server-side rendering (SSR) is a popular technique for rendering a single-page client application (SPA) on the server and then sending the fully rendered page to the client. It allows dynamic components to be used as static HTML markup. Note: this article requires a certain level of experience. Consider reading the How to Host a Website: Simple Guide for Beginners article first.
This approach can be useful for search engine optimisation (SEO) when JavaScript code is not handled properly during indexing. It can also be useful in situations where loading a large block of JavaScript is difficult due to slow network speeds.
Note. Next.js also enables a modern approach to building static React applications and applications that are rendered on the server.
Almost every second website nowadays is a single-page application (SPA). I'm sure you know what a single-page application is. Frameworks like Angular, React, Vue, Svelte etc are on the rise because of their ability to develop SPAs quickly and efficiently. They are ideal not only for rapid prototyping, but also for developing complex web applications (if done right).
Until recently, for most sites, HTML was generated on the server and sent along with the response so the browser could render it on screen. Whenever a user clicked a link to access a new page, we sent a new request to the server to generate new HTML for that page. There was nothing wrong with this approach, except the load time and user experience.
The user had to wait several seconds for the server to receive the request, collect the data, generate the HTML and return a response. Because it was a full-page download, the browser had to wait for all the resources such as JavaScript, CSS, and other files to load again (unless they were cached properly). This was a huge inconvenience for the user.
Nowadays, most web applications only request data from the server. All HTML generation is done on the client side (browser). Whenever a user clicks on a link, instead of sending a new request to the server to get the HTML of that page, we create the HTML on the client side by mounting new components (web application building blocks), and request from the server only the data needed to populate that HTML.
In this way, we prevent the page from being completely reloaded and greatly improve page load time. We programmatically change the URL in the browser using the History API, which does not cause the browser to refresh. Since the page never refreshes, we only request the initial HTML, which includes JavaScript, CSS, and other facilities for the entire application.
For any page, such as example.com/ or example.com/settings (if directly accessible via URL entry in the browser), our server sends the same HTML and resources in response. The JavaScript application reads the URL in the browser, sees the paths, such as / or /settings, and renders the components associated with those paths to the client side. These components then make a request to the server to get the data they need. Therefore a typical HTML response from the server for such SPAs looks like the one shown below.
// index.htmlSPA Application
In the above HTML, <div id="app"></div> is the container or root element of the SPA. All the application HTML generated by our JavaScript will be inserted inside this element on the client side.
Let's talk about the benefits and pitfalls of SPA.
SPAs provide similar interaction experience to the native applications. As all the HTML of the application is generated on the client side, the page loading is very fast.
Since all the application resources such as JavaScript and CSS files are downloaded only once and are never requested again after the application has been loaded, we greatly save on server bandwidth.
After the initial loading of the application, we only request a few kilobytes of data from the server (on-demand). Thus SPAs are ideal for use in poor network conditions.
The whole application can be cached on the client (device) with a service worker. Thus, the next time a user accesses the site, the browser will no longer need to load HTML and resources. When the user's device is not connected to the Internet, instead of displaying the default browser message "Not connected to the Internet!", we can display a custom screen that will give the user offline access.
Users can save the SPA as an app on the device. If you are interested in developing a mobile app but don't want to spend money on native app development (Android or iOS), SPA opens up the possibility to create an app similar to a native app using the same website code base.
As SPA needs to serve all JavaScript and CSS files of the app together (usually), these files are cumbersome (several megabytes). Consequently, it takes considerably longer to load the application initially, which means that the user will see a blank screen for quite a long time. With a bad network this can be a serious problem. However, we can fix this with SSR.
In SPAs, since JavaScript manages the generation of HTML on the client side, SPAs do the heavy work on the client side, which was previously done by the server. Therefore, SPAs need devices with good CPU and battery capacity.
Since the raw HTML provided by the server (for all pages) does not contain any application-specific HTML, the search engine sees the website as empty, with no content. Thus, your website may not make it to the top of search results, despite the huge traffic and relevant content.
It can be seen from the comparison above that the benefits of SPAs outweigh their pitfalls. Our devices are becoming more productive every day, and network conditions are getting better and better. So we don't have to worry about it anymore.
However, every site wants to rank first in the search results. When it comes to SPA, this is not very easy to achieve. As we said, when a crawler like Google sees our website, it sees HTML with an empty <div id="app"></div> element because most crawlers only read the HTML returned by the server and don't run the application the way our browser would. This happens with respect to any page of the site.
Therefore, there is a good chance that your site will never appear on the first few pages of search results. So how can we fix this? The only way to fix this is to generate HTML on the server for the given page, but only on first load.
The reason I highlighted "on first load" is because this approach is not like traditional server-side HTML rendering of the entire application. Here we only generate the HTML on the server once for the requested page, so that search engines see the correct HTML while the application behaves exactly the same in the browser.
This method has another added benefit. Since the server will return the correct HTML for the page, the user will no longer see a blank screen until all of the application's resources have been loaded. We will need to configure a few parameters for this, but it will be very user-friendly.
If you're interested in understanding how a browser renders a website, check out this article. Since the server has already rendered the HTML for this page, we will need to load all JavaScript resources after the DOMContentLoaded event fires. So make sure the <script> tags in your HTML have a defer attribute.
This process of rendering HTML on the server side is called server-side rendering or SSR.