Telerik blogs

The first of .NET 8’s Release Candidates brings Blazor's new features together in a unified project template.

.NET 8 Release Candidate 1 has shipped, and with it comes the best glimpse yet of what’s coming for .NET in November. Here are the key changes that landed with this release.

Get up and Running Quickly with the New Project Template

A big part of any web framework is how easy it is to get started.

.NET 8 ships with a new Blazor web app project template which combines server-side rendering with support for interactive components using Blazor Server and (optionally) Blazor WASM.

It enables enhanced navigation and form handling by default—when your users navigate between pages in your app or submit forms, the browser’s fetch API will be used (in favor of performing full page posts). Effectively this provides a “SPA-like” experience even though you’re not actually running Blazor as a SPA (single-page application).

For example, when you submit a form in a new Blazor .NET 8 app, the user’s scroll position will be retained.

There are a few new configuration options when spinning up a new project. Here are the key ones (and how they affect the resulting project).

In all cases the project uses Server-side rendering for components by default.

Use Interactive Server Components

This is true by default.

With this enabled, the resulting web app includes support for interactive components using Blazor Server.

dotnet new blazor --use-server true

This results in this configuration (to enable server components).

Program.cs

builder.Services.AddRazorComponents()
    .AddServerComponents();

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

The Counter demo component has the RenderModeServer attribute (it will run interactively using Blazor Server):

Counter.razor

@attribute [RenderModeServer]

Use Interactive WebAssembly Components

False by default.

This enables support for interactive components using Blazor WASM.

Here’s the command to use enable WASM “exclusively” (including disabling Blazor Server support, which is otherwise enabled by default).

dotnet new blazor --use-server false --use-wasm true

Program.cs

builder.Services.AddRazorComponents()
    .AddWebAssemblyComponents();
    
...

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

With this enabled, your solution will have two projects—the base project plus a .Client project.

In the .Client project, Counter.razor includes the RenderModeWebAssembly attribute, and runs interactively using Blazor WASM.

@attribute [RenderModeWebAssembly]

Using Both Interactive Modes

You can opt to enable support for interactivity using both WASM and Server.

dotnet new blazor --use-server true --use-wasm true

Program.cs

builder.Services.AddRazorComponents()
    .AddServerComponents()
    .AddWebAssemblyComponents();

...

app.MapRazorComponents<App>()
    .AddServerRenderMode()
    .AddWebAssemblyRenderMode();

With this, you’ll find your Counter component uses the new auto render mode:

Counter.razor

@attribute [RenderModeAuto]

In this mode, Counter will use Blazor Server initially, while the .NET runtime and app bundle is downloaded to the browser. On subsequent visits to the same component, Auto will switch to using WebAssembly instead.

Start with an ‘Empty’ Project

One final handy option is whether to include sample pages (or not). This affects whether you get the usual Counter, Weather components and layout based on Bootstrap styling.

 dotnet new blazor --empty

Auth? Not in the Template Yet

If you’re expecting to see options for enabling Auth in the project template, you might be surprised to see its omission in RC1.

According to various comments from MS employees (and open tickets in the official repo on GitHub), a new option for enabling Auth should land in RC2. With that will come several components for Auth. They will interact with the new MS Identity endpoints that you can enable when you configure your project.

Stay tuned for news of RC2 when it lands in October.

New Solution Layout

Blazor has had the same folder layout from its inception, with a single Pages folder for housing your components.

This release tweaks that structure slightly.

There is now a Components folder in the root of your project. It contains a Components/Layout folder (containing the MainLayout and NavMenu components).

There is also a Components/Pages folder which contains the ‘routable’ page components for the app.

App.razor is a little bit leaner in this release.

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

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <base href="/" />
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="BlazorApp51.styles.css" />
    <link rel="icon" type="image/png" href="favicon.png" />
    <HeadOutlet />
</head>

<body>
    <Routes />    
</body>

</html>

With Blazor SSR, this component acts as the entry point for your App.

This is configured in Program.cs:

