Skip to content

Fix WASM gallery startup stall/blank by forcing UnoRuntimeIdentifier#314

Merged
Arlodotexe merged 1 commit into
CommunityToolkit:mainfrom
MartinZikmund:mzikmund/wasmlaunch
Jun 25, 2026
Merged

Fix WASM gallery startup stall/blank by forcing UnoRuntimeIdentifier#314
Arlodotexe merged 1 commit into
CommunityToolkit:mainfrom
MartinZikmund:mzikmund/wasmlaunch

Conversation

@MartinZikmund

Copy link
Copy Markdown
Contributor

Problem

The WebAssembly gallery fails on startup: WinUI 2 / Uno.UI (production at toolkitlabs.dev) hangs on the splash screen at ~100% load, and WinUI 3 / Uno.WinUI shows a blank screen. No console error. Both have the same root cause and regressed with the net8→net9 migration that flipped the head SDK from Microsoft.NET.Sdk.Web to Microsoft.NET.Sdk.WebAssembly.

Root cause

  1. The WASM head sets TargetFramework late — in App.Head.Wasm.props, imported in the project body.
  2. NuGet's generated .nuget.g.props imports Uno.(UI|WinUI).Runtime.WebAssembly.props (which sets UnoRuntimeIdentifier=WebAssembly) inside an ImportGroup gated on '$(TargetFramework)' == 'net9.0'. That file is evaluated before the project body, when TargetFramework is still empty, so the import is skipped and UnoRuntimeIdentifier never gets set.
  3. Uno's ReplaceUnoRuntime target is gated on UnoRuntimeIdentifier != '', so it never runs. That target swaps the platform-agnostic reference lib/net9.0/Uno.UI.dll (no embedded JS) for the uno-runtime/.../webassembly/Uno.UI.dll implementation that embeds Uno.UI.WasmScripts.Uno.UI.js.
  4. So the JS-less reference assembly ships → Uno.UI.js is never delivered → globalThis.Uno.UI never registers → Application.Start's callback is never invoked → the splash never clears.

Diagnostic proof: dotnet build … --getProperty:UnoRuntimeIdentifier returns empty; adding -p:TargetFramework=net9.0 (early) returns WebAssembly.

Fix

Set UnoRuntimeIdentifier=WebAssembly and UnoIsWebAssemblyBrowserHead=true explicitly in App.Head.Wasm.props (what the skipped NuGet import would have set). The runtime-assembly swap runs late enough that a body PropertyGroup satisfies its gate.

Verification

Built and run in the browser for both flavors. After the fix: 11 MB runtime Uno.UI.dll deployed, Uno.UI.js present in the package, uno_dependencies includes Uno.UI, and the gallery renders fully (2386 XAML elements, loader gone) in both Uno.UI/WinUI 2 and Uno.WinUI/WinUI 3.

Note for maintainers

This is the minimal, low-risk fix. The deeper issue is that the late-TargetFramework pattern silently skips any net9.0-conditional NuGet import; longer-term, making TargetFramework known before .nuget.g.props (global property / real multi-targeting outer build) or migrating heads to Uno.Sdk would address the class of problem.

🤖 Generated with Claude Code

…Identifier

The WASM head sets TargetFramework late, via App.Head.Wasm.props imported in the
project body, after NuGet's generated .nuget.g.props has already been evaluated.
That generated file imports Uno.(UI|WinUI).Runtime.WebAssembly.props - which sets
UnoRuntimeIdentifier=WebAssembly - inside an ImportGroup gated on
"'$(TargetFramework)' == 'net9.0'". Since TargetFramework is still empty when
.nuget.g.props is evaluated, the import is skipped and UnoRuntimeIdentifier is
never set.

With UnoRuntimeIdentifier empty, Uno's ReplaceUnoRuntime target (gated on
UnoRuntimeIdentifier != '') does not run, so the platform-agnostic reference
Uno.UI.dll (lib/, no embedded JS) is deployed instead of the
uno-runtime/.../webassembly implementation that embeds Uno.UI.WasmScripts.Uno.UI.js.
The bootstrapper therefore has no Uno runtime JS to load, globalThis.Uno.UI is
never registered, Application.Start's callback is never invoked, and the gallery
hangs on the splash screen (WinUI 2 / Uno.UI) or shows blank (WinUI 3 / Uno.WinUI).

This regressed in the net8 -> net9 migration that flipped the head SDK from
Microsoft.NET.Sdk.Web to Microsoft.NET.Sdk.WebAssembly.

Set UnoRuntimeIdentifier=WebAssembly and UnoIsWebAssemblyBrowserHead=true
explicitly in App.Head.Wasm.props so the runtime-assembly swap runs regardless of
NuGet import timing. Verified end-to-end (gallery renders, 2386 XAML elements) for
both Uno.UI/WinUI 2 and Uno.WinUI/WinUI 3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@Arlodotexe Arlodotexe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, this did the trick! Huge thanks @MartinZikmund, we'd have never guessed this on our own 😄 Approved to merge

Image

@Arlodotexe

Arlodotexe commented Jun 25, 2026

Copy link
Copy Markdown
Member

Note that upstream repositories (Labs, mainline) will need a tooling commit pointer bump before devs can use this fix.

Additionally, we still have a configuration issue on the WASM head that prevents deploying from Visual Studio (#314) that we need to resolve before contributors can try/test code in WASM again. To be addressed after we fix the WinUI 3 head, since that's stalled via CommunityToolkit/Labs-Windows#77.

@Arlodotexe Arlodotexe merged commit 2c6819d into CommunityToolkit:main Jun 25, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants