maui-blazor-development
SKILL.md
.NET MAUI Blazor Hybrid Development
Expert guidance for building cross-platform apps with .NET MAUI and Blazor.
Implementation Workflow
1. Analysis Phase (Required)
Before implementation, determine:
- App type: Pure MAUI Blazor or MAUI + Blazor Web App (shared UI)
- Platform targets: Android, iOS, Windows, macOS
- Native features needed: Sensors, camera, file system, notifications
- State management: Component state, MVVM, or hybrid approach
- Navigation pattern: Blazor-only, Shell, or mixed navigation
2. Architecture Decision
| Scenario | Recommended Approach |
|---|---|
| Mobile-first with some web | maui-blazor template |
| Shared UI across mobile + web | maui-blazor-web template with RCL |
| Complex native integration | MVVM with platform services |
| Simple data-driven UI | Component state with DI services |
3. Project Setup
// MauiProgram.cs - Essential setup
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
builder.Services.AddMauiBlazorWebView();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
#endif
// Register services
builder.Services.AddSingleton<IDeviceService, DeviceService>();
builder.Services.AddScoped<IDataService, DataService>();
return builder.Build();
}
4. BlazorWebView Configuration
<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:b="clr-namespace:Microsoft.AspNetCore.Components.WebView.Maui;assembly=Microsoft.AspNetCore.Components.WebView.Maui">
<b:BlazorWebView HostPage="wwwroot/index.html">
<b:BlazorWebView.RootComponents>
<b:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
</b:BlazorWebView.RootComponents>
</b:BlazorWebView>
</ContentPage>
Core Patterns
Dependency Injection
| Lifetime | Use Case |
|---|---|
AddSingleton<T> |
App-wide state, device services, settings |
AddScoped<T> |
Per-BlazorWebView instance state |
AddTransient<T> |
Stateless utilities, factories |
// Interface for platform-specific implementation
public interface IDeviceService
{
string GetDeviceModel();
Task<bool> HasPermissionAsync(string permission);
}
// Platform implementation registered in MauiProgram.cs
builder.Services.AddSingleton<IDeviceService, DeviceService>();
Component Lifecycle
@code {
[Parameter] public string Id { get; set; } = "";
// Called once when component initializes
protected override async Task OnInitializedAsync()
{
await LoadDataAsync();
}
// Called when parameters change (including first render)
protected override void OnParametersSet()
{
// React to parameter changes
}
// Called after each render
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
// JS interop safe here
}
}
}
Platform Feature Access
// Check platform and access native features
@inject IDeviceService DeviceService
@if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
<AndroidSpecificComponent />
}
@code {
private async Task AccessCameraAsync()
{
var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.Camera>();
}
if (status == PermissionStatus.Granted)
{
// Use camera
}
}
}
State Updates from External Events
@implements IDisposable
@inject IDataService DataService
<p>@message</p>
@code {
private string message = "";
protected override void OnInitialized()
{
DataService.OnDataChanged += HandleDataChanged;
}
private async void HandleDataChanged(object? sender, EventArgs e)
{
message = "Data updated!";
await InvokeAsync(StateHasChanged); // Required for external events
}
public void Dispose()
{
DataService.OnDataChanged -= HandleDataChanged;
}
}
Reference Documentation
For detailed patterns and examples, see:
- Project Structure: Solution templates, RCL setup, multi-targeting
- Blazor Components: Lifecycle, RenderFragment, EventCallback, data binding
- Platform Integration: Device APIs, permissions, platform-specific code
- Navigation & Routing: Blazor routing, Shell, deep linking
- State Management: MVVM, DI patterns, CommunityToolkit.Mvvm
Quick Reference
Common Service Registration
// Services
builder.Services.AddSingleton<ISettingsService, SettingsService>();
builder.Services.AddSingleton<IConnectivity>(Connectivity.Current);
builder.Services.AddSingleton<IGeolocation>(Geolocation.Default);
// ViewModels (if using MVVM)
builder.Services.AddTransient<MainViewModel>();
builder.Services.AddTransient<SettingsViewModel>();
// Pages with DI
builder.Services.AddTransient<MainPage>();
Platform Checks
// Runtime platform check
if (DeviceInfo.Current.Platform == DevicePlatform.iOS) { }
if (DeviceInfo.Current.Platform == DevicePlatform.Android) { }
if (DeviceInfo.Current.Platform == DevicePlatform.WinUI) { }
if (DeviceInfo.Current.Platform == DevicePlatform.macOS) { }
// Compile-time platform check
#if ANDROID
// Android-specific code
#elif IOS
// iOS-specific code
#elif WINDOWS
// Windows-specific code
#endif
Navigation Patterns
// Blazor navigation (within BlazorWebView)
@inject NavigationManager Navigation
Navigation.NavigateTo("/details/123");
// MAUI navigation (to other pages)
await Navigation.PushAsync(new SettingsPage());
await Shell.Current.GoToAsync("//settings");
Weekly Installs
43
Repository
ibutters/claude…epluginsGitHub Stars
1
First Seen
Jan 25, 2026
Security Audits
Installed on
opencode36
gemini-cli34
github-copilot34
codex33
kimi-cli28
amp28