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