Telerik blogs

In this article, we will learn about the new Blazor render modes in .NET 8, including ServerInteractivity, WebAssemblyInteractivity, AutoInteractivity and static server-side rendering (SSR).

For an introduction to Blazor Server and Blazor WebAssembly, read the articles in the Blazor Basics series.

Introduction

Previously, until .NET 7, we had Blazor Server and Blazor WebAssembly as dedicated and exclusive render modes. With .NET 8, we now have four different rendering modes.

Also, we can now mix and match different rendering modes within the same application by setting a render mode per component instead of a whole application.

When using the new Blazor Web App project template, everything we need is already set up for us. When working with an existing application or when starting with a different project template, we need to make sure that the application is correctly configured.

First of all, we need to make sure that we add the following line to the Program.cs to register the required services for Razor components:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
var app = builder.Build();
app.Run();

When we want to enable Blazor Server interactivity for the application, we also need to call the AddInteractiveServerComponents method to register the required services.

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

Accordingly, we also need to call the AddInteractiveWebAssemblyComponents method when we want to set up the application to support components with WebAssembly interaction.

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents();

If we want to mix and match, we can also call both methods, enabling the application to use both Blazor Server interactivity as well as WebAssembly interactivity within the same Blazor application.

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

Now, let’s find out if the new render modes make Blazor more complex or if they are also helpful in building modern web applications.

Applying Render Modes to Individual Components

With .NET 8, we can set render modes to individual components in two different ways.

  1. We can use the @rendermode attribute when defining an instance of a component. For example, let’s say that we have a User component. When defining an instance of the User component, we add the @rendermode attribute and set the value to server interactivity:

    <User @rendermode="RenderMode.InteractiveServer" />

    This approach is very flexible. We define the User component as render mode agnostic. This means that the component can be used with different rendering modes, and we do not set a render mode within the component definition.

  2. We can set the render mode within the component implementation using the @rendermode attribute followed by the render mode.

    @rendermode InteractiveServer
    <div>Username: @User.Username</div>
    

    In this example, the User component is fixed to a specific render mode. We cannot set or change the render mode when defining an instance of the component.

    This approach limits the flexibility of the application and should only be used if the component’s implementation limits the usage of different render modes. This could be the case when we call backend APIs within event callbacks, which are only available in Blazor Server interactivity.

Prerendering Blazor Components in .NET 8

Component prerendering allows the browser to render the component while data is loading in the background. As soon as the asynchronous operation has been completed, the component is updated with the loaded data.

It helps the application to feel more responsive and could also improve SEO since the application appears to be faster, which increases the signals to the search engines.

During the prerendering phase, event handlers aren’t active. The components don’t react to user actions.

Prerendering is enabled by default for all interactive components.

It sounds too good to be true—and it maybe is. What’s the catch?

Prerendering makes the whole rendering process a lot more complex. While it sounds great to have a rendered component on the screen as soon as possible, it also comes with challenges.

As explained above, interactivity triggered while prerendering hasn’t been completed is ignored. This can lead to unexpected behavior and confusion among users.

From my experience working with Blazor for a few years, I recommend disabling prerendering unless you specifically need it in a certain case. In my opinion, prerendering shouldn’t be enabled by default. But that is another discussion to be had.

When we want to disable prerendering, we can either do it when defining the component using one of the following lines depending on the desired interactivity mode:

  • @rendermode @(new InteractiveServerRenderMode(prerender: false))
  • @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
  • @rendermode @(new InteractiveAutoRenderMode(prerender: false))

Or we set it for every instance of a component using the @rendermode attribute:

  • <... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />

If we want to turn off prerendering for a specific component, we also specify its interactivity type.

Static Server-Side Rendering (Static SSR)

If we do not specify any interactivity mode on a Blazor component, static server-side rendering (static SSR) is used.

This means that there is no interactivity because the page is rendered on the server and returned to the client without any interactivity (callback code, etc.). As a result, any button callbacks are ignored and will not be triggered when the user presses the button.

Static SSR makes sense for websites without any interactivity. For example, for building company websites or blogs that mostly render data, static SSR is a great choice. Of course, we can still have some interactive components, but we don’t need it for most components.

