Skip to content

Blazor WebAssembly Custom Elements Completely Broken in .NET 10 RC2 #64087

@MarkStega

Description

@MarkStega

Blazor WebAssembly Custom Elements Completely Broken in .NET 10 RC2

Summary

Blazor WebAssembly projects using Custom Elements fail to build/publish properly in .NET 10 RC2. The publish process appears to succeed but produces no usable output - no blazor.boot.json, no DLL files, and no working WebAssembly bundle.

cc: @guardrex

Environment

  • .NET SDK Version: 10.0.100-rc.2.25502.107
  • OS: Windows
  • Project Type: Blazor WebAssembly with Custom Elements
  • Package: Microsoft.AspNetCore.Components.CustomElements 10.0.0-rc.2.25502.107

Expected Behavior

When publishing a Blazor WebAssembly project with custom elements, the publish output should contain:

  1. blazor.boot.json manifest file
  2. All compiled .NET assemblies (.dll files) in wwwroot\_framework
  3. A working WebAssembly bundle that can be loaded in a browser

Actual Behavior

The publish process reports success but the output is incomplete and non-functional:

  1. blazor.boot.json is never generated
  2. No .dll files are copied to the output
  3. ❌ Only JavaScript loader files are present (dotnet.js, blazor.webassembly.js, etc.)
  4. ❌ Runtime fails with: [MONO] * Assertion at /__w/1/s/src/runtime/src/mono/mono/metadata/assembly.c:2718, condition '<disabled>' not met

Steps to Reproduce

1. Create Project

dotnet new blazorwasm -n CustomElementWASM -f net10.0
cd CustomElementWASM
dotnet add package Microsoft.AspNetCore.Components.CustomElements --version 10.0.0-rc.2.25502.107

2. Create Custom Element Component

BlazorMarkdigViewer.razor:

@namespace CustomElementWASM

<div>
    <h2>BlazorMarkdigViewer</h2>
    <p>Hello @Name</p>
</div>

@code {
    [Parameter]
    public string? Name { get; set; }
}

3. Register Custom Element

Program.cs:

using CustomElementWASM;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

// Dummy root components required to trigger boot.json generation
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

// Register custom element
builder.RootComponents.RegisterCustomElement<BlazorMarkdigViewer>("blazor-markdig-viewer");

await builder.Build().RunAsync();

App.razor:

@namespace CustomElementWASM
<div></div>

_Imports.razor:

@using CustomElementWASM
@using Microsoft.AspNetCore.Components.Web

4. Publish

dotnet publish -c Release

5. Verify Output

# Check for blazor.boot.json
Test-Path "bin\Release\net10.0\browser-wasm\publish\wwwroot\_framework\blazor.boot.json"
# Result: False

# Check for DLL files
Get-ChildItem "bin\Release\net10.0\browser-wasm\publish\wwwroot\_framework" -Filter "*.dll"
# Result: No items found

Additional Issues Encountered

Issue 1: Artifacts Path Conflicts

When a parent Directory.Build.props sets <ArtifactsPath>, it causes:

  • Duplicate attribute errors (CS0579) due to generated files in multiple locations
  • Publish fails completely with cryptic errors

Workaround: Create local Directory.Build.props in project folder:

<Project>
  <!-- Empty file to block parent Directory.Build.props -->
</Project>

And add to .csproj:

<PropertyGroup>
  <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  <OutDir>bin\$(Configuration)\$(TargetFramework)\</OutDir>
</PropertyGroup>

Issue 2: Missing dotnet.js (Non-Versioned)

blazor.webassembly.js imports ./dotnet.js but build generates dotnet.{hash}.js.

Workaround: MSBuild target to copy versioned file:

<Target Name="CreateDotnetJsSymlink" AfterTargets="Build;Publish">
  <PropertyGroup>
    <FrameworkPath Condition="'$(PublishDir)' != ''">$(PublishDir)wwwroot\_framework\</FrameworkPath>
    <FrameworkPath Condition="'$(PublishDir)' == ''">$(OutputPath)wwwroot\_framework\</FrameworkPath>
  </PropertyGroup>
  <ItemGroup>
    <DotnetVersionedFile Include="$(FrameworkPath)dotnet.*.js" 
                         Exclude="$(FrameworkPath)dotnet.native.*.js;$(FrameworkPath)dotnet.runtime.*.js" />
  </ItemGroup>
  <Copy SourceFiles="@(DotnetVersionedFile)" 
        DestinationFiles="$(FrameworkPath)dotnet.js" />
</Target>

Issue 3: Custom Elements Without Root Component

Projects with only custom elements (no traditional root component) don't generate proper output. This suggests the SDK has hardcoded assumptions about root components being required.

Build Log Evidence

The build log shows GeneratePublishWasmBootJson and GeneratePublishBlazorBootJson targets running, but no output is produced:

CustomElementWASM net10.0 browser-wasm GeneratePublishWasmBootJson (7.0s)
CustomElementWASM net10.0 browser-wasm succeeded (8.9s) → publish-output\
Build succeeded in 14.1s

Yet blazor.boot.json does not exist in the output.

Browser Console Output

When attempting to load the incomplete build output:

[MONO] * Assertion at /__w/1/s/src/runtime/src/mono/mono/metadata/assembly.c:2718, condition `<disabled>' not met
MONO_WASM: mono_wasm_load_runtime () failed [object Object]
Uncaught (in promise) ExitStatus {name: 'ExitStatus', message: 'Program terminated with exit(1)', status: 1, silent: true}
Uncaught (in promise) Error: Failed to start platform. Reason: [object Object]

Impact

This is a complete blocker for:

  • Migrating Blazor custom elements projects to .NET 10
  • Using Blazor custom elements in non-Blazor hosts (Vite, plain HTML, React, Angular, etc.)
  • Embedding Blazor components as web components
  • Any scenario where Blazor components need to be consumed outside of a full Blazor app

Workarounds Attempted (All Failed)

  1. ❌ Adding dummy root component (App.razor)
  2. ❌ Disabling artifacts output with <UseArtifactsOutput>false</UseArtifactsOutput>
  3. ❌ Explicit PublishDir parameter: dotnet publish -c Release /p:PublishDir=publish-output
  4. ❌ Using traditional bin/obj paths via .csproj properties
  5. ❌ Creating local Directory.Build.props to block parent
  6. ❌ Clean builds (removing obj/bin folders)
  7. ❌ Different combinations of root components and custom elements

None of these workarounds result in a functional build output.

Minimal Reproduction Repository

A minimal reproduction repository can be provided if needed. The issue is 100% reproducible following the steps above.

Request

Please investigate why Blazor WebAssembly publish is not generating the required files for custom elements projects in .NET 10 RC2. This appears to be a regression or incomplete implementation of the custom elements feature in this release candidate.

Related Documentation

Additional Context

This issue was discovered while attempting to integrate Blazor custom elements into a Vite-based website. The custom elements feature worked in .NET 7, and there are no indications in the documentation that custom elements have been deprecated or fundamentally changed in .NET 10.


Priority: High - Complete feature breakage
Component: Blazor WebAssembly / Custom Elements
Affects: .NET 10 RC2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Attention 👋This issue needs the attention of a contributor, typically because the OP has provided an update.area-blazorIncludes: Blazor, Razor Components

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions