Describe the bug
When leveraging Microsoft.NET.Sdk.WebAssembly to create a WASM-only project (No Blazor) that also takes a dependency on a standard Library project (using Microsoft.NET.Sdk) which in turn contains its own static web assets, it is unclear how to export the static web assets such that they properly appear both:
- When published (
dotnet publish).
- When debugging (either
dotnet run or F5 in Visual Studio).
While the Microsoft.NET.Sdk.WebAssembly default debug experience appears to leverage the SWA pipeline available to Blazor apps, it does not seem to include static web assets from the dependent libraries, nor does it take any notice of the <StaticWebAssetBasePath> that appears in those libraries.
The static web asset files can be explicitly binplaced with <Content> in the Library to get the proper publish behavior, but ONLY by manually creating any nested library-specified content paths within the library's file structure. This is undesirable because it creates extra directory structure that is not normally present.
Or in the alternative the app project can explicitly include content from the library using its own <Content Include="..\MyLibrary\wwwroot\**\*" Link="wwwroot\MyLibrary\%(RecursiveDir)%(Filename)%(Extension)"> pattern. This allows the app to define the substructure but requires the app to know about the make-up of its library a priori (e.g. whether or not they even have static web assets) breaking project independence.
The above solutions produce a proper binplaced file layout for Publish. However, neither of the above solutions correctly participates in the SWA pipeline that generates the static web asset manifest leveraged by the default debugging experience. dotnet run and F5 in Visual Studio include ONLY the assets found directly in the app's wwwroot and do NOT include those assets inherited from dependencies.
What is the proper way to build this two-project solution such that publishing and debugging work correctly?
Steps to reproduce
MyLibrary.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-browser</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Needed for [JSImport]. -->
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<StaticWebAssetBasePath>MyLibrary</StaticWebAssetBasePath>
</PropertyGroup>
<ItemGroup>
<Content Include="wwwroot\**\*" CopyToOutputDirectory="Always" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.JSInterop" Version="10.0.8" />
</ItemGroup>
</Project>
MyWasm.csproj
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
<PropertyGroup>
<TargetFramework>net10.0-browser</TargetFramework>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<!-- Include SWA assets from MyLibrary? -->
<ItemGroup>
<!--<Content Include="..\MyLibrary\wwwroot\**\*"
Link="wwwroot\MyLibrary\%(RecursiveDir)%(Filename)%(Extension)"
CopyToOutputDirectory="Always" />-->
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.JSInterop.WebAssembly" Version="10.0.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyLibrary\MyLibrary.csproj" />
</ItemGroup>
</Project>
Expected behavior
The MyWasm project to automatically include the static web assets defined in MyLibrary. Those assets are available at runtime at an offset path defined by the <StaticWebAssetBasePath> tag in MyLibrary. Those assets are binplaced to the appropriate file structure by Publish. Those assets are included (referenced from their original location within the project directory of MyLibrary) in the SWA manifest produced by the MyWasm build and used to load static web assets during debugging sessions (either dotnet run or F5 in Visual Studio).
Actual behavior
The static web assets from MyLibrary are not available to the app under test during debugging sessions (either dotnet run or F5 in Visual Studio). The static web assets are only published IFF CopyToOutputDirectory="Always" is explicitly specified in the <Content>.
Is this a regression?
n/a
Are there any workarounds?
The static web assets from MyLibrary can be explicitly copied into the wwwroot folder of MyWasm before building. This makes maintenance complicated, but it does work.
dotnet --info output
D:\dev\Wasm\WasmBrowser >dotnet --info
.NET SDK:
Version: 10.0.300
Commit: caa81fa497
Workload version: 10.0.300.3
MSBuild version: 18.6.3+caa81fa49
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19045
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\10.0.300\
.NET workloads installed:
[android]
Installation Source: SDK 10.0.300, VS 17.14.37301.10, VS 18.6.11822.322
Manifest Version: 36.1.53/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.android\36.1.53\WorkloadManifest.json
Install Type: Msi
[ios]
Installation Source: SDK 10.0.300, VS 17.14.37301.10, VS 18.6.11822.322
Manifest Version: 26.5.10284/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.ios\26.5.10284\WorkloadManifest.json
Install Type: Msi
[maccatalyst]
Installation Source: SDK 10.0.300, VS 17.14.37301.10, VS 18.6.11822.322
Manifest Version: 26.5.10284/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maccatalyst\26.5.10284\WorkloadManifest.json
Install Type: Msi
[macos]
Installation Source: SDK 10.0.300
Manifest Version: 26.5.10284/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.macos\26.5.10284\WorkloadManifest.json
Install Type: Msi
[maui-windows]
Installation Source: SDK 10.0.300, VS 17.14.37301.10, VS 18.6.11822.322
Manifest Version: 10.0.20/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maui\10.0.20\WorkloadManifest.json
Install Type: Msi
[wasm-experimental]
Installation Source: SDK 10.0.300
Manifest Version: 10.0.108/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.workload.mono.toolchain.current\10.0.108\WorkloadManifest.json
Install Type: Msi
[wasm-tools]
Installation Source: SDK 10.0.300
Manifest Version: 10.0.108/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.workload.mono.toolchain.current\10.0.108\WorkloadManifest.json
Install Type: Msi
Configured to use workload sets when installing new manifests.
Host:
Version: 10.0.8
Architecture: x64
Commit: 94ea82652c
.NET SDKs installed:
1.0.4 [C:\Program Files\dotnet\sdk]
2.1.104 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.302 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.526 [C:\Program Files\dotnet\sdk]
2.1.818 [C:\Program Files\dotnet\sdk]
2.2.103 [C:\Program Files\dotnet\sdk]
3.0.103 [C:\Program Files\dotnet\sdk]
3.1.120 [C:\Program Files\dotnet\sdk]
3.1.426 [C:\Program Files\dotnet\sdk]
5.0.101 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
5.0.202 [C:\Program Files\dotnet\sdk]
5.0.214 [C:\Program Files\dotnet\sdk]
5.0.303 [C:\Program Files\dotnet\sdk]
5.0.406 [C:\Program Files\dotnet\sdk]
5.0.408 [C:\Program Files\dotnet\sdk]
7.0.410 [C:\Program Files\dotnet\sdk]
8.0.127 [C:\Program Files\dotnet\sdk]
9.0.305 [C:\Program Files\dotnet\sdk]
9.0.314 [C:\Program Files\dotnet\sdk]
10.0.108 [C:\Program Files\dotnet\sdk]
10.0.300 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
arm64 [C:\Program Files\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\arm64\InstallLocation]
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
IDE version
Visual Studio 2026
Other details
No response
Describe the bug
When leveraging
Microsoft.NET.Sdk.WebAssemblyto create a WASM-only project (No Blazor) that also takes a dependency on a standard Library project (usingMicrosoft.NET.Sdk) which in turn contains its own static web assets, it is unclear how to export the static web assets such that they properly appear both:dotnet publish).dotnet runor F5 in Visual Studio).While the
Microsoft.NET.Sdk.WebAssemblydefault debug experience appears to leverage the SWA pipeline available to Blazor apps, it does not seem to include static web assets from the dependent libraries, nor does it take any notice of the<StaticWebAssetBasePath>that appears in those libraries.The static web asset files can be explicitly binplaced with
<Content>in the Library to get the proper publish behavior, but ONLY by manually creating any nested library-specified content paths within the library's file structure. This is undesirable because it creates extra directory structure that is not normally present.Or in the alternative the app project can explicitly include content from the library using its own
<Content Include="..\MyLibrary\wwwroot\**\*" Link="wwwroot\MyLibrary\%(RecursiveDir)%(Filename)%(Extension)">pattern. This allows the app to define the substructure but requires the app to know about the make-up of its library a priori (e.g. whether or not they even have static web assets) breaking project independence.The above solutions produce a proper binplaced file layout for Publish. However, neither of the above solutions correctly participates in the SWA pipeline that generates the static web asset manifest leveraged by the default debugging experience.
dotnet runand F5 in Visual Studio include ONLY the assets found directly in the app's wwwroot and do NOT include those assets inherited from dependencies.What is the proper way to build this two-project solution such that publishing and debugging work correctly?
Steps to reproduce
MyLibrary.csproj
MyWasm.csproj
Expected behavior
The
MyWasmproject to automatically include the static web assets defined inMyLibrary. Those assets are available at runtime at an offset path defined by the<StaticWebAssetBasePath>tag inMyLibrary. Those assets are binplaced to the appropriate file structure by Publish. Those assets are included (referenced from their original location within the project directory ofMyLibrary) in the SWA manifest produced by theMyWasmbuild and used to load static web assets during debugging sessions (eitherdotnet runor F5 in Visual Studio).Actual behavior
The static web assets from
MyLibraryare not available to the app under test during debugging sessions (eitherdotnet runor F5 in Visual Studio). The static web assets are only published IFFCopyToOutputDirectory="Always"is explicitly specified in the<Content>.Is this a regression?
n/a
Are there any workarounds?
The static web assets from
MyLibrarycan be explicitly copied into thewwwrootfolder ofMyWasmbefore building. This makes maintenance complicated, but it does work.dotnet --info output
IDE version
Visual Studio 2026
Other details
No response