app.MapRazorComponents<App>()
    .AddServerRenderMode()
    .AddWebAssemblyRenderMode();

Notice the new Routes component.

<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] { typeof(Client._Imports).Assembly }">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
</Router>

This contains the Router for your app and is the key place to go if you want to change things like the default layout.

In this example, I’m using Blazor WASM—the AdditionalAssemblies parameter ensures .NET can route requests to components located within the separate Client project.

It’s worth taking a quick look at Components/Layout/MainLayout.razor too:

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            @Body
        </article>
    </main>
</div>

<div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
</div>

The notable change being that the default Blazor error UI now lives here.

Make the Entire App Interactive?

If you use this new project template but want to run your entire app interactively (using WASM or Server), you can.

The trick is to specify the render mode for the HeadOutlet and Routes components when they’re rendered in App.razor.

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

<head>
    ...
    
    <HeadOutlet @rendermode="@RenderMode.Server"/>
</head>

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

</html>

With this, we’re effectively running the entire app using Blazor Server (SSR won’t be used for any of the pages).

Use SSR with Components from Other Assemblies

Sometimes you might choose to locate your components in a separate project but still use static server-side rendering to render them.

A new configuration option enables that in Program.cs:

app.MapRazorComponents<App>()
    .AddAdditionalAssemblies(typeof(Counter).Assembly);

This example assumes Counter lives in a separate project (and therefore assembly).

With this, you can store your components in any assembly and still have .NET route requests to them as part of your app.

Refresh Pages at Will

If you’re using SSR with your blazor components, you may run into a scenario where you want to refresh the page from code. You can now do this, and .NET 8 will attempt to use enhanced page navigation to perform the refresh.

This means it will use the browser’s fetch API then “patch” the DOM with the HTML that comes back (to save reloading the entire page). If it can’t use enhanced navigation for any reason, it will perform a full page refresh.

NavigationManager.Refresh();

QuickGrid

It feels like the new QuickGrid component has flown under the radar during .NET 8’s preview releases, with little coverage compared to other .NET 8 features.

If you’re wondering what QuickGrid is and why you would use it, check out the official examples here:

https://aspnet.github.io/quickgridsamples/

It’s worth noting the grid is not intended as a replacement for more fully featured grids (such as Progress Telerik’s excellent Blazor Grid), but rather as a convenient and quick way to show data in your Blazor component.

Routing Improvements, WASM Runtime Configuration and More

Finally, as the RTM draws ever closer, .NET 8 RC1 delivers a few small but key improvements.

Check out the official release notes for the RC here. They outline some other areas of improvement, namely:

  • Blazor routing is now unified with ASP.NET Core routing, which brings support for Complex Segments, Default values and additional route constraints.
  • It’s now possible to pass any parameter you like to QuickGrid and it will forward them on to the resulting table HTML element.
  • You can check if an EditForm field is valid using EditContext.IsValid(FieldId).
  • It’s now possible to configure the .NET WASM runtime during startup using the new configureRuntime function.
  • You can try the new, snappily titled WasmStripILAfterAOT option with your Blazor WASM applications to trim some code from the bundle that gets downloaded by the browser (reduces the size by 1.7% to 4.2% in Microsoft’s tests).

In Summary

RC1 delivers .NET 8’s new Blazor features and provides a reliable “out-of-the-box” experience when you spin up a new Blazor web app.

You can now choose to enable interactivity using WASM or Server (or both) when creating your projects. The resulting project includes simplified base components (including the new Routes component).

Finally, while this release doesn’t include Auth in the new template, that should be addressed in RC2.


Jon Hilton
About the Author

Jon Hilton

Jon spends his days building applications using Microsoft technologies (plus, whisper it quietly, a little bit of JavaScript) and his spare time helping developers level up their skills and knowledge via his blog, courses and books. He's especially passionate about enabling developers to build better web applications by mastering the tools available to them. Follow him on Twitter here.

Related Posts

Comments

Comments are disabled in preview mode.