Search code examples
macosblazorblazor-webassembly.net-8.0

System.Runtime.InteropServices.JavaScript is not supported on this platform


I'm running Net8.0 on a Macbook Intel with Sonoma 14.3

I'm trying to call a Javascript function from the WASM client in a Blazor project.

My code is a simple alert test:

NetToJsWasm.razor

@namespace SharedComponents.JSInteropSamples

@page "/nettojswasm"

@rendermode InteractiveWebAssembly

@using System.Runtime.InteropServices.JavaScript


<h3>This is a demo how to call JavaScript from .NET</h3>
<button @onclick="ShowMyAlert">Show Alert</button>

@code {
    protected async void ShowMyAlert()
    {
        ShowAlert("Hello from .NET");
    }
    protected override async Task OnInitializedAsync()
    {
        await JSHost.ImportAsync("nettojswasm", "NetToJSWasm.razor.js");
    }
}

NetToJsWasm.razor.js

export function showAlert(message) {
    return alert(message);
}

NetToJsWasm.razor.cs

namespace SharedComponents.JSInteropSamples;

using System.Runtime.InteropServices.JavaScript;

public partial class NetToJsWasm
{
    [JSImport("showAlert", "nettojswasm")]
    internal static partial string ShowAlert(string message);
}

When I execute, I get the error PlatformNotSupportedException

PlatformNotSupportedException: System.Runtime.InteropServices.JavaScript is not supported on this platform.
System.Runtime.InteropServices.JavaScript.JSHost.ImportAsync(string moduleName, string moduleUrl, CancellationToken cancellationToken)
MyBlog.Client.JSInteropSamples.NetToJsWasm.OnInitializedAsync() in NetToJsWasm.razor
+
        await JSHost.ImportAsync("nettojswasm", "NetToJSWasm.razor.js");
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
...

Only related topic is Blazor WASM - JavaScript not supported on Linux, but this is related to Linux/Ubuntu, and the workaround is not clear for me.


Solution

  • The problem was that this component is running in a project with prerender active. It's not enough to declare @rendermode InteractiveWebAssembly. I had to deactivate the prerender as @rendermode @(new InteractiveWebAssemblyRenderMode(prerender:false))

    This is the working NetToJsWasm.razorfile:

    @namespace SharedComponents.JSInteropSamples
    
    @page "/nettojswasm"
    
    @* @rendermode InteractiveWebAssembly *@
    @rendermode @(new InteractiveWebAssemblyRenderMode(prerender:false))
    
    @using System.Runtime.InteropServices.JavaScript
    
    
    <h3>This is a demo how to call JavaScript from .NET</h3>
    <button @onclick="ShowMyAlert">Show Alert</button>
    
    @code {
        protected async void ShowMyAlert()
        {
            ShowAlert("Hello from .NET");
        }
        protected override async Task OnInitializedAsync()
        {
            await JSHost.ImportAsync("nettojswasm", "../_content/SharedComponents/JSInteropSamples/NetToJsWasm.razor.js");
        }
    }
    

    BTW: I have declared the path to javascript code analysing the generated folder structure: ../_content/SharedComponents/JSInteropSamples/NetToJsWasm.razor.js. But I'm afraid is not correct. Do you know best way to declare the path without depending of current location?