Search code examples
blazorblazor-webassemblyblazor-client-sideasp.net-blazor

How to change the base URL of a blazor wasm app


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.


Solution

  • 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.