So far, the Kladde has two faces: the web app from K2 with Razor components, and the app from the lessons before this one with XAML pages. Both show appointments, both know about booking, but their user interfaces have nothing in common. Whoever changes the booking view changes it twice. This lesson shows how one Razor component runs in both worlds: in the browser and in the app.
As a starting picture, we assume your solution looks like this. Adjust the names to your projects and pages:
| Project | Contents |
|---|---|
Kladde.Core |
the rules, including FreeSlots |
Kladde.Web |
the web app with the API GET /api/slots and POST /api/bookings from K2 |
Kladde.Web.Client |
the WebAssembly island with SlotPicker, ISlotSource and HttpSlotSource from lesson 2.5.10 |
Kladde.App.Logic |
the view models with CommunityToolkit.Mvvm and their interfaces, without MAUI, with Kladde.App.Logic.Tests |
Kladde.App |
the MAUI app: Shell, XAML pages for contacts and appointments, SQLite, an HttpClient for the API |
At the end of the lesson there is a new project, Kladde.Shared. It contains the booking view as a Razor component, and both
Kladde.Web and Kladde.App show the same component.
What Blazor Hybrid is
Microsoft describes Blazor Hybrid like this: the Razor components run natively on the device, in the app’s .NET process, and render to an
embedded WebView control. They don’t run in the browser, and WebAssembly isn’t involved. In .NET MAUI, the control is called
BlazorWebView. Because the code runs natively, the components can reach the device’s capabilities through the .NET platform.
A WebView is a piece of browser inside the app. Which one depends on the platform:
| Platform | WebView | Source of the engine |
|---|---|---|
| Windows | WebView2 | Microsoft Edge (Chromium) |
| Android | android.webkit.WebView |
Chromium, the version depends on the installed Android WebView |
| iOS and Mac Catalyst | WKWebView |
Safari WebKit |
From that follows what Microsoft states explicitly: the appearance of the components can differ between platforms, and you have to test it on each one. On Windows, the people who use your app also need the WebView2 runtime.
The three places where Razor components can run differ in what they’re allowed to do. The documentation on reusable components gives one example for each:
| Place | What works there |
|---|---|
| Blazor WebAssembly | synchronous JavaScript calls |
| Blazor Server | services that exist only on the server, such as an Entity Framework context |
BlazorWebView |
direct access to device features, such as location services |
Your shared components must not presuppose any of this. How they can still make use of the differences is explained further down.
When hybrid, when XAML
Both run in the same app, and you can mix them. You decide per screen. The following table is a trade-off, not a rule from Microsoft:
| Question | speaks for BlazorWebView |
speaks for XAML |
|---|---|---|
| Does the user interface already exist as a Razor component on the web? | yes: reuse the same component | no |
| Should it feel like a native control (system picker, gestures)? | no | yes |
| Is the screen at its core a form or a list that looks the same on the web? | yes | rarely needed |
| Must the appearance be exactly the same on all platforms? | rather yes, with a test on each platform | the controls adapt to the platform |
| Does the screen need a lot of device functionality (camera, sensors)? | possible through interfaces, more effort | closer to hand |
For the Kladde, the choice goes like this: contacts and today’s appointments stay XAML, because they use the device’s database and feel like an app. The booking view already exists on the web, and it’s a form. It becomes the hybrid page.