Reputation: 389
I am getting started with Blazor
server-side and I don't get the routing right. I don't understand the need for the base
tag in _host.cshtml
. If I still have to add the base
url in every Blazor component, for example: I want to have a base address of /app/
and the @page
directive for the example Counter
with a value of "/counter"
does not "compile" to "/app/counter"
. I have to set the @page
to "/app/counter"
which makes sense but that means that the base
Tag in _host.cshtml
is useless...
What am I getting wrong here?
Upvotes: 6
Views: 11532
Reputation: 516
In Blazor .NET 8 Interactive Server (no idea if this works in other rendering modes or .NET versions) you can do this with no configuration required. Then it works in development and wherever you deploy it...
In App.razor:
<base href="@BaseUrl" />
In the App razor code:
[CascadingParameter] private HttpContext HttpContext { get; set; }
private string BaseUrl => $"{HttpContext.Request.PathBase}/";
Upvotes: 4
Reputation: 41
I had the same problem because I needed to host multiple apps under one Nginx server.
Very important: you have to set the PathBase BEFORE any other configuration of the ApplicationBuilder in Startup.cs. To set the path dynamically it is read from the appsettings
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UsePathBase(Configuration.GetValue<string>("PATH_BASE") ?? "/");
...
}
appsettings.json
{
...
"PATH_BASE": "/mycustompath",
...
}
_Host.cshtml
<head>
<base href="~/" />
...
</head>
All links to navigation and resources must be relative, e.g.
<script src="_framework/blazor.server.js"></script>
or
<script src="_framework/blazor.server.js"></script>
Upvotes: 4
Reputation: 6452
In case of Blazor WebAssembly you have to deal with index.html
only.
When you publish your site to some subfolder in production (ex: yoursite.com/couch/web
) put this code instead of <base href="/">
inside head
tag and replace "/couch/web/"
with your own sub:
<script type="text/javascript">
var appBase = document.createElement('base');
appBase.href = "/couch/web/";
if (window.location.href.indexOf("localhost") > -1)
{
appBase.href = "/";
}
document.head.appendChild(appBase);
</script>
The result is <base href="/couch/web/">
being automatically generated in production and <base href="/">
when developing from localhost.
Later one can access this base href that was set via a read-only NavigationManager.BaseUri
.
Upvotes: 5
Reputation: 351
To get this working completely I had to combine Softlion fix
In the startup.cs file this is also required. It also needs to be the first line in the configure method, else bad things happen
app.UsePathBase("/app");
This is so that your relative links will also work. For example I had a link to a login page.
<a href="~/Login">Login</a>
-------------Edit extra information-------
I just found out blazer is really picky with casing. This happens both in IIS and visual studio
<base href="/app/" />
app.UsePathBase("/app");
is not the same as
<base href="/App/" />
app.UsePathBase("/App");
you have to get these to match up. Not only that you have to navigate to your Web application with the same casing as well.
I have made a github issue due to the urls not being the same and throwing issues in the javascript debugger
localhost:5001/App
https://github.com/dotnet/aspnetcore/issues/23107
Upvotes: 1
Reputation: 12595
The solution is there
app.UsePathBase("/app");
in Startup.Configure<base href="/app/">
below <head>
in _Host.cshtmlUpvotes: 0
Reputation: 25350
The <base href='' >
is a client side technology that specifies the base URL for all relative URLs in current document. Many SPA frameworks , e.g. Angular, will use this element.
I have to set the @page to "/app/counter"
Actually, you don't have to and should never do that. One of the most important advantages when using <base>
is that it allows us to create an app without letting the components know about the base url.
Assuming you've changed the base href
from '/' to '/app/', and also changed the other relative urls:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BlazorApp</title>
<base href="/app/" />
<link rel="stylesheet" href="/css/bootstrap/bootstrap.min.css" />
<link href="/css/site.css" rel="stylesheet" />
</head>
<body>
<app>
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>
<script src="/_framework/blazor.server.js"></script>
</body>
</html>
Don't forget to prepend the default Blazor
Hub url with a /app/
:
app.UseEndpoints(endpoints => { endpoints.MapBlazorHub("/app/_blazor"); endpoints.MapFallbackToPage("/_Host"); });
That's all. There's no need to change the routes from @page "/counter"
to @page "/app/counter"
at all.
Here's a demo that we don't change the @page
routes for components:
Upvotes: 10