1. What is Masa Blazor
Before this, we have already introduced what Masa Blazor is and how to use Masa Blazor. If you are still unfamiliar with Masa Blazor, you can refer to my previous article Getting to Know Masa Blazor. Today, let's explore how to use Masa Blazor in MAUI. First, let's understand what MAUI is.
2. What is MAUI
.NET MAUI stands for .NET Multi-platform App UI, which is a cross-platform framework evolved from Xamarin.Forms. It uses C# and XAML to create native mobile and desktop applications. Here, XAML can be replaced with RazorView. Using .NET MAUI, you can develop applications that run on Android, iOS, macOS, Windows, and Linux (community support) from a single shared codebase — one codebase for multiple platforms.

2.1 Advantages of MAUI
- Write cross-platform Visual Studio solutions from a single shared codebase using XAML and C#.
- Share UI layouts and designs across platforms.
- Share code, tests, and business logic across platforms.
- Another advantage is the cross-framework reuse of
Razorcomponents, which can be implemented asRazorclass libraries (RCL) and shared withBlazor ServerandWebAssembly. This maximizes code reuse and enables generatingmobile,desktop, andwebsolutions from a single codebase.
Today, we will focus on hands-on practice and not introduce too many conceptual things. For those who want to learn more about MAUI, please refer to the official documentation What is .NET MAUI?. This article will guide you through creating a common timeline page using MAUI + Masa Blazor for mobile, with a small feature for switching theme colors. The effect is shown below:


Now let's implement it step by step. First, we need to prepare the necessary environment.
Note: The demo environment in this article is (Maui 6.0.200-preview.14.5 + Masa.Blazor 0.3.0)
3. MAUI Environment Setup
- Ensure you have installed the
latest version of Visual Studiowith theMobile development with .NETworkload.

- Enable hardware acceleration to maximize Android emulator performance. You can enable
Hyper-VorHAXMacceleration. Here we only introduce the first method:
- In the Windows search box, type "Windows Features" and select "Turn Windows features on or off" from the results. In the "Windows Features" dialog, enable "Hyper-V" and "Windows Hypervisor Platform":

After making these changes, restart your computer.
Ensure that the virtual device created in Android Device Manager uses an x86_64 or x86-based system image. Using an Arm-based system image will not accelerate the virtual device, and it will run slowly. After enabling Hyper-V, you can run the accelerated Android emulator. For detailed settings on HAXM acceleration, refer to: How to use Android Emulator & Enable Hardware Acceleration.
4. Create a MAUI App and Introduce Masa Blazor
- Create a new project and select
.NET MAUI Blazor App. This allows us to useBlazor Viewto write the UI.

- Install
Masa.Blazorfrom NuGet and register the related service in theMauiProgram.csfile.

builder.Services.AddMasaBlazor();
The
CreateMauiApp()method can be simply understood as: in the startup method, an extension method of the builder objectRegisterBlazorMauiWebView()is called, and thenBlazorWebViewitself is added to theDIcontainer's Services collection via thebuilder.Servicesproperty. This performs dependency injection to load platform-specific views for rendering the output HTML. Since each platform has its own web engine, theBlazorWebView(inheriting fromView) control can process Razor components at runtime and generate their equivalent HTML. That HTML will be rendered using the platform's native web engine without any web server involvement.
- In
wwwroot/index.html, include the styles, fonts, and scripts.

