lolveley
lolveley

Reputation: 1719

How to dynamically change app base path in a hosted wasm app?

In a WASM hosted project, I would like to change the app base path dynamically: given an appSettings.json configuration file, I would like to store the value associated to a given key in a variable, and set the <base href="..."/> tag with the content of this variable.

Currently, I can't do this because in an HTML file I can't get the configurations parameter. So I see a few ways :

I searched on google and will continue, but if someone can give me advices on how to continue, it would be nice.

Upvotes: 2

Views: 1624

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30177

Add a JS file to the client app.

site.js


window.SetBaseHref = function (elementId, hRef) {
    var link = document.getElementById(elementId);
    if (link !== undefined) {
        link.href = hRef;
    }
    return true;
}

wwwroot/appsettings.json

{
  "Configuration": {
    "BaseHRef": "/blue"
  }
}

Reference it in index.html and create an id on <base>.

    <base href="~/" id="BlazorHRef" />

.......

    <script src="/site.js"></script>

Demo in the index page
@page "/"
@page "/red/"

<h1>Hello, world!</h1>

    Welcome to your new app.

<button type="button" @onclick="this.SetBaseHRef">SetHRef</button>

<SurveyPrompt Title="How is Blazor working for you?" />
@code {

    [Inject] private IJSRuntime _js { get; set; }

    private bool _isAltHRef;

    private string _altHRef => _isAltHRef ? "/" : "/red";

    public async Task SetBaseHRef()
    {
        await this.SetBaseHref("BlazorHRef", _altHRef);
        _isAltHRef = !_isAltHRef;
    }

    public ValueTask<bool> SetBaseHref(string elementId, string hRef)
      => _js.InvokeAsync<bool>("SetBaseHref", elementId, hRef);

}
Setting it at startup in App.razor
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

@code {
    [Inject] IConfiguration Configuration { get; set; }

    [Inject] private IJSRuntime _js { get; set; }

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        var baseHRef = Configuration.GetValue<string>("Configuration:BaseHRef");
        if (!string.IsNullOrEmpty(baseHRef)) await this.SetBaseHref("BlazorHRef", baseHRef);
    }

    public ValueTask<bool> SetBaseHref(string elementId, string hRef)
          => _js.InvokeAsync<bool>("SetBaseHref", elementId, hRef);

}

You can change out most things in the header in a similar way.

Upvotes: 2

Related Questions