.NET MAUI Blazor Hybrid 2026: Web-Komponenten in nativen Apps mit BlazorWebView

Praxisleitfaden zu .NET MAUI Blazor Hybrid in .NET 10: Razor-Komponenten in nativen Apps mit BlazorWebView einbetten, Code zwischen Web und Mobile teilen, native APIs nutzen und Startzeit optimieren. Mit Code-Beispielen aus produktiven Kundenprojekten.

MAUI Blazor Hybrid: BlazorWebView 2026

Aktualisiert: 11. Juli 2026

.NET MAUI Blazor Hybrid ist ein Anwendungsmodell, mit dem Razor-Komponenten direkt in eine native .NET MAUI-App eingebettet und plattformübergreifend gerendert werden. Der Unterschied zu klassischem Blazor Server oder WebAssembly: Die Komponenten laufen im gleichen Prozess wie die MAUI-App und greifen über BlazorWebView direkt auf native Gerätefunktionen zu, ohne Umweg über HTTP oder eine JavaScript-Bridge. In diesem Praxisleitfaden für .NET 10 zeige ich dir, wann Blazor Hybrid wirklich der richtige Weg ist, wie ein Projekt in unter 15 Minuten läuft und welche Fallstricke mir in meinen letzten drei Beratungsprojekten am häufigsten unter die Räder gekommen sind.

  • Blazor Hybrid nutzt BlazorWebView aus dem Paket Microsoft.AspNetCore.Components.WebView.Maui und läuft komplett ohne Netzwerkverbindung. Jede Razor-Komponente wird lokal im nativen WebView-Prozess gerendert.
  • Der grösste Vorteil ist Code-Sharing. Dieselben .razor-Komponenten können in einer Razor Class Library (RCL) liegen und von einer Blazor-Web-App, einer MAUI-App und einer WPF-App gleichzeitig verwendet werden.
  • Native APIs wie GPS, Kamera oder SecureStorage stehen Blazor-Komponenten über Dependency Injection im MauiProgram zur Verfügung. Kein JavaScript-Interop nötig.
  • Die Startzeit einer Blazor-Hybrid-App liegt auf modernen Geräten in .NET 10 mit NativeAOT unter 900 ms, aber ohne AOT ist sie deutlich langsamer als bei reinen XAML-Apps.
  • Für Formular-lastige B2B-Apps und interne Tools ist Blazor Hybrid oft die schnellste Option. Für performance-kritische Listen bleiben CollectionView und XAML überlegen.
  • Ab .NET 8 stabil, in .NET 10 mit produktionsreifem Hot Reload und deutlich verbesserter Startzeit dank NativeAOT.

Was ist .NET MAUI Blazor Hybrid?

Blazor Hybrid ist ein Rendering-Modus, bei dem Razor-Komponenten in einem eingebetteten WebView innerhalb einer nativen .NET-Anwendung ausgeführt werden, im Fall von MAUI in BlazorWebView. Es gibt keinen Blazor-Server, keinen HTTP-Roundtrip und keinen WebAssembly-Download. Der C#-Code läuft im .NET-Prozess der MAUI-App, während das gerenderte HTML/CSS im plattformabhängigen WebView angezeigt wird: WKWebView auf iOS, das Android System WebView auf Android, WebView2 auf Windows und WebKit auf Mac Catalyst.

Der entscheidende Punkt: Die Kommunikation zwischen Razor-Komponenten und nativem Code läuft direkt über einen Interop-Kanal, nicht über HTTP oder eine JavaScript-Bridge. Dadurch kannst du @inject IGeolocation in eine Razor-Komponente schreiben und bekommst dieselbe MAUI-Essentials-Schnittstelle wie in einer XAML-Seite. Microsoft beschreibt das in der offiziellen Blazor-Hybrid-Tutorial-Dokumentation mit dem Slogan "web UI in a .NET native app", und technisch gesehen ist es genau das.

Wann Blazor Hybrid statt XAML sinnvoll ist

