Interactive what now? Deciphering Blazor's web app project template options

February 13, 2024 · 4 minute read · Tags: aspnet | blazor

.NET 8 shipped with a new template for creating Blazor Web Apps.

Use it (either via Visual Studio or the command line) and you face choices about how your app’s interactivity should work.

Specifically you’ll be asked two questions:

  • Which interactive render modes do you want your app to support?
  • Where do you want the interactivity to apply?

Whether you’re new to Blazor or switching to .NET 8 from an earlier version these options can be pretty confusing.

Here’s what they mean, and how to choose between them.

Let’s start with the first choice - which Interactive render modes to enable for your app.

Interactive Modes

In VS this is referred to as Interactive render mode, if you’re using the CLI it’s the -int or
--interactivity option.

The available options are:

  • None
  • Server
  • WebAssembly
  • Auto

Let’s take them one at a time.

Server

Your project will have the plumbing necessary to run components via Blazor Server.

Program.cs


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

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

With this you can specify InteractiveServer as the render mode for some/all of your components.

<Counter @rendermode="InteractiveServer"/>

WASM

This option configures the project with support for running components via Blazor WASM.

Program.cs


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

app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(InteractiveWASM.Client._Imports).Assembly);

As part of this your solution will include a client project.

The call here to AddAdditionalAssemblies ensures Blazor find any components you put in that .Client project.

With this you can specify InteractiveWebAssembly as the render mode for some/all of your components.

<Counter @rendermode="InteractiveWebAssembly"/>

Auto

With this option both Server and WASM interactivity is enabled.

Program.cs

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();
    
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(InteractiveAuto.Client._Imports).Assembly);    

Again, note the call to locate razor components from the included .Client project.

With this you can choose any of the render modes for your components: Server, WebAssembly or Auto (WASM with Server as a fallback).

<Counter @rendermode="InteractiveWebAssembly"/>

<Counter @rendermode="InteractiveServer"/>

<Counter @rendermode="InteractiveAuto"/>

Interactivity Location

With that decision made, the next question comes down to whether you want the entire app to run interactively, or just the pages/components you specify.

Per page/component

This is presented in VS as ‘Interactivity Location’.

If using the CLI the relevant flag is -ai or --all-interactive which you can set to true (for global) or false (for per page/component).

When this option is left as “per page/component” your app will default to static server-side rendering for components (aka “non-interactive”).

You can see this in the App.razor for the project.

App.razor

<!DOCTYPE html>
<html lang="en">

<head>
    ...
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Notice how the HeadOutlet and Routes components have no render mode specified.

This means they’ll use the default of static server-side rendering.

This leaves it up to you whether you then run specific components using one of the interactive render modes.

Global

If you choose this option everything will be set to run interactively from the get go.

You’ll see this reflected in App.razor.

<!DOCTYPE html>
<html lang="en">

<head>
    ...
    <HeadOutlet @rendermode="InteractiveAuto" />
</head>

<body>
    <Routes @rendermode="InteractiveAuto" />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Here the Routes and HeadOutlet components are configured to use the InteractiveAuto render mode.

Which render mode is specified here comes from your answer to the first question (which interactive render modes to enable).

This global approach to making your components interactivity is equivalent to how Blazor worked prior to .NET 8, where you typically used one of Blazor’s hosting models (Server or WASM) for your entire app.

So if you’re migrating from an existing app this can be a useful stepping stone to .NET 8.

However, if your app could benefit from using static server-side rendering for some of its pages/components, then choosing Per Page/Component leaves you free to pick and choose which components run interactively (and which render mode you want them to use).

In Summary

.NET 8 brings more power, and inevitably more complexity to your Blazor web apps.

The big change lies in how and when you run your components ‘interactively’.

When you create your new Blazor web app you can choose which of the interactive render modes you want your app to support, plus whether you want everything to run interactively, or just the components you specify.

Of course, you can always change these options later one, either adding or removing support for the various render modes, or tweaking which components run interactively…

But it’s worth knowing what you’re getting into when you spin up that new .NET8 Blazor web project!

Join the Practical ASP.NET Newsletter

Ship better Blazor apps, faster. One practical tip every Tuesday.

I respect your email privacy. Unsubscribe with one click.

    Next up

    How to upload a file with Blazor SSR in .NET 8?
    How to handle file uploads without using an interactive render mode?
    3 simple design tips to improve your Web UI
    Spruce up your features
    The quickest way to integrate PayPal checkout with Blazor SSR in .NET 8
    JavaScript Interop works differently with Blazor Server-side rendering