17

The generated template for a blazor wasm hosted app has its base URL starting at '/' ( ie, https://localhost:5001/ for local development or https://www.domain-name.xyz/ when deployed.) I need this base URL to be '/app' instead, ie, (https://localhost:5001/app) or (https://www.domain-name.xyz/app).

The documentation (here and here) says that I have to change the base URL in the <base /> tag in index.html:

<base href="/app/" />

and use the command line argument --pathbase when developing locally:

dotnet run --pathbase=/app

I did that and changed nothing else to the template. This however does not work for me. I just get a 404 not found for all the files of the app.

This issue here says that I also need to change where the Blazor files are exposed by passing '/app' to UseBlazorFrameworkFiles:

app.UseBlazorFrameworkFiles("/app")

This also does not solve my problem.

Can anyone provide a step by step guidance to how to achieve this and that is guaranteed to work.

Abdelhakim
  • 815
  • 1
  • 5
  • 19

1 Answers1

14

You're almost there. I'm not sure what you're doing with the root site so I've added a simple landing page with a link to the WASM SPA. Here's a full set on instructions.

  1. host.html - change base to <base href="/app/" />. This will make sure all the @Page directives in the SPA get prefixed with app. You need the trailing /.
  2. host.html - change the script reference to <script src="/app/_framework/blazor.webassembly.js"></script>. You'll get away with not changing it if you're hosting a single WASM SPA. Experiment.
  3. WASM Project file Add StaticWebAssetBasePath. This sets up the build with the correct path.
  <PropertyGroup>
    <StaticWebAssetBasePath>app</StaticWebAssetBasePath>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
  1. Update Startup in the Server project, adding a new middleware path for mywebsite/app
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseWebAssemblyDebugging();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();


    app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/app"), first =>
    {
        first.UseBlazorFrameworkFiles("/app");
        first.UseStaticFiles();

        first.UseRouting();
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("app/{*path:nonfile}", "app/index.html");
        });
    });

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        // endpoints.MapFallbackToFile("_index.cshtml");
        endpoints.MapFallbackToPage("/_Index");
    });
}

I've added a default landing page to the root site - _Index.cshtml

@page "/"
@model WebApplication2.Server.Pages._IndexModel
    <h3>Hello App</h3>
<div><a href="/app">App WASM SPA</a></div>
@{
}

Note FetchData won't work until you update the controller url

forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("/WeatherForecast");

You can also move the WASM wwwroot into the root and add the startup page at say _App.cshtml to launch the SPA.

For more information there's a Github site here by Javier Nelson and an article I wrote on how to host multiple SPAs on the same website here with a Github Repo.

MrC aka Shaun Curtis
  • 19,075
  • 3
  • 13
  • 31
  • 1
    Thank you for the detailed answer. It works like a charm when run locally with `dotnet run` command. But when dockerized, I see the requests twice: one with the correct path (`localhost/app/{ressourse}`) which results in a 200OK response, and one with the path `localhost/app/app/{ressource}` which results in a 404 response. Any chance you know why I'm having that? – Abdelhakim Mar 30 '21 at 19:24
  • Straight answer is no, I don't user Docker. Over to the community - I suspect it's in the proxy'ing. All my stuff goes up to Azure App Services. – MrC aka Shaun Curtis Mar 30 '21 at 20:09
  • 2
    I finally figured out why I was having more requests ( erroneous requests) than I should have. It is because my app is a PWA. When publishing the pwa app, dotnet generates a file called service-worker-assets.js that contains the list of all needed files to make the app work offline. Apparently, changing the base path of the app breaks this mechanism. I fixed that by removing the "app/" part (which is my base path) from the paths of all files in service-worker-assets.js (`sed -i 's/app\\\///g' wwwroot/app/service-worker-assets.js`). I might open an issue on that later. Thanks again. – Abdelhakim Apr 04 '21 at 22:13
  • 1
    In my case I also had to add `app.UseStaticFiles("/app");`. This resolved issues with Blazorise and potentially third-party libraries that add other static files to a wasm path. – DLeh Feb 11 '22 at 19:03