Course contentsShow
← C#
Lesson 1342 of 1,90812. Modern Frontend with Razor and BlazorFree lesson

Blazor JavaScript Isolation

Implement modern JS modules that load asynchronously with specific components.

In this lesson, you will learn how to encapsulate JavaScript functionality directly within your Blazor components using JS Modules to prevent global scope pollution.

The Problem with Global JS

In standard Blazor JS Interop, you typically place scripts in wwwroot/index.html or _Host.cshtml. This makes them globally accessible, often leading to naming collisions, "spaghetti code," and performance hits since every page loads every script.

Enter JavaScript Isolation

Blazor provides a cleaner approach by allowing you to define a JavaScript file that mirrors your Razor component’s location (e.g., MyComponent.razor and MyComponent.razor.js). These files act as ES6 Modules, meaning their functions are not attached to the global window object. They are loaded asynchronously only when the specific component is rendered.

Implementation

To use this, you inject the IJSRuntime service and use InvokeAsync to load the module:

@inject IJSRuntime JS

@code {
    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // Load the module associated with this component
            module = await JS.InvokeAsync<IJSObjectReference>("import", "./MyComponent.razor.js");
        }
    }

    private async Task TriggerAlert()
    {
        if (module is not null)
        {
            await module.InvokeVoidAsync("showGreeting", "Hello from an isolated module!");
        }
    }
}

In your MyComponent.razor.js file, you simply export your functions:

export function showGreeting(message) {
    alert(message);
}

Why this is better

  1. Performance: The script is only fetched from the network if the component is actually used.
  2. Encapsulation: Your JS functions are scoped to the module. You don't have to worry about another script overriding your function names.
  3. Lifecycle Management: By capturing the IJSObjectReference, you can easily dispose of the module when the component is destroyed, preventing memory leaks.

Key Takeaway: Blazor JavaScript Isolation allows you to bundle logic and behavior into component-specific modules, ensuring your application remains modular, performant, and free from global scope conflicts.