Ehrlich gesagt hängt die Entscheidung zwischen XAML und Blazor Hybrid weniger von der Performance ab als von deinem Team und deiner bestehenden Code-Basis. In meiner Beratungspraxis stelle ich vier Fragen, bevor ich eine Empfehlung ausspreche: Habt ihr bereits Blazor-Komponenten im Einsatz? Ist das Team stärker in Web- oder in XAML-Entwicklung? Braucht ihr eine parallele Web- und eine mobile Version? Sind die Bildschirme formular- oder listen-lastig?

AspektXAML (klassisch)Blazor Hybrid
Ideale Team-KompetenzC#/XAML, WPF/UWP-ErfahrungWeb-Entwickler (HTML/CSS/Razor)
Code-Sharing mit Web-AppNur ViewModels/ServicesUI-Komponenten komplett (RCL)
Startzeit (kalt, iOS)~ 500 ms~ 900 ms (AOT), ~ 1400 ms (JIT)
Grosse Listen (10k Zeilen)CollectionView virtualisiert nativVirtualize-Komponente, aber DOM-basiert langsamer
Formulare & WizardsAufwendig mit ValidationSehr komfortabel mit EditForm
Native Look & FeelAutomatisch (Handler)CSS-Design nötig
Hot ReloadXAML + C#Razor + CSS + C#

Meine Faustregel: Für ein internes Verwaltungstool mit vielen Formularen, das auch als Web-App laufen soll, ist Blazor Hybrid schneller entwickelt und einfacher zu warten. Für eine Consumer-App mit intensiver Nutzung von CollectionView, komplexen Gesten und plattformspezifischem Look bleibt XAML die bessere Wahl. Du kannst auch gemischt arbeiten: einige Seiten in XAML, einzelne komplexe Formulare in einem BlazorWebView. Mehr dazu im Abschnitt über MAUI-Handler und Custom Controls.

Blazor-Hybrid-Projekt in .NET 10 aufsetzen

Ab .NET 9 liefert das MAUI-Workload eine dedizierte Projekt-Vorlage maui-blazor. In .NET 10 (November 2025 LTS) heisst der Befehl weiterhin so, aber die generierte MauiProgram.cs ist deutlich schlanker geworden. Voraussetzungen: aktuelles .NET-10-SDK und das installierte MAUI-Workload.

# SDK und Workload pruefen
dotnet --version    # sollte 10.0.x zurueckgeben
dotnet workload install maui

# Neues Projekt erstellen
dotnet new maui-blazor -n KontosApp -o ./KontosApp
cd KontosApp

# iOS und Android einzeln bauen
dotnet build -f net10.0-android
dotnet build -f net10.0-ios

Nach dem Anlegen findest du die entscheidenden Dateien: MainPage.xaml mit einem einzelnen <BlazorWebView>-Element, Components/Routes.razor mit dem Blazor-Router und wwwroot/index.html als HTML-Host. Die zentrale Registrierung in MauiProgram.cs sieht so aus:

using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Extensions.Logging;

namespace KontosApp;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        // Blazor WebView aktivieren
        builder.Services.AddMauiBlazorWebView();

    #if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
        builder.Logging.AddDebug();
    #endif

        // Eigene Services fuer Razor-Komponenten
        builder.Services.AddSingleton<IAccountRepository, AccountRepository>();
        builder.Services.AddScoped<IUserSession, UserSession>();

        return builder.Build();
    }
}

AddBlazorWebViewDeveloperTools() aktiviert im Debug-Build die WebView-Konsole und Remote-Inspektion: auf Android über chrome://inspect, auf iOS über den Safari-Web-Inspektor. Diese Tools sind für die Fehlersuche unverzichtbar und werden im Release-Build automatisch entfernt.

Komponenten zwischen Web und MAUI teilen (RCL)

Der grösste strategische Vorteil von Blazor Hybrid ist echtes UI-Sharing. Erstelle eine Razor Class Library und lege alle wiederverwendbaren Komponenten dort ab. Deine MAUI-App und eine parallele Blazor-Web-App referenzieren dann dasselbe Projekt.