Before .NET 8, we always had a SignalR connection (because of Blazor Server) or a sizeable bundle for WebAssembly. With static SSR, we can render the website on the server and send plain HTML, CSS (and JavaScript) to the server. It’s fast, simple and great for SEO.

Notice: When we want to have interactivity on Blazor components, we need to set the interactivity mode to either Server, WebAssembly or Auto. Otherwise, there is no interactivity, and our components use static SSR.

Interactive Server-Side Rendering (Blazor Server)

What was previously known as Blazor Server is now called InteractiveServer rendering.

@rendermode InteractiveServer

If we set the render mode of a component to InteractiveServer, the interactivity code is executed on the server, similar to a Blazor Server application running on .NET 7 or earlier.

Client-Side Rendering Using Blazor WebAssembly

What was previously known as Blazor WebAssembly is now called InteractiveWebAssembly.

@rendermode InteractiveWebAssembly

If we set the render mode of a component to InteractiveWebAssembly, the interactivity code is executed on the client using WebAssembly. The component behaves similarly to a Blazor WebAssembly application running on .NET 7 or earlier.

The Interactive Auto Render Mode

While the InteractiveServer and InteractiveWebAssembly render modes have been around for a few years, the InteractiveAuto render mode was introduced with .NET 8.

The Auto render mode decides how to render the component at runtime. First, the component is rendered using InteractiveServer. In the background, the .NET runtime and the app bundle are downloaded and cached client-side.

Next time the component renders, it will use the client executable and render the component using InteractiveWebAssembly.

Important: The Auto render mode does not change the interactivity type at runtime for a component that has already been rendered. In other words, the component doesn’t change from InteractivityServer to InteractivtiyWebAssembly. It always uses one of those interactivity types and sticks with them until the component is used in another place of the app or when the app is reloaded.

I personally have had a mixed experience with the Auto render mode. While it sounds like a good plan to benefit from both fast loading times and latency-free interactivity as soon as the WebAssembly bundle is available, I have seen some issues with unpredictable behavior. Also, it introduces more complexity to the application.

As always, it’s a great tool for some applications, but not the right way for all of them.

Using the Same Render Mode for the Entire Application

Sometimes, we developers want to make our lives as simple as possible. And that’s a great thing.

If we have a scenario where we want to use the same render mode for all components in the entire Blazor web application, it makes sense to globally set the render mode.

Unfortunately, it currently means we need to set the render mode in two places. At least both are in the same file, the App component.

The Routes and HeadOutlet components are the place where we need to apply the @rendermode attribute if we want to set the render mode globally.

Consider the following example:

<!DOCTYPE html>
<html lang="en">
<head>
    <base href="/" />
    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
</head>
<body>
    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

As you can see, we have the same definition for both the HeadOutlet and the Routes components.

I wish there was a central place where we only had to set it once, but this is better than nothing.

When we set the render mode globally, we don’t have to worry about it in the entire application. We do not need to set the render mode on individual component instances or when implementing those components.

Conclusion

Two of the four available render modes in .NET 8 are known to Blazor developers from earlier .NET versions.

Two Auto and static SSR modes were introduced with .NET 8, and opened up new opportunities to build Blazor applications for additional scenarios.

However, with the new render modes, another level of complexity is introduced in your Blazor web applications. Therefore, I highly recommend to familiarize yourself with the four render modes and picking what makes the most sense for your scenario.

It isn’t a shame to continue with ServerInteractivity or WebAssemblyInteractivity for simplicity. On the contrary, I highly recommend it for most scenarios.

If you want to learn more about Blazor development, you can watch my free Blazor Crash Course on YouTube. And stay tuned to the Telerik blog for more Blazor Basics.


About the Author

Claudio Bernasconi

Claudio Bernasconi is a passionate software engineer and content creator writing articles and running a .NET developer YouTube channel. He has more than 10 years of experience as a .NET developer and loves sharing his knowledge about Blazor and other .NET topics with the community.

Related Posts

Comments

Comments are disabled in preview mode.