Joe Enos
Joe Enos

Reputation: 40413

Set base href on publish in Blazor WebAssembly project

The index.html file in Blazor WebAsssembly has a value of "/" for href. My understanding is that I would just change this if I need to host my app in a subdirectory of a website.

I'm working on an ASP.NET hosted Blazor WebAppsembly app.

What if I have multiple environments and I want to publish this with different bases - for example http://mysite/someapptest/ and http://mysite/someappstage/.

Since it's static HTML I don't think I can get to it programmatically at runtime. Is there any way to do that at build time without writing some kind of custom handler to swap out a placeholder or something?

For example, Angular has ng build --base-href /someapptest/

Anything similar for Blazor?

Upvotes: 3

Views: 3545

Answers (2)

Joe Enos
Joe Enos

Reputation: 40413

This blog entry seems to solve the issue, with the following in the head:

<base />
<script>
    // https://blog.elmah.io/how-to-fix-blazor-wasm-base-path-problems/
    var path = window.location.pathname.split('/');
    var base = document.getElementsByTagName('base')[0];
    if (window.location.host.includes('localhost')) {
        base.setAttribute('href', '/');
    } else if (path.length > 2) {
        base.setAttribute('href', '/' + path[1] + '/');
    } else if (path[path.length - 1].length != 0) {
        window.location.replace(window.location.origin + window.location.pathname + '/' + window.location.search);
    }
</script>

Upvotes: 3

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30167

There are two settings that you use:

<Base..>

The settings depend on your Css setup.

    <base href="/red/" />
    <link href="/red/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="/red/css/app.css" rel="stylesheet" />
    <link href="/red/Hydra.Red.styles.css" rel="stylesheet" />

<StaticWebAssetBasePath..>

Set in the WebAssembly Proj file. This sets the path that the WASM files can be accessed.

    <StaticWebAssetBasePath>red</StaticWebAssetBasePath>

The main problem you face is Page Refreshes. What happens when a user hits F5 on say /Red/FetchData. You need to make sure the server site knows which SPA launch page to hit, and the SPA router needs to know the route /Red/FetchData, not just FetchData which may be the route internally in the project.

You end up with multiple End Points in your server config:

app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/red"), app1 =>
{
    app1.UseBlazorFrameworkFiles("/red");
    app1.UseRouting();
    app1.UseEndpoints(endpoints =>
    {
      endpoints.MapFallbackToPage("/red/{*path:nonfile}", "/_Red");
    });

});

I wrote a proof of concept article on the subject a while ago on Code Project. It's a bit dated now - https://www.codeproject.com/Articles/5287009/Blazor-Hydra-Hosting-Multiple-Blazor-SPAs-on-a-sin. There's an associated Repo here: https://github.com/ShaunCurtis/Hydra

Upvotes: 3

Related Questions