Blazouter.WebAssembly
1.0.14
Prefix Reserved
dotnet add package Blazouter.WebAssembly --version 1.0.14
NuGet\Install-Package Blazouter.WebAssembly -Version 1.0.14
<PackageReference Include="Blazouter.WebAssembly" Version="1.0.14" />
<PackageVersion Include="Blazouter.WebAssembly" Version="1.0.14" />
<PackageReference Include="Blazouter.WebAssembly" />
paket add Blazouter.WebAssembly --version 1.0.14
#r "nuget: Blazouter.WebAssembly, 1.0.14"
#:package Blazouter.WebAssembly@1.0.14
#addin nuget:?package=Blazouter.WebAssembly&version=1.0.14
#tool nuget:?package=Blazouter.WebAssembly&version=1.0.14
Blazouter.WebAssembly
WebAssembly-specific extensions for Blazouter - the React Router-like routing library for Blazor applications. This package provides optimized components and extensions for Blazor WebAssembly applications.
Features
- ✅ All core Blazouter features
- ✅ Browser-specific enhancements
- ✅ Blazor WebAssembly integration
- ✅ Client-side routing optimizations
- ✅ Optimized bundle size for WASM
Installation
dotnet add package Blazouter
dotnet add package Blazouter.WebAssembly
Note: This package requires the core Blazouter package.
Quick Start
1. Configure Services
// Program.cs
using Blazouter.Extensions;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddBlazouter(); // Add Blazouter services
await builder.Build().RunAsync();
2. Define Routes in App.razor
@using Blazouter.Models
@using Blazouter.Components
<Router Routes="@_routes" DefaultLayout="typeof(Layout.MainLayout)">
<NotFound>
<h1>404 - Page Not Found</h1>
</NotFound>
</Router>
@code {
private List<RouteConfig> _routes = new()
{
new RouteConfig
{
Path = "/",
Component = typeof(Pages.Home),
Title = "Home",
Transition = RouteTransition.Fade
},
new RouteConfig
{
Path = "/about",
Component = typeof(Pages.About),
Title = "About",
Transition = RouteTransition.Slide
}
};
}
3. Include CSS
Add to your index.html:
<link rel="stylesheet" href="_content/Blazouter/blazouter[.min].css" />
WebAssembly-Specific Features
Optimized for Client-Side
The WebAssembly package is specifically optimized for:
- Reduced bundle size
- Browser-based navigation
- Client-side route matching
- Local storage integration possibilities
Router Component
The standard Router component works seamlessly in WebAssembly mode with:
- SPA-style navigation
- Browser history integration
- Fast client-side route resolution
Layouts
Configure a default layout for all routes and override per route:
<Router Routes="@_routes" DefaultLayout="typeof(Layout.MainLayout)">
<NotFound><h1>404</h1></NotFound>
</Router>
@code {
private List<RouteConfig> _routes = new()
{
// Uses DefaultLayout (MainLayout)
new RouteConfig
{
Path = "/",
Component = typeof(Pages.Home)
},
// Override with different layout
new RouteConfig
{
Path = "/account",
Component = typeof(Pages.Account),
Layout = typeof(Layout.AccountLayout)
},
// No layout for fullscreen pages
new RouteConfig
{
Path = "/presentation",
Component = typeof(Pages.Presentation),
Layout = null
}
};
}
Lazy Loading for Better Performance
In WebAssembly, lazy loading is crucial for reducing initial load time.
ComponentLoader
Load individual components on-demand:
new RouteConfig
{
Path = "/reports",
ComponentLoader = async () =>
{
// Simulate dynamic loading
await Task.Delay(100);
return typeof(ReportsPage);
},
Title = "Reports"
}
WASM RCL Assembly Lazy Loading
Load entire Razor Class Library (RCL) assemblies on demand using OnNavigateAsync and AdditionalAssemblies. This is ideal for large applications where separate modules are packaged as RCL projects:
@using System.Reflection
@using Blazouter.Models
@using Blazouter.Components
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@inject LazyAssemblyLoader AssemblyLoader
<Router Routes="@_routes"
DefaultLayout="typeof(MainLayout)"
OnNavigateAsync="@OnNavigateAsync"
AdditionalAssemblies="@_lazyLoadedAssemblies">
<Loading>
<p>Loading module...</p>
</Loading>
<NotFound>
<h1>404 - Page Not Found</h1>
</NotFound>
</Router>
@code {
private readonly List<Assembly> _lazyLoadedAssemblies = [];
private async Task OnNavigateAsync(BlazouterNavigationContext context)
{
if (context.Path.StartsWith("/support", StringComparison.OrdinalIgnoreCase) ||
context.Path.StartsWith("/help", StringComparison.OrdinalIgnoreCase))
{
if (_lazyLoadedAssemblies.Count == 0)
{
var assemblies = await AssemblyLoader.LoadAssembliesAsync(
["MyModule.wasm"]);
_lazyLoadedAssemblies.AddRange(assemblies);
}
}
}
}
Configure the assemblies to lazy-load in your .csproj:
<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="MyModule.wasm" />
</ItemGroup>
Key parameters:
OnNavigateAsync: Callback invoked before each navigation. Use it to load assemblies based on the target path.AdditionalAssemblies: List of dynamically loaded assemblies whose[Route]attributes are scanned for route discovery.BlazouterNavigationContext: ProvidesPath(target URL) andCancellationTokenfor the callback.
Nested Routes
Use <RouterOutlet /> for nested routing within components:
new RouteConfig
{
Path = "/products",
Component = typeof(ProductLayout),
Children = new List<RouteConfig>
{
new RouteConfig
{
Path = "",
Component = typeof(ProductList),
Exact = true
},
new RouteConfig
{
Path = ":id",
Component = typeof(ProductDetail)
}
}
}
@using Blazouter.Components
<div class="product-layout">
<h1>Products</h1>
<RouterOutlet />
</div>
Note: <RouterOutlet /> is for nested routing within a component hierarchy, while Layout (via DefaultLayout or RouteConfig.Layout) wraps entire routes with a common layout structure like headers, footers, and navigation.
Navigation Links
@using Blazouter.Components
<nav class="menu">
<RouterLink Href="/" Exact="true" ActiveClass="active">
Home
</RouterLink>
<RouterLink Href="/products" ActiveClass="active">
Products
</RouterLink>
<RouterLink Href="/about" ActiveClass="active">
About
</RouterLink>
</nav>
Route Guards
Protect routes with authentication logic:
new RouteConfig
{
Path = "/admin",
Component = typeof(AdminDashboard),
Guards = new List<Type> { typeof(AuthGuard) }
}
public class AuthGuard : IRouteGuard
{
private readonly ILocalStorageService _localStorage;
public AuthGuard(ILocalStorageService localStorage)
{
_localStorage = localStorage;
}
public async Task<bool> CanActivateAsync(RouteMatch match)
{
var token = await _localStorage.GetItemAsync<string>("auth_token");
return !string.IsNullOrEmpty(token);
}
public Task<string?> GetRedirectPathAsync(RouteMatch match)
{
return Task.FromResult<string?>("/login");
}
}
Programmatic Navigation
@inject RouterNavigationService NavService
private void NavigateToProduct(int productId)
{
NavService.NavigateTo($"/products/{productId}");
}
private void GoBack()
{
NavService.NavigateTo(-1); // Browser back
}
Access Route Parameters
@inject RouterStateService RouterState
@code {
private string? _productId;
protected override void OnInitialized()
{
_productId = RouterState.GetParam("id");
var category = RouterState.GetQueryParam("category");
}
}
Route Transitions
Built-in CSS transitions optimized for smooth animations:
new RouteConfig
{
Path = "/",
Component = typeof(Home),
Transition = RouteTransition.Fade // Smooth fade transition
}
new RouteConfig
{
Path = "/products",
Component = typeof(Products),
Transition = RouteTransition.Slide // Slide from left
}
Available transitions:
Fade- Fade in animationScale- Scale in animationFlip- 3D card flip animationSlide- Slide from left animationPop- Bounce effect with elastic easingNone- No transition animation (instant)SlideUp- Slide from bottom animationRotate- Spinning entrance along Z-axisReveal- Mask opening from bottom to topSlideFade- Combined slide and fade effectBlur- Focus transition from blurred to sharpSwipe- Mobile-style swipe reveal from right to leftCurtain- Theatrical curtain opening from top to bottomSpotlight- Dramatic lighting effect with brightness and blurLift- Content lifts up with subtle scaling and shadow (iOS-style)
Performance Tips for WebAssembly
- Minimize route configuration in the initial load
- Use lazy loading extensively to reduce initial bundle size
- Use transitions sparingly on mobile for better performance
- Consider route-based code splitting for large applications
- Leverage route guards to prevent unnecessary component initialization
Target Frameworks
- .NET 6.0
- .NET 7.0
- .NET 8.0
- .NET 9.0
- .NET 10.0
Browser Support
Blazouter.WebAssembly supports all modern browsers that support WebAssembly:
- Safari (latest)
- Firefox (latest)
- Chrome/Edge (latest)
Example Application
See the sample application for a complete working example of Blazor WebAssembly with Blazouter.
Documentation
Migration Guide
Moving from standard Blazor WebAssembly routing to Blazouter:
Before (Standard Blazor)
@page "/products"
@page "/products/{Id:int}"
<h1>Product @Id</h1>
After (Blazouter)
// Route configuration
new RouteConfig
{
Path = "/products/:id",
Component = typeof(ProductDetail)
}
@inject RouterStateService RouterState
<h1>Product @_productId</h1>
@code {
private string? _productId;
protected override void OnInitialized()
{
_productId = RouterState.GetParam("id");
}
}
License
MIT License - see LICENSE for details.
Support
Made with ❤️ for the Blazor community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
See CHANGELOG.md: https://github.com/Taiizor/Blazouter/blob/develop/CHANGELOG.md