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

Interpreting Browser Browser API

Build wrappers for native browser APIs like Geolocation or Notification via JS Interop.

In this lesson, you’ll learn how to extend your Blazor application’s capabilities by creating C#-friendly wrappers around native browser APIs using JS Interop.

Bridging the Gap with Wrappers

While Blazor handles most of your UI logic, sometimes you need to reach outside the sandbox to interact with the browser directly—like accessing the user’s physical location or triggering system notifications. Because these are JavaScript-based APIs, we use JS Interop to build a C# "wrapper." This hides the complexity of JavaScript from your components, allowing you to treat native browser features like standard C# methods.

The Wrapper Pattern

Instead of injecting IJSRuntime directly into your components, it is best practice to create an abstraction service. This keeps your components clean and makes your code testable.

Consider a service for the Browser Geolocation API:

public class GeolocationService
{
    private readonly IJSRuntime _js;

    public GeolocationService(IJSRuntime js) => _js = js;

    public async Task<Location> GetCurrentPosition()
    {
        // Calling a custom JS function 'getCoords' defined in your project
        return await _js.InvokeAsync<Location>("getCoords");
    }
}

In your JavaScript file (utilizing Blazor JS Isolation), you define the implementation:

export function getCoords() {
    return new Promise((resolve) => {
        navigator.geolocation.getCurrentPosition(pos => {
            resolve({ lat: pos.coords.latitude, lon: pos.coords.longitude });
        });
    });
}

Why this matters

By creating these wrappers, you move the "interop noise" out of your Razor components. If you decide to swap the browser API logic later, or if you need to add error handling (like checking if the browser supports the API), you only change the service, not every component that uses it. You register this service in your Blazor DI Container, making it globally accessible as a clean, strongly-typed dependency.

Key Takeaway: Build dedicated service classes to wrap JS Interop calls, providing a clean, C#-native interface for your components to interact with the browser's native capabilities.