<link href="_content/Masa.Blazor/css/masa-blazor.css" rel="stylesheet" />
<link href="_content/Masa.Blazor/css/masa-extend-blazor.css" rel="stylesheet" />
<link
href="https://cdn.masastack.com/npm/@mdi/font@5.x/css/materialdesignicons.min.css"
rel="stylesheet"
/>
<link
href="https://cdn.masastack.com/npm/materialicons/materialicons.css"
rel="stylesheet"
/>
<link
href="https://cdn.masastack.com/npm/fontawesome/v5.0.13/css/all.css"
rel="stylesheet"
/>
<script src="_content/BlazorComponent/js/blazor-component.js"></script>
<script src="https://cdn.masastack.com/npm/echarts/5.1.1/echarts.min.js"></script>
<!-- The echarts script file can be omitted if not needed -->
Note:
- In MAUI projects, these files need to be referenced in
index.html, not inPages/_Layout.cshtmlas in Blazor.- Starting from Masa Blazor 0.3.0, it adopts the same naming convention as Microsoft (PascalCase). "MASA" was changed to "Masa". So when upgrading to 0.3.0 or later versions, be careful not to miswrite, otherwise the style files and js files will not be found.
- In the
_Imports.razorfile, reference theMasa.BlazorandBlazorComponentnamespaces. This way we don't need to reference them in every file.
5. Implement the Timeline Feature
First, design the approximate layout of our page in the layout page MainLayout.razor. We need a Toolbar at the top, a bottom navigation at the bottom, and the child page content in the middle.
This is a common layout. Clicking the menu on the toolbar allows us to switch the theme color. Let's implement it simply with Masa Blazor.
For the top toolbar, we mainly use the MToolbar component and MMenu component. For the bottom, since the BottomNavigation component is not yet available in the official site (it will be released in later versions), we will use the MFooter component instead. This way, our layout template page is ready. The global color is stored in a variable and controlled by the value selected in MMenu.

Mainlayout.razor complete code:
@inherits LayoutComponentBase
<MApp>
<MToolbar MaxHeight="64" Color="@_color" Dark>
<MAppBarNavIcon></MAppBarNavIcon>
<MSpacer></MSpacer>
Timeline
<MSpacer></MSpacer>
<MMenu Left OffsetY Transition="slide-x-transition" Bottom>
<ActivatorContent>
<MButton Icon @attributes="@context.Attrs">
<MIcon>mdi-dots-vertical</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<MList>
@foreach (var item in _colors) {
<MListItem OnClick="()=>{_color = item.Value;}">
<MListItemTitle>@item.Text</MListItemTitle>
</MListItem>
}
</MList>
</ChildContent>
</MMenu>
</MToolbar>
<div style="width:100%; height:100%">
<CascadingValue Value="_color"> @Body </CascadingValue>
</div>
<MFooter Color="#FAFAFA" Elevation="2">
<MRow NoGutters Justify="JustifyTypes.SpaceBetween">
<MCol Style="display:flex; justify-content:center;">
<MButton Color="@_color" Icon Class="my-2 white--text">
<MBadge OverLap Color="error" Content="6">
<ChildContent>
<MIcon>mdi-chat</MIcon>
</ChildContent>
</MBadge>
</MButton>
</MCol>
<MCol Style="display:flex; justify-content:center;">
<MButton Color="@_color" Icon Class="my-2 white--text">
<MIcon>mdi-account-details</MIcon>
</MButton>
</MCol>
<MCol Style="display:flex; justify-content:center;">
<MButton Color="@_color" Icon Class="my-2 white--text">
<MIcon>mdi-compass</MIcon>
</MButton>
</MCol>
</MRow>
</MFooter>
</MApp>
@code{
private string _color = "purple darken-3";
private List<(string Text, string Value)> _colors = new()
{
new("pink", "purple darken-1"),
new("indigo", "indigo"),
new("teal", "teal"),
new("deep-purple", "deep-purple darken-1"),
new("yellow", "yellow darken-4"),
};
}
Next, let's implement the Body page, which is our main content. We can find the Timelines component on the Masa Blazor official site and use it directly. The official site happens to have a mobile Timeline demo, but it doesn't have the color-changing feature. No worries, we can take it and modify it.

We copy the code and remove its toolbar because we already have one in the layout page, and it applies to every child page. But here we need to consider how to pass the _color parameter to the Timeline page. We use cascading parameters: pass the parameter to the child page via CascadingValue, and the child page receives it via CascadingParameter. This way, we can access the color variable in the child page.

