maui-blazor-development

.NET MAUI Blazor Hybrid Development

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "maui-blazor-development" with this command: npx skills add ibutters/claudecodeplugins/ibutters-claudecodeplugins-maui-blazor-development

.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

  1. 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

  1. 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&#x3C;IDeviceService, DeviceService>();
builder.Services.AddScoped&#x3C;IDataService, DataService>();

return builder.Build();

}

  1. 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");

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

storybook

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-typescript

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

atomic-design

No summary provided by upstream source.

Repository SourceNeeds Review