Starting with ASP.NET Core 3.0, you can add Blazor components to your existing ASP.NET Core (MVC, Razor Pages) application.

This is a great way to test the ground with Blazor, without chucking everything you have in the bin and starting over!

Here’s how to do it using ASP.NET Core 3.1 (released December 3rd 2019).

In your existing ASP.NET Core 3 app, you’ll need to update ConfigureServices in startup.cs to add all the services required for Blazor Server.

services.AddServerSideBlazor();

Now you can add the MapBlazorHub call in Configure to register the Blazor Hub endpoint (which Blazor Server uses to communicate with the browser).

app.UseEndpoints(endpoints =>
{	
    endpoints.MapRazorPages(); // existing endpoints
    endpoints.MapBlazorHub();                
});

Almost there; at this point your ASP.NET Core application is ready to process and render Blazor components.

Now you just need to render one!

You can add a .razor component somewhere in your application (for now I just put mine in the Pages folder and called it HelloWorld.razor).

@page "/Hello"

<h3>HelloWorld</h3>

Hello @Name

<button @onclick="Toggle">Toggle</button>

@code {
    public string Name { get; set; } = "Jon";

    protected async Task Toggle()
    {
        if (Name == "Jon")
        {
            Name = "Susan";
        }
        else
        {
            Name = "Jon";
        }
    }
}

Finally, you can take an existing page like Index.cshtml and add some code to render your component:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<script src="~/_framework/blazor.server.js"></script>

<component type="typeof(HelloWorld)" render-mode="ServerPrerendered" />

First we’ve added a reference to blazor.server.js; this is required for Blazor to communicate between the browser and your application. You’ll find this script is automatically made available by your ASP.NET Core application.

Then we’ve used the component tag helper (new in ASP.NET Core 3.1) to render the HelloWorld component.

If you’re using ASP.NET Core 3.0, you’ll need to use HTML.RenderComponentAsync instead:

@(await Html.RenderComponentAsync<HelloWorld>(RenderMode.ServerPrerendered))

Spin this up in the browser now and you’ll see your component, rendered in all its glory (in your Razor page!)

However, the Toggle button won’t work until we take one more step.

Add an _Imports.razor file to your Pages folder:

@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Web

With that, your application has everything it needs to support Razor components; the HelloWorld component renders, and clicking the button changes the Name and re-renders the markup accordingly.

Move the Blazor script to shared layout

Now this works, but we can improve things further.

Currently, a SignalR connection will be opened up every time you navigate to Index.cshtml.

This might be less than desirable, not least because you get a small flash of content appearing every time this connection is made.

So a better option is probably to put this in your application’s Layout page (assuming you have one).

Shared/_Layout.cshtml

<!-- other scripts -->

<script src="~/_framework/blazor.server.js"></script>

@RenderSection("Scripts", required: false) <!-- existing code -->
</body>

What is RenderMode?

In this example I used RenderMode.ServerPrerendered.

You might be wondering what this means.

Essentially, there are three ways to render Blazor components in a Razor View or Page.

Static

ASP.NET will render the component at the same time as the rest of the page and return static html to your browser.

Server

ASP.NET will render a marker for the component, and return that with the rest of the page, at which point Blazor (running in the browser) will open up its socket connection to the server, render the component and then update the DOM in the browser to display the component.

ServerPrerendered

A kind of “best of both worlds”.

ASP.NET will render and return the component’s markup with the rest of the page. Then it will act the same as Server mode whereby it will include a marker for the component and set up a Blazor connection.

Which RenderMode?

Each of these three options has trade-offs, but the main thing to watch out for is performance and how they work with Seach Engines.

With RenderMode.Static your page is rendered entirely, in one call to the server.

This means, if a search engine comes along and requests your page, it will get the entire thing back (including your component) and can index it accordingly.

You can see this for yourself in the browser; hit your page and notice how the component markup is returned as part of the page response (this is using Firefox Dev Tools)…

However, the component is essentially “non-interactive” at this point. So clicking the Toggle button won’t do anything at all.

With RenderMode.Server mode, the opposite is true.

Your component won’t be rendered in the initial response when you visit the page:

Instead, Blazor will kick in after your page is rendered and then render the component (via the socket connection it opens up with your server).

Now the Toggle button works, but search engines won’t “see” that component markup when they index the page.

Finally, RenderMode.ServerPrerendered does both.

You get the initial markup for the component in the initial page response, then Blazor kicks in and opens up its socket connection for further interactions with the component.

Next Steps

Adding Blazor to your existing ASP.NET Core 3 app turns out to be relatively straightforward; you can give Blazor a try, without affecting the rest of your application and see for yourself whether you find it a productive way to build your application’s user interface.

Your simplest next step might be to take some small part of your UI (like a table, list, or some other read-only component) and try building that as a Blazor component.

That way, you can quickly get a feel for how building components differs from building pages or views before moving on to more “interactive” components (using callbacks etc).

Next up

Custom validation logic on client AND server with Blazor?
It would be pretty handy if you could write one validator and have your validation rules run seamlessly on both client and server…
Go faster with your own re-usable Blazor components
You can easily avoid re-inventing the same wheels over and over when you break your UI down into re-usable components
3+1 ways to manage state in your Blazor application
As soon as you have more than one Blazor component you need to think how you’ll communicate between them.