In part one of this series, I mentioned the IJSInterop Runtime can be used to call any JavaScript function from an Event Handler. Here is one example.

Here a button triggers DownloadLogo
@page "/download"
@inject IJSRuntime JS
<div>
<h5>Click the button to download our logo.</h5>
</div>
<div class="d-flex justify-content-center align-items-center">
<button class="btn btn-secondary" @onclick="DownloadLogo"><image src="/images/logo.jpg" class="img-fluid" style="height:100px;"></image></button>
</div>
The IJSRuntime must be injected in order to call a Javascript function.
DownloadLogo uses the IJSInteropRuntime to call a Javascript fuction triggerFileDownload
@code {
const String url = "https://schroederconsultingstore.blob.core.windows.net/logos/3db34f06-795d-4125-81fa-dc2aa89f4220.jpg";
async Task DownloadLogo()
{
string[] arr = url.Split('/');
var fileName = arr[arr.Length - 1];
var fileURL = url;
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
}
}
In this case, the JavaScript function is in the script section of the body.
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
http://_framework/blazor.server.js
http://~/js/download.js
</body>
The JavaScript function must be scoped to the global window variable. This function creates an anchor element, adds it to the page, clicks it, then removes it.
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
Then the file downloads with the specified file name.
In the next part of this series, I will explore JavaScript [JSImport]/[JSExport] interop.