dotnet new razorclasslib -n Kontos.Shared -o ./Kontos.Shared

# In der MAUI-App referenzieren
dotnet add ./KontosApp reference ./Kontos.Shared

# In einer Blazor Web App referenzieren
dotnet add ./Kontos.Web reference ./Kontos.Shared

Damit Routen aus der RCL in der MAUI-App gefunden werden, muss der Router die Assembly kennen. In Components/Routes.razor ergänzen:

<Router AppAssembly="@typeof(MauiProgram).Assembly"
        AdditionalAssemblies="new[] { typeof(Kontos.Shared._Imports).Assembly }">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <p>Diese Seite existiert nicht.</p>
    </NotFound>
</Router>

Native Gerätefunktionen aus Razor-Komponenten aufrufen

Weil Razor-Komponenten im selben Prozess wie die MAUI-App laufen, ist der Zugriff auf native APIs so einfach wie @inject. Registriere die MAUI-Essentials-Services im DI-Container und injiziere sie direkt.

// MauiProgram.cs
builder.Services.AddSingleton(_ => Geolocation.Default);
builder.Services.AddSingleton(_ => SecureStorage.Default);
builder.Services.AddSingleton(_ => MediaPicker.Default);

// LocationCard.razor
@inject IGeolocation Geolocation

<button class="btn btn-primary" @onclick="ReadLocationAsync">Position ermitteln</button>

@if (_location is not null)
{
    <p>Breitengrad: @_location.Latitude, Laengengrad: @_location.Longitude</p>
}

@code {
    private Location? _location;

    private async Task ReadLocationAsync()
    {
        try
        {
            _location = await Geolocation.GetLocationAsync(new GeolocationRequest
            {
                DesiredAccuracy = GeolocationAccuracy.Medium,
                Timeout = TimeSpan.FromSeconds(10)
            });
        }
        catch (FeatureNotSupportedException)
        {
            // Fallback fuer Web-Rendering
        }
    }
}

Wenn dieselbe Komponente auch in einer Web-App laufen soll, führst du eine Interface-Abstraktion (ILocationService) ein und registrierst pro Plattform eine passende Implementierung. Für die Web-Version dient dann die HTML5 Geolocation-API aus MDN als Grundlage, für die MAUI-Version IGeolocation. Zur sicheren Ablage von Auth-Tokens gilt weiterhin, was ich im Sicherheitsleitfaden zu SecureStorage beschrieben habe. Blazor Hybrid ändert daran nichts.

JavaScript-Interop, wwwroot und statische Assets

Manche Web-Bibliotheken (Chart.js, Signature-Pad, Fabric.js) haben kein direktes .NET-Pendant. Für diese Fälle nutzt du IJSRuntime genauso wie in Blazor Server oder WebAssembly. Assets landen unter wwwroot/ der MAUI-App und werden automatisch in den WebView-Host integriert.

<!-- wwwroot/index.html -->
<script src="js/chart.min.js"></script>
<script src="js/interop.js"></script>

// wwwroot/js/interop.js
window.chartInterop = {
    renderLine: (canvasId, labels, values) => {
        const ctx = document.getElementById(canvasId).getContext('2d');
        new Chart(ctx, {
            type: 'line',
            data: { labels, datasets: [{ label: 'Umsatz', data: values }] }
        });
    }
};

// LineChart.razor
@inject IJSRuntime Js

<canvas id="salesChart" width="400" height="200"></canvas>

@code {
    [Parameter] public IReadOnlyList<string> Labels { get; set; } = [];
    [Parameter] public IReadOnlyList<double> Values { get; set; } = [];

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await Js.InvokeVoidAsync("chartInterop.renderLine", "salesChart", Labels, Values);
        }
    }
}

Offline-Fähigkeit und Zustandsverwaltung

Blazor Hybrid ist von Natur aus offline-fähig, weil das gesamte C# lokal auf dem Gerät läuft. Für persistente Daten setzt du auf dieselben Muster wie in reiner MAUI-Entwicklung. SQLite-net-pcl bleibt der Standard für lokale Datenbanken. Ich empfehle, den DbContext als Scoped-Service zu registrieren und in Razor-Komponenten via @inject zu konsumieren.

// MauiProgram.cs
var dbPath = Path.Combine(FileSystem.AppDataDirectory, "kontos.db3");
builder.Services.AddDbContextFactory<KontosDbContext>(o => o.UseSqlite($"Filename={dbPath}"));

// AccountList.razor
@inject IDbContextFactory<KontosDbContext> DbFactory

@code {
    private List<Account> _accounts = [];

    protected override async Task OnInitializedAsync()
    {
        await using var db = await DbFactory.CreateDbContextAsync();
        _accounts = await db.Accounts.OrderBy(a => a.Name).ToListAsync();
    }
}

Für komplexere Sync-Szenarien mit einem Backend gelten die gleichen Regeln wie in klassischen MAUI-Apps. Falls du eine Konfliktlösung mit Last-Write-Wins oder CRDTs baust, passt mein Leitfaden zu Offline-First mit SQLite und Konfliktlösung nahtlos daneben. State-Management innerhalb der UI löst du entweder über einen einfachen Singleton-Service (State-Container-Pattern) oder, wenn du bereits MVVM einsetzt, über das CommunityToolkit.Mvvm, das ebenso in Razor-Komponenten funktioniert.

Performance und Startzeit optimieren

So, jetzt zum grössten Kritikpunkt an Blazor Hybrid: der Startzeit. Der WebView muss initialisiert, index.html geladen und das Blazor-Rendering-System hochgefahren werden. Auf einem iPhone 14 mit .NET 10 und aktiviertem PublishAot messe ich einen kalten Start von rund 900 ms, ohne AOT sind es eher 1400 ms. Zum Vergleich: eine reine XAML-Seite liegt bei etwa 500 ms.

Die wichtigsten Hebel für Startzeit:

  1. NativeAOT aktivieren. In der .csproj setzt du <PublishAot>true</PublishAot> für die iOS- und Android-Targets. Das verkürzt die Startzeit um 20 bis 40 %. Reflektion in Razor-Komponenten braucht dann aber Trim-Analyzer-Hinweise.
  2. Startseite minimal halten. Verzichte auf OnInitializedAsync-Datenzugriffe in der ersten Route. Zeige stattdessen einen Skeleton-Screen und lade Daten in OnAfterRenderAsync(firstRender: true).
  3. Assets komprimieren. index.html, app.css und alle Bilder in wwwroot/ sollten minifiziert sein, Bilder am besten als WebP eingebettet.
  4. Virtualisierung nutzen. Für Listen ab 100 Einträgen ist <Virtualize> Pflicht. Ohne Virtualisierung erzeugst du DOM-Elemente für jedes Item, und das killt die Scroll-Performance.

Für tiefere Optimierungen (GC-Pausen, XAML-Alternativen, CollectionView im Vergleich zu Virtualize) habe ich eine ausführliche Performance-Analyse für .NET MAUI geschrieben. Die dortigen Startzeit-Techniken lassen sich auf Blazor Hybrid direkt anwenden.

Speicherverbrauch messen

Der WebView selbst braucht etwa 40 bis 60 MB RAM. Dazu kommt der .NET-Heap deiner Komponenten. In einer typischen B2B-App mit 20 bis 30 gleichzeitig gerenderten Komponenten liegt der Gesamtverbrauch bei 120 bis 160 MB. Vertretbar für Business-Apps, spürbar für Konsumenten-Apps auf älteren Geräten. Miss mit dotnet-counters monitor -n KontosApp auf Windows/macOS und mit Xcode Instruments auf iOS.

Häufige Fehler beim BlazorWebView und wie man sie debuggt

In Praxis-Projekten sehe ich immer wieder die gleichen fünf Probleme. Hier die schnelle Referenz.

Weisse Seite nach dem Start