Timeline.razor complete code:
@page "/"
<MCard Elevation="0" Class="mx-auto">
<MCard Dark Flat>
<MButton Absolute Bottom Color="@Color" Right Fab>
<MIcon>mdi-plus</MIcon>
</MButton>
<MImage
Src="https://cdn.masastack.com/stack/images/website/masa-blazor/cards/forest.jpg"
Gradient="to top, rgba(0,0,0,.44), rgba(0,0,0,.44)"
Dark
>
<MContainer Class="fill-height">
<MRow Align="@AlignTypes.Center">
<strong class="text-h1 font-weight-regular mr-6">8</strong>
<MRow Justify="@JustifyTypes.End">
<div class="text-h5 font-weight-light">Monday</div>
<div class="text-uppercase font-weight-light">February 2015</div>
</MRow>
</MRow>
</MContainer>
</MImage>
</MCard>
<MCardText Class="py-0">
<MTimeline AlignTop Dense>
<MTimelineItem Color="pink" Small>
<MRow Class="pt-1">
<MCol Cols="3">
<strong>5pm</strong>
</MCol>
<MCol>
<strong>New Icon</strong>
<div class="text-caption">Mobile App</div>
</MCol>
</MRow>
</MTimelineItem>
<MTimelineItem Color="@Color" Small>
<MRow Class="pt-1">
<MCol Cols="3">
<strong>3-4pm</strong>
</MCol>
<MCol>
<strong>Design Stand Up</strong>
<div class="text-caption mb-2">Hangouts</div>
<MAvatar>
<MImage
Src="https://avataaars.io/?avatarStyle=Circle&topType=LongHairFrida&accessoriesType=Kurt&hairColor=Red&facialHairType=BeardLight&facialHairColor=BrownDark&clotheType=GraphicShirt&clotheColor=Gray01&graphicType=Skull&eyeType=Wink&eyebrowType=RaisedExcitedNatural&mouthType=Disbelief&skinColor=Brown"
></MImage>
</MAvatar>
<MAvatar>
<MImage
Src="https://avataaars.io/?avatarStyle=Circle&topType=ShortHairFrizzle&accessoriesType=Prescription02&hairColor=Black&facialHairType=MoustacheMagnum&facialHairColor=BrownDark&clotheType=BlazerSweater&clotheColor=Black&eyeType=Default&eyebrowType=FlatNatural&mouthType=Default&skinColor=Tanned"
></MImage>
</MAvatar>
<MAvatar>
<MImage
Src="https://avataaars.io/?avatarStyle=Circle&topType=LongHairMiaWallace&accessoriesType=Sunglasses&hairColor=BlondeGolden&facialHairType=Blank&clotheType=BlazerSweater&eyeType=Surprised&eyebrowType=RaisedExcited&mouthType=Smile&skinColor=Pale"
></MImage>
</MAvatar>
</MCol>
</MRow>
</MTimelineItem>
<MTimelineItem Color="pink" Small>
<MRow Class="pt-1">
<MCol Cols="3">
<strong>12pm</strong>
</MCol>
<MCol>
<strong>Lunch break</strong>
</MCol>
</MRow>
</MTimelineItem>
<MTimelineItem Color="@Color" Small>
<MRow Class="pt-1">
<MCol Cols="3">
<strong>9-11am</strong>
</MCol>
<MCol>
<strong>Finish Home Screen</strong>
<div class="text-caption">Web App</div>
</MCol>
</MRow>
</MTimelineItem>
</MTimeline>
</MCardText>
</MCard>
@code{
[CascadingParameter]
public string Color { get; set; }
}
Then, change the colors that should follow the theme color to be controlled by the Color variable.

In this way, we have completed a timeline page with theme color switching. We could also add more features based on this demo, such as clicking the "+" button to open a dialog and add a timeline task, then render it on the page. That is quite simple, so we won't demonstrate it here. This article mainly introduces how to use Masa Blazor in MAUI and creates a small demo. As a primer, everyone can try using MAUI + Blazor to build some applications and experience it.
Complete sample code: codding-y/Maui.MasaBlazor (github.com)
Open Source Addresses
MASA.BuildingBlocks: https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib: https://github.com/masastack/MASA.Contrib
MASA.Utils: https://github.com/masastack/MASA.Utils
MASA.EShop: https://github.com/masalabs/MASA.EShop
MASA.Blazor: https://github.com/BlazorComponent/MASA.Blazor
If you are interested in our MASA Framework, whether it's code contributions, usage, or raising issues, feel free to contact us.
