How AI is applied across API Evangelist and APIs.io. Read my AI disclosure →
API Evangelist API Evangelist
Discovery
Learnings
Guidance
Toolbox
Alignment
API Evangelist LLC

The Rendering Equation: Client + Server + Framework

calendar_today May 19, 2025 person State Farm Engineering domain state-farm

By Jordan Leeper

Introduction

When I first started my career 12+ years ago, I had no idea how client-server interactions worked. I often see new software engineers that have learned a JavaScript framework in college or in a bootcamp lacking some critical understanding of how their frontend application interacts with its API(s). I wish that I could have had someone explain to me some of those basic concepts, like what is client-side rendering (CSR)? What is server-side rendering (SSR)? How do they work together? How do they work for different frameworks? Hopefully after reading this, you will feel confident in answering these questions!

The Basics

Regardless of CSR or SSR, the browser interacts with the server the same way.

Here’s a high-level breakdown:

  1. The client (browser) sends a GET request to the server (for an application)
  2. The server responds with an HTML file
  3. The client (browser) requests any additional assets provided in the HTML file with <link> or <script> elements
  4. The server responds with the requested assets.

Steps 1 and 2 are done for every single application on the web. Steps 3 and 4 are optional (depending on your framework) and can be repeated many times depending on how much additional content the application might need to load.

The key difference between CSR and SSR is in step 2 — the HTML that is returned by the server. Let’s get into the details.

Client-side Rendering (CSR)

CSR is the process by which the client, in our case the browser, creates the views as it is instructed by JavaScript.

Any UI that loads HTML and then attaches elements to the Document Object Model (DOM) in the browser is doing a type of client-side rendering. Even vanilla JavaScript that appends and manipulates the browser’s DOM is an implementation of client-side rendering.

Nowadays, we usually think about frameworks like React, Vue, Angular, Svelte, Solid, etc. when it comes to CSR.

The actual HTML that is returned is almost always very sparse and has a single element that is used as the starting point for building out the views using JavaScript. These CSR frameworks look for that starting element, such as a div with an id, to build out the UI within.

For example, here is the starting HTML file for an Angular application that is passed to the browser.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<app-root></app-root>
<script src="polyfills.js" type="module"></script>
<script src="main.js" type="module"></script>
</body>
</html>

Almost no HTML elements exist in the file, because it is all built out at runtime when the browser loads the application’s JavaScript. As you can see, the <script src="main.js" type="module"></script> tag will run to load the JavaScript which constructs the views for the application. This is true for every CSR framework that dynamically creates HTML via JavaScript in the browser.

CSR is often very appealing because of the abundance of frameworks available and how easy they are to use. Generally, they manage routing in the browser instead of going back and forth to a server to generate HTML. They also provide an excellent developer experience when paired with tool like Vite that can manage hot reloading and file bundling. Another advantage of a CSR framework is that the final result of the build is a set of static files that don’t need to be run on a server. This makes deploying and managing a UI as simple as uploading files to cloud storage rather than managing containers or servers.

Server-side Rendering (SSR)

Server-side rendering is when the view (HTML) is created by the server and then sent to the client (browser).

When it comes to SSR, this is the tried-and-true experience that many web developers have used since the beginning. The browser makes an HTTP GET request for a file and the server returns a fully built out HTML file filled with elements that the browser uses. That HTML page may sometimes use some client-side JavaScript for things like form validation, animations, reactivity, and occasionally adding an element to the UI, but generally most of the HTML is already there and was provided by the server. Things like Spring JSP, Node + EJS, .NET Razor, and PHP are probably some frameworks that come to mind.

These days, most front-end developers don’t actually mean those frameworks when talking about SSR. They are usually referring to frameworks that combine both CSR and SSR together. For our context, let’s consider SSR to refer to frameworks that provide those capabilities like Next.js or Nuxt or SvelteKit.

So, what is it then?

Basically, an SSR framework allows you to render the HTML on a server and send it to the client so that the content renders immediately. Then, the client-side part of the framework (such as React, Vue, etc.) kicks in. Now you are now able to take advantages of your CSR framework’s features such as event handling and easy ways to template your UI. Let’s keep digging in!

