Exploring Blazor Changes in .NET 8 - Server Side Rendering (SSR)

July 11, 2023 · 5 minute read · Tags: blazor

This is the first in a number of posts where we’ll explore the changes coming for Blazor in .NET 8 (due later this year - 2023).

So you’ve decided to build your new web app using Blazor. You’ve heard good things, about how productive your fellow developers are now they’ve jumped on the Blazor bandwagon, and you want to join!

But hold your horses, first you need to figure out which hosting model to use.

You can go for Blazor Server, where an open socket connection is required for each user ‘session’, and all UI logic executes on the server.

Or you can choose Blazor WASM, where the web app is downloaded to the browser, and your UI logic runs there.

Oh, and you’d better get this right, or your app is doomed to failure (doomed I tell you!)

Of course, in reality your app isn’t going to fall apart because you made the “wrong” choice (and it may actually make sense to make your app work with both hosting models).

But, having to make this decision up front feels like a big deal, and it’s easy to assume that Blazor is all about its hosting models.

In truth, Blazor’s real power lies in its component model.

It’s the component model that enables you to break your UI down into smaller pieces, then compose them together to form a larger part of your UI.

Soon, with .NET 8, we’ll be able to use this component model in an entirely new way, on the server, using Server Side Rendering.

Render once, on the server

With SSR you don’t need to adopt either of the two hosting models (server/WASM).

Instead, when someone attempts to visit a page on your site:

  • The request is sent to the server
  • Your server directs that request to the relevant Blazor component
  • The component is rendered (on the server)
  • The resulting HTML is sent back to the browser

In this mode, Blazor is operating much like MVC, or Razor Pages.

Microsoft have released a number of previews, and we’re beginning to get a good sense of how this new SSR option will work. Here’s how it’s shaping up.

First, there’s a new project template which enables SSR (and a few other things) by default.

dotnet new blazor -o BlazorWebApp

The resulting project includes a couple of pages:

  • Index.razor
  • ShowData.razor

The Index page is a standard Blazor component:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

Run this in the browser and you’ll see a familiar looking Home page, the difference is this has been rendered on the server, and what you’re seeing is plain old HTML (returned to the browser from the server).

A browser window showing a simple Hello World page. The Dev Tools are open which show the request to localhost, and some plain HTML that has been returned in the response

How SSR is configured

If we look at Program.cs we can see how this is being wired up:

builder.Services.AddRazorComponents();

This registers the various services needed to support server-side rendering of Razor components.

We also need to be able to route requests to our Razor Components. That’s taken care of by this line:

Program.cs

app.MapRazorComponents<App>();

With this, incoming requests will be forwarded to the component that lives in App.razor.

In App.razor we have a standard Blazor Router:

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        ...
    </Found>
    ...
</Router>

This picks up the request and forwards it to the relevant component.

For example, our Index page has this attribute:

@page "/"

As a result, we can access the Index page via the root URL for our app (/).

Any requests for / will be forwarded to App.razor which will forward the request on to the Index component.

Once there, the Index component (and any child components) will be rendered, and the resulting HTML is returned.

In SSR Mode, as of Preview 6, navigating to new pages performs a fetch, rather then a full page load.

For example, imagine we visit your app .NET 8 app, starting with the Index page.

For that first load the browser will fetch the HTML for the Index component plus any linked CSS and JavaScript files.

SSRDocumentRequest.jpg

But, after that first load, as you continue to click on links and navigate to different pages, Blazor will intercept those requests and perform a fetch instead.

SSRDocumentRequest.jpg

(Here we navigated to the FetchData page and then back again).

This avoids the need to fully load the page and provides a smoother “spa-like” experience as you navigate around the app.

It also means less work for the browser, as it can preserve any parts of the DOM which haven’t changed (like a shared nav bar).

Use Cases

SSR looks like a great way to use Blazor’s component model (Razor Components) for pages where you don’t need a lot of interactivity (essentially, static content).

Imagine a product details page. Most of the page is just showing content (text, images etc) and requires little (to zero) interactivity.

But what if you want to enable some level of interactivity, for specific parts of the page? For that, you’ll be able to enable ‘islands of interactivity’ by making specific components interactive.

We’ll explore that in the next post - Pop your email in the box below and get these .NET 8 preview articles first.

Join the Practical ASP.NET Newsletter

Get every .NET 8 article first, delivered straight to your inbox.

I respect your email privacy. Unsubscribe with one click.

    Next up

    Finally! Improved Blazor Server reconnection UX
    .NET 9 changes how your Blazor Server app behaves when server connection is lost
    .NET 9 improves JavaScript module importing for Blazor
    .NET 9 ensures your users always get the latest version of your JS modules
    How to use .NET 9 to ensure users always get the latest version of your stylesheets
    .NET 9 changes how static files are served, and it solves a long-standing problem