Blazor include javascript library in specific component

Viewed 164

My Blazor server side app has several js / css libraries included in the _Layout.cshtml file. However, in one of my components I want to leverage an additional set of js / css libraries to add functionality for that specific component-- I don't want these libraries to get loaded globally.

Is there a way to do this that is native to Blazor? I've seen many posts that use a third-party library or some sort of hack to accomplish this (for example https://github.com/mishelshaji/DynamicJavaScriptInBlazor), but it seems like something that ought to be supported natively.

1 Answers

Using the lazy loading feature of IJSRuntime you can dynamically load JavaScript with your component.

In this component I lazy load a script file within a Razor Class Library.

Relevant sections from a code behind approach component:

public partial class Dialog : ComponentBase, IAsyncDisposable
{
    private readonly Lazy<Task<IJSObjectReference>> moduleTask;
    private DotNetObjectReference<Dialog> dotNetObjectReference;
    ...

    public Dialog()
    {
        moduleTask = new(() => jsRuntime!.InvokeAsync<IJSObjectReference>(
            identifier: "import",
            args: "./_content/BlazorDialogs/dialogJsInterop.js")
        .AsTask());

        dotNetObjectReference = DotNetObjectReference.Create(this);
    }

    [Inject]
    private IJSRuntime jsRuntime { get; set; }
...

    public async ValueTask ShowDialogAsync()
    {
        var module = await moduleTask.Value;
        await module.InvokeVoidAsync(identifier: "showDialog", dialogElement, dotNetObjectReference);
        ...
    }

    public async ValueTask CloseDialogAsync()
    {
        var module = await moduleTask.Value;
        await module.InvokeVoidAsync(identifier: "closeDialog", dialogElement);
        ...
    }

    [JSInvokable]
    public void OnDialogClosed()
    {
...
    }

    public async ValueTask DisposeAsync()
    {
        if (moduleTask.IsValueCreated)
        {
            var module = await moduleTask.Value;
            await module.DisposeAsync();
        }
    }
}

Note: OnDialogClosed is called from the JavaScript.

Repo

Related