SSR Frameworks

These SSR frameworks allow you to use the CSR framework/library you might be familiar with, but also take advantage of all of the features of SSR!

Other frameworks that offer SSR built in are:

Each of these frameworks offer different pros and cons and are at different stages in terms of what features they offer. For example, at the current time of writing, only Next.js offers a fully robust Incremental Static Regeneration capability. This can be set up manually with other frameworks, but requires more overhead.

With Angular, for example, enabling SSR takes only one CLI command to add to your existing non-SSR Angular project: ng add @angular/ssr. The advantage here is that you don't have to migrate your CSR application to a completely different framework to enable SSR like you would need to do with React to Next.js or Vue to Nuxt.

The CSR + SSR Problem

Like I mentioned earlier in the post, CSR frameworks look for an element in the HTML and then mount onto it. They will start to append and build out the HTML via JavaScript. When this happens with an already fully created HTML view that was provided via SSR, the HTML would actually get destroyed and then re-created. This results in a flash of the page as the content is visible for a split second, before it’s destroyed by the JavaScript and then added back.

The CSR + SSR Solution = Hydration

How can we fix this page flashing? The answer is something you’ve probably heard about. Hydration!

Hydration, while complex to implement, is actually quite simple to understand. Rather than the CSR framework destroying the already rendered HTML elements, let’s provide them to the framework instead! JavaScript often needs to apply interactivity to the HTML by attaching event listeners to buttons, the window, or other elements. This is where the concept of hydration comes from, since the page is not interactive until it’s been “watered” by the JavaScript that has been loaded. This also prevents the page from flashing, since the CSR framework doesn’t rebuild the HTML elements.

What advantages does SSR have?

SSR still plays a very crucial role in front-end development. While React, Angular, and Vue might be sufficient for most UI applications, there are several gaps that SSR fills.

  1. SSR applications can often provide improved performance when it comes to first contentful paint (FCP) since the browser does not need to download JavaScript in order to display the views.
  2. When building out complex and performance heavy visuals or elements, it can often be faster to do so on the server which generally has more powerful resources available than a user’s browser.
  3. Search Engine Optimization (SEO) was a very common use case, but perhaps not anymore. It was generally thought that search engine crawlers that traversed web pages to index them had a lot of problems when it comes to JavaScript heavy (CSR) pages since they might not wait for the view to be constructed (among other things). However, this article from Vercel demonstrates with evidence from over 37k different HTML pages that JavaScript heavy pages may no longer have as many issues when it comes to Google’s page indexing and SEO processing (At least for the Googlebot crawler).

Infrastructure

Running an SSR framework locally is usually very easy. The complex part comes in the big differences required when deploying to a test/QA/production environment. The standard approach for a CSR app is to use something like Amazon S3, Cloudflare Pages, etc. that acts as a simple file store since we don’t actually need a server. However, this is no longer possible with SSR (due to that Server which needs to construct the HTML per request) and we can’t just rely on static content being delivered via cloud storage.

Many providers offer capabilities that can help simplify SSR infrastructure management. Vercel offers SSR capabilities for Next.js, SvelteKit, Nuxt, and Astro. NuxtHub offers full stack capabilities for Nuxt applications. AWS has several services that could enable SSR applications such as Amazon EKS, Amazon ECS, or AWS Amplify. Firebase offers App Hosting for Next.js and Angular applications that leverages Google Cloud Platform behind the scenes.

One important note is that using a cloud storage solution to serve static content, such as a CSR app, is generally cheaper than running a server which hosts an SSR application. It is also often much simpler to set up and maintain.

Other acronyms?

Oftentimes, several other concepts are talked about when it comes to SSR and I think it’s critical to understand what they are. SSR occurs at runtime. When a web request reaches the server, it will build out the HTML response dynamically and send it back to the client. Sometimes we might want to build out the HTML ahead of time since it won’t change per request. This is where Static Site Generation (SSG) and Incremental Static Regeneration (ISR) come into play. Many SSR frameworks offer these capabilities so that it will lessen the load on the server and improve efficiency.

Static Site Generation (SSG)

Static site generation is when the associated pages of your application are pre-rendered at build time rather than dynamically when requested by the server. Many frameworks are able to do both SSR and SSG in the same application! Angular does this out of the box. This can be a very efficient approach since all of the work is done up front. However, it can be cumbersome to easily make changes to content since it is all done at build time.

Incremental Static Regeneration (ISR)

ISR allows your applications to periodically regenerate pages that were created via SSG. This means that you no longer need to do a redeploy and rebuild of your statically generated pages to pick up new content as long as the content is pulled dynamically from a source, such as a content management system (CMS), at build time. Not all frameworks offer ISR, but it is becoming more popular.

What does State Farm do?

In general, State Farm enables teams to use the tools which best fit the problems they are trying to solve for. This means that each of our applications have the potential to be built with different frameworks depending on the team’s knowledge, the product area, and the different ways we need to interact with customers. State Farm has a large number of UI frameworks in use including Angular, Astro, Ember, Next.js, React, Vue, Spring MVC + JSP, etc.

Some of the common patterns I recommend to our engineering teams are:

  • Do you have a form heavy application with a lot of inputs? Save yourself some time and use a framework that enables two-way data binding like Vue or Angular.
  • Spinning up a quick project or proof of concept? React might be an easy option since it has many learning resources and open-source dependencies.
  • Building a large, enterprise application with many engineers and you need to have an easy time managing updates and technical debt? Use Angular. It prioritizes backwards compatibility and easy version updates.
  • Do you need to build a UI where first page load speed is super critical? Use an SSR framework like Next.js or Angular with SSR.

Review — when to use CSR or SSR?

This is a question a lot of teams ask me, but I’m hopeful that now that we have more of a grasp on their differences, we can determine what makes the most sense to use. Let’s review.

When to use SSR

  • You have an application that needs to display as soon as possible. We can achieve this by sending pre-rendered HTML to the browser and not needing to load JavaScript to display the UI.
  • Your application needs to maximize its SEO statistics. While the aforementioned article from Vercel is promising, our best bet is to keep things easy for web crawlers and send all of our content on the first load of the HTML.
  • Your application needs to do heavy data processing which might cause very slow load times or interactions in the client. Process the data on the server rather than relying on the browser.

When to use CSR

  • For most other scenarios, using CSR is the right choice. It’s cheaper to host, easier to manage the infrastructure, and makes for a great user experience.

Exceptions…

  • One scenario where it might make sense to use something other than CSR would be for certain types of pages that don’t require much user data or interactivity. For example, marketing pages that display static content. In this scenario, you might want to consider using SSG. Oftentimes JavaScript frameworks such as Angular and Astro can let you choose what routes of your application can be pre-rendered at build time.
  • Another scenario might be a need for a limited backend API or Backend for Frontend (BFF). By creating an SSR application, you could also include one or more API routes that the client calls. However, this can grow complicated. As API needs grow and change, you should be cognizant of when pulling those capabilities into their own managed service makes more sense.

Conclusion

Understanding client-server requests and how your framework operates helps teams with debugging, building efficient applications, and providing the best experience possible to users. Those basics, along with an understanding of CSR vs SSR, empowers teams to craft their ideal application. Now that you’ve had a chance to learn more you can ask yourself: Do I need SSR for my application or will CSR suffice? Can my application’s content be pre-rendered with SSG? Is the cost of running an SSR application server worth it versus a CSR application hosted in static cloud storage? Thanks for reading and let’s get building!

To learn more about technology careers at State Farm, or to join our team visit, https://www.statefarm.com/careers.

Information contained in this article may not be representative of actual use cases. The views expressed in the article are personal views of the author and are not necessarily those of State Farm Mutual Automobile Insurance Company, its subsidiaries and affiliates (collectively “State Farm”). Nothing in the article should be construed as an endorsement by State Farm of any non-State Farm product or service.

<hr /><p>The Rendering Equation: Client + Server + Framework was originally published in State Farm Engineering Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>

open_in_new Read original post