Ursache in 80 % der Fälle: ein JavaScript-Fehler in wwwroot/index.html, den du in der C#-Konsole nicht siehst. Aktiviere AddBlazorWebViewDeveloperTools() und öffne die WebView-Konsole (Safari-Web-Inspektor auf iOS, chrome://inspect auf Android). Der zweite häufige Grund: Der Router findet keine Assembly, weil AdditionalAssemblies in Routes.razor fehlt.

Native Dienste sind null

Das passiert, wenn du @inject IGeolocation Geolocation schreibst, aber vergisst, den Dienst im MauiProgram zu registrieren. Blazor wirft in diesem Fall eine InvalidOperationException. Merke: MAUI-Essentials-Instanzen sind Singletons und müssen explizit über builder.Services.AddSingleton(_ => Geolocation.Default) registriert werden.

Hot Reload funktioniert nicht

Ab .NET 10 ist Razor-Hot-Reload in MAUI stabil, aber CSS-Änderungen greifen nur, wenn du <link href="app.css?ts=1"> nicht mit versioniertem Query-String cachest. Klare Regel: keine Cache-Busting-Parameter in Debug-Builds.

iOS: WKWebView blockiert lokale HTTP-Requests

Für Development-Server auf localhost brauchst du den NSAppTransportSecurity-Eintrag in Platforms/iOS/Info.plist mit NSAllowsLocalNetworking. Sonst schlagen alle Fetch-Aufrufe im WebView still fehl.

Android: Content-Security-Policy verhindert Interop

Wenn du selbst ein CSP-Meta-Tag in index.html setzt, muss script-src immer 'unsafe-eval' und 'self' enthalten. Das ist eine Anforderung von Blazor selbst, nicht von MAUI. Ich hab diesen Bug in einem Projekt einmal drei Stunden lang gejagt, bevor mir die restriktive CSP als Übeltäter aufgefallen ist.

Häufig gestellte Fragen

Was ist der Unterschied zwischen .NET MAUI Blazor Hybrid und Blazor WebAssembly?

Blazor Hybrid führt Razor-Komponenten in einem eingebetteten WebView aus, während der C#-Code im nativen .NET-Prozess der App läuft. Blazor WebAssembly lädt das .NET-Runtime über WASM in den Browser. Hybrid hat keinen WASM-Download, dafür ist die App-Grösse durch das MAUI-Runtime höher (rund 40 MB APK).

Kann ich Blazor Hybrid Apps in den App Store veröffentlichen?

Ja. Da die App als reguläre .NET MAUI Anwendung kompiliert wird, gelten dieselben Regeln wie für jede andere MAUI-App. Apple hat WebView-basierte Apps in der Vergangenheit teilweise abgelehnt, wenn sie nur eine Website darstellen. Blazor Hybrid gilt aber als native App mit lokal ausgeführtem Code und wird akzeptiert.

Läuft Blazor Hybrid komplett offline?

Ja. Weder der Blazor-Rendering-Prozess noch die Komponenten benötigen eine Netzwerkverbindung. Alle Assets liegen im App-Bundle, das C# läuft lokal. Nur wenn du bewusst HTTP-Requests an ein Backend machst, wird das Netzwerk gebraucht.

Sollte ich für ein Neu-Projekt XAML oder Blazor Hybrid wählen?

Wenn dein Team primär aus Web-Entwicklern besteht und du eine parallele Web-Version brauchst, wähle Blazor Hybrid. Für performance-kritische Consumer-Apps mit langen Listen, komplexen Gesten und nativem Look-and-Feel bleibt XAML die bessere Wahl. Hybride Ansätze mit gemischten Seitentypen sind ebenfalls möglich und in produktiven Apps üblich.

Unterstützt Blazor Hybrid Hot Reload für Razor-Komponenten?

Ja, ab .NET 8 und stabil ab .NET 10. Änderungen an .razor-Dateien und CSS werden im laufenden Debug-Build ohne Neustart übernommen. Änderungen an Service-Registrierungen in MauiProgram.cs erfordern weiterhin einen App-Neustart.

Editorial Team
Über den Autor Editorial Team

Our team of expert writers and editors.