Subpath Hosting
Blazing.Mvvm supports hosting Blazor applications under a subpath such as https://example.com/myapp instead of the domain root.
Automatic base path detection
Since v3.1.0, Blazing.Mvvm automatically detects the base path from NavigationManager.BaseUri. In many cases, including YARP reverse proxy setups, you do not need to configure BasePath manually.
Automatic detection works well for:
- standard subpath hosting
- YARP reverse proxy scenarios
- multi-tenant setups with dynamic paths
- development and production environments without different MVVM configuration
Standard subpath hosting
1. Configure launchSettings.json
{
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "fu/bar",
"applicationUrl": "https://localhost:7037;http://localhost:5272",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
2. Configure middleware in Program.cs
app.UsePathBase("/fu/bar/");
app.UseRouting();
3. Set the base href dynamically
For legacy _Host.cshtml:
@{
var baseHref = HttpContext?.Request?.PathBase.HasValue == true
? HttpContext?.Request.PathBase.Value!.TrimEnd('/') + "/"
: "/";
}
<base href="@baseHref" />
For App.razor:
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string baseHref => HttpContext?.Request.PathBase.HasValue == true
? HttpContext.Request.PathBase.Value!.TrimEnd('/') + "/"
: "/";
}
4. Register Blazing.Mvvm normally
builder.Services.AddMvvm(options =>
{
options.HostingModelType = BlazorHostingModelType.Server;
options.ParameterResolutionMode = ParameterResolutionMode.ViewAndViewModel;
});
YARP support
Blazing.Mvvm also works when YARP sets PathBase on incoming requests.
Configure YARP routes
{
"ReverseProxy": {
"Routes": {
"blazor-route": {
"ClusterId": "blazor-cluster",
"Match": {
"Path": "/fu/bar/{**catch-all}"
},
"Transforms": [
{ "PathRemovePrefix": "/fu/bar" }
]
}
},
"Clusters": {
"blazor-cluster": {
"Destinations": {
"blazor-destination": {
"Address": "http://localhost:5005/"
}
}
}
}
}
}
Configure forwarded headers and optional prefix handling
app.UseForwardedHeaders();
app.Use((ctx, next) =>
{
if (ctx.Request.Headers.TryGetValue("X-Forwarded-Prefix", out StringValues prefix) &&
!StringValues.IsNullOrEmpty(prefix))
{
var p = prefix.ToString();
if (!string.IsNullOrEmpty(p))
{
ctx.Request.PathBase = p;
}
}
return next();
});
For development, you can also force a path base:
app.Use((ctx, next) =>
{
ctx.Request.PathBase = "/fu/bar";
return next();
});
Legacy explicit configuration
If you need to override automatic detection, BasePath still works:
builder.Services.AddMvvm(options =>
{
options.HostingModelType = BlazorHostingModelType.Server;
options.ParameterResolutionMode = ParameterResolutionMode.ViewAndViewModel;
options.BasePath = "/fu/bar/";
});
Resolution priority
Base path resolution follows this order:
- Explicit
BasePath - Dynamic detection from
NavigationManager.BaseUri
Working examples and further reading
- Blazing.SubpathHosting.Server sample
- Subpath hosting guidance
- ASP.NET Core path base middleware
- YARP documentation