Overview
- .NET can invoke JavaScript and vice-versa.
IJSRuntime
is automatically registered as a service by the Blazor framework.- Documentation:
OnAfterRenderAsync
method.
Prerendering
Invoking JavaScript
JavaScript Locations
In <body>
markup
Place the JavaScript inside the closing </body>
element of wwwroot/index.html
(Blazor WASM) or Pages/_Host.cshtml
(Blazor Server):
<body>
...
<script src="_framework/blazor.{server|webassembly}.js"></script>
<script>
<!-- JavaScript starts here: -->
window.jsMethod = (methodParameter) => {
...
};
</script>
</body>
From a JavaScript File
Place the JavaScript src
reference inside the closing </body>
element of wwwroot/index.html
(Blazor WASM) or Pages/_Host.cshtml
(Blazor Server):
<body>
<!-- ... -->
<script src="_framework/blazor.{server|webassembly}.js"></script>
<script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>
JavaScript Code-Behind
For a Blazor component SomeComponent
in Pages/SomeComponent.razor
, place the JavaScript code-behind for that component in Pages/SomeComponent.razor.js
:
Pages/SomeComponent.razor
<!-- ... -->
@code {
// ...
private IJSInProcessObjectReference? module;
protected override void OnAfterRenderAsync() {
module = await JS.InvokeAsync<IJSObjectReference>("import", "./Pages/SomeComponent.razor.js");
}
// ...
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
await module.DisposeAsync();
}
}
Pages/SomeComponent.razor.js
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
Injecting a Script Before/After Blazor Starts
JavaScript Isolation
See JavaScript isolation in JavaScript modules.
Invoking JavaScript from .NET
1. Add the script to wwwroot
or as an inline script with <script>
tag
2. Register the script in the hosting page (index.html
or host.cshtml
)
<script>
window.DoSomething = () => {
// do something here
}
</script>
3. Inject IJSRuntime
via DI
@code
{
[Inject]
public IJSRuntime JsRuntime { get; set; }
}
4. Call the script (invoke the JavaScript function) from .NET
protected async override Task OnAfterRenderAsync(bool firstRender)
{
// if expecting a value to be returned:
var result = await JsRuntime.InvokeAsync<object>("DoSomething", "");
// else...
_ = await JsRuntime.InvokeVoidAsync<object>("DoSomething", "");
}
InvokeAsync vs InvokeVoidAsync
Use InvokeVoidAsync
when .NET is not required to read the result of a JavaScript call, or the JavaScript function being called returns void
or undefined
.
JavaScript Interop Call Timeouts
By default, Blazor Server apps use a timeout of 60 seconds for interop calls.
Change the Global Timeout
Program.cs
builder.Services.AddServerSideBlazor(
options => options.JSInteropDefaultCallTimeout = TimeSpan.FromSeconds(30));
Change the Timeout per Call
// {ID} is the placeholder for the identifier of the JavaScript function to invoke:
var result = await JS.InvokeAsync<string>("{ID}", TimeSpan.FromSeconds(30), new[] { "Arg1" });
Catch JavaScript Exceptions
Wrap the interop call in a try/catch block and catch JSException
:
try
{
var result = await JS.InvokeAsync<string>("nonFunction");
}
catch (JSException e)
{
var errorMessage = $"Error Message: {e.Message}";
}
Render UI with JavaScript
See JavaScript Libraries that render UI.