Telerik blogs

Shared Blazor components can power UI across web and native apps, thanks to .NET MAUI.

.NET MAUI is the future of cross-platform development with .NET—a single shared code base can power native apps for mobile and desktop. And Blazor is the natural choice for modern web apps with .NET, helping developers write C# front and back.

We’ve heard the promise of .NET MAUI and Blazor together—but how realistic is it? Can Blazor developers truly power native apps with .NET MAUI while using shared components and styles? The answer is yes—let’s take a look.

Blazor Inside .NET MAUI

.NET MAUI welcomes Blazor and other web frameworks to native land with a modern WebView. BlazorWebView is a smart UI component—an abstraction that knows how to grab the browser WebView on corresponding platforms, like iOS/Android/Windows/Mac. Developers get to render web UI on mobile/desktop apps, with the full benefit of .NET MAUI—shared cross-platform code, application lifecycle hooks and easy platform API access.

There are templates to get developers started using Blazor with .NET MAUI—the .NET MAUI Blazor App for Visual Studio or maui-blazor for Command Line tooling. The resulting project sets things up nicely: Pages, Shared and wwwroot—these are all artifacts known to Blazor web developers, now ready for use inside .NET MAUI apps. The MainPage hosts the WebView—and off we go with Blazor routing, components, layouts and styles.

Pages, Shared, wwwroot are all present

As nice as Blazor is within .NET MAUI, the real appeal is to lure web developers to now start building cross-platform native apps. Real .NET web developers are likely already building/maintaining web apps with Blazor—it may be impractical to have them bring all Blazor assets now within a .NET MAUI app. What is much more realistic is to reuse Blazor code within native apps—while at the same time, serving the web application.

Blazor Across Web and Native

So, how do Blazor and .NET MAUI co-exist while serving their respective platforms? Simple—put them all together in a single solution and keep the common assets shared. This is not doable directly from a Visual Studio template, but totally achievable if the parts of the puzzle are broken up. Let’s look at a solution:

BlazorEverywhere has BlazorForWeb.Client, BlazorForWeb.Server, BlazorForWeb.Shared, BlazorForNative, and BlazorSharedUI

Here are the pieces:

  1. BlazorEverywhere – An empty VS solution
  2. BlazorForWeb.Client – The Blazor WebAssembly client-side project
  3. BlazorForWeb.Server – Optional ASP.NET hosted Backend project (for API services)
  4. BlazorForWeb.Shared – Shared project between Blazor Web and Server (for business logic/validations, etc.)
  5. BlazorForNative – A .NET MAUI project with Blazor template
  6. BlazorSharedUI – A Razor Class Library project for sharing Blazor assets across web and native AppAssembly

The goal is to have the Blazor bits drive the existing web app as usual, but the same components/styles light up UI on mobile/desktop apps through .NET MAUI. The only way to achieve this is to keep them in a shared project—a separate Razor Class Library works perfectly. The parts of the Blazor app that actually render UI—Pages, Shared and wwwroot folders, can be conveniently moved into the Shared UI project.

Pages, Shared and wwwroot folders now in the Shared UI project

The Blazor project for web and the .NET MAUI project embedding Blazor UI in native apps don’t need to have the rendering pieces—they simply need a reference to the Shared UI library, like so:

Under BlazorForNative - Dependencies - net6.0-ios - Projects is BlazorSharedUI

Shared UI Across Platforms

Now that the UI rendering pieces are shared between the web and native platform projects, how would they be used from Blazor across platforms?

First up, both the Blazor for web and the .NET MAUI project embedding Blazor, have the _Imports.razor file in the wwwroot folder—this is how Blazor gets all of its dependencies. The Shared UI project/namespace references need to be added here:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorForWeb.Client
@using BlazorSharedUI
@using BlazorSharedUI.Shared

Both Blazor for web and Blazor for .NET MAUI start off with App.razor/Main.razor which loads up routing/components and the MainLayout—this is skeleton structure of the Blazor views. Since the Shared folder now houses the MainLayout outside of the Blazor for web and the .NET MAUI with Blazor projects, it needs to be pointed out explicitly to come from the Shared UI external assembly—this needs to be done for both web and native projects.

@using BlazorSharedUI.Shared

<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new[] { typeof(BlazorSharedUI.Shared.MainLayout).Assembly }">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

That is all. The Blazor project for web apps continue to work as usual—just pulling UI from the Shared UI project. And the .NET MAUI project works on iOS/Android/Windows/Mac embedding Blazor UI through WebView—also pulling from the same Shared UI project. Blazor is truly everywhere now—all it takes for developers is switch which app is the Startup Project in Visual Studio.

Shared Styles Across Platforms

While all the Blazor components have been moved off to a Shared UI project, both the Blazor for web and the .NET MAUI project with Blazor do maintain the starting artifact of any web-based UI—the index.html file in the wwwroot folder. This is responsible for providing structure to the HTML view, a placeholder for components and pulling in any JavaScript references. Since all the CSS for styling has been moved off to the Shared UI project, the CSS references need to be updated accordingly:

<!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, viewport-fit=cover" />
    <title>BlazorForNative</title>
    <base href="/" />
    <link rel="stylesheet" href="_content/BlazorSharedUI/css/bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="_content/BlazorSharedUI/css/app.css" />
    <link href="BlazorForNative.styles.css" rel="stylesheet" />
</head>

<body>
    <div class="status-bar-safe-area"></div>
    <div id="app">Loading...</div>

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

    <script src="_framework/blazor.webview.js" autostart="false"></script>
</body>
</html>

With a shared app.css file that is used from the Shared UI library by both the Blazor for web and the .NET MAUI project with Blazor, there is now a easy way to apply styles—and have a global impact across platforms.

@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

.btn-primary {
    color: #fff;
    background-color: red;
    border-color: #1861ac;
}

...
...       

P.S. Need to follow along as you play with Blazor and .NET MAUI? Source code for the article is here.

That’s a Wrap

Blazor is understandably the most exciting web framework for .NET developers—allowing C# front and back through WebAssembly. And .NET MAUI ushers in the next generation of native cross-platform development on .NET, effortlessly reaching mobile/desktop platforms from a single codebase. With a modern WebView UI component, .NET MAUI welcomes Blazor to native land—web components and styles can be rendered inside native apps on iOS/Android/Windows/Mac.

An exciting prospect for Blazor with .NET MAUI is when web developers can reuse web assets/code for reaching mobile/desktop platforms. With a little bit of shuffle of key web rendering pieces, a shared library can house all of the UI and styles—to be used for both web and native apps. Developers get to maintain web components in one spot and reuse them for Blazor apps on the web or Blazor views inside of mobile/desktop apps with .NET MAUI.


Blazor for .NET MAUI: What, How and When


SamBasu
About the Author

Sam Basu

Sam Basu is a technologist, author, speaker, Microsoft MVP, gadget-lover and Progress Developer Advocate for Telerik products. With a long developer background, he now spends much of his time advocating modern web/mobile/cloud development platforms on Microsoft/Telerik technology stacks. His spare times call for travel, fast cars, cricket and culinary adventures with the family. You can find him on the internet.

Related Posts

Comments

Comments are disabled in preview mode.