Blazor WebAssembly applications have traditionally needed a development server to serve the application during development. In earlier setups, Microsoft.AspNetCore.Components.WebAssembly.DevServer was commonly used for this purpose.
That approach changes with .NET 11.
The Blazor WebAssembly development experience now uses a Gateway approach instead of the older DevServer package. The Gateway can handle development-time hosting and proxying while keeping the application structure simpler. Microsoft introduced this change as part of the ASP.NET Core and Blazor development updates.
For developers maintaining an existing standalone Blazor WebAssembly application, this means there are a few things worth understanding before upgrading.
The basic idea is:
Older setup
Blazor WebAssembly
|
v
WebAssembly DevServer
|
v
Development browser
The newer approach looks more like:
Blazor WebAssembly
|
v
Blazor Gateway
|
v
Development browser
The change is mainly about the development infrastructure. It does not mean that your application suddenly becomes a server-rendered Blazor application.
In this article, we will look at the role of the Gateway, how it differs from the old development server, how to configure a standalone application, and what to check when moving an existing project.
What Was WebAssembly DevServer?
A standalone Blazor WebAssembly application runs primarily in the browser.
During development, however, the application still needs a server to:
Serve static files
Provide development-time behavior
Support debugging
Handle browser requests
Coordinate development tooling
Historically, a project could reference:
<PackageReference
Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer"
Version="..." />
The package provided the development server used to launch the WebAssembly application.
A developer could then run the application using the normal .NET tooling and access it through the development URL.
What Is the Blazor Gateway?
The Gateway is the newer development-time mechanism used for standalone Blazor WebAssembly applications.
Its job is still related to development hosting, but it provides a more integrated way to handle the development application and its associated requests.
The important distinction is:
Gateway
=
Development infrastructure
It is not your application backend.
If your application calls an ASP.NET Core API, the API remains a separate application or backend service.
For example:
Browser
|
v
Blazor WebAssembly
|
v
Gateway
|
+------> Static application assets
|
+------> API/backend
The Gateway should therefore not be confused with an ASP.NET Core Web API.
Why Is the Change Important?
The change matters mostly when maintaining or upgrading existing standalone WebAssembly projects.
A project that still contains the old DevServer package may need changes during an upgrade.
Developers should check:
Project references
Development launch configuration
HTTPS configuration
Proxy configuration
API endpoints
Local development ports
Build and publish behavior
The goal is not to rewrite the application.
The goal is to move the development hosting setup to the newer approach.
Standalone Blazor WebAssembly Architecture
A typical standalone Blazor WebAssembly application looks like this:
+-------------------------+
| Browser |
| |
| Blazor WebAssembly |
| |
+------------+------------+
|
| HTTP
v
+-------------------------+
| Backend API |
| |
| ASP.NET Core / Other |
+-------------------------+
The WebAssembly application runs in the browser.
The backend API runs separately.
The development server or Gateway is primarily responsible for making the local development experience work.
This distinction becomes important when troubleshooting.
If your application cannot call an API, the problem may be related to CORS, authentication, URL configuration, or the API itself. Replacing the DevServer with Gateway does not automatically solve those issues.
Checking the Project File
Start by checking the .csproj file.
An older project might contain:
<ItemGroup>
<PackageReference
Include="Microsoft.AspNetCore.Components.WebAssembly"
Version="..." />
<PackageReference
Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer"
Version="..." />
</ItemGroup>
The important line is:
Microsoft.AspNetCore.Components.WebAssembly.DevServer
When moving to the newer development model, review the project template and .NET 11 migration guidance rather than blindly copying package versions.
The correct project configuration depends on the exact application template and target framework.
Targeting .NET 11
A project targeting .NET 11 should have the appropriate target framework:
<TargetFramework>net11.0</TargetFramework>
A simplified project file might look like:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
The exact SDK and package references should come from the application template being used.
Do not remove package references simply because their names look related to the old server.
Check whether your application actually requires them.
Development Launch Configuration
A standalone WebAssembly application may also have a Properties directory containing development launch settings.
For example:
{
"profiles": {
"BlazorApp": {
"commandName": "Project",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7001;http://localhost:5001"
}
}
}
Do not copy these ports directly into another project.
The port values are application-specific.
When migrating, compare your existing launch configuration with the configuration generated by the current .NET template.
Gateway and API Proxying
One useful role of development infrastructure is helping the browser communicate with backend services during local development.
Suppose the WebAssembly application runs at:
https://localhost:7001
and the API runs at:
https://localhost:8001
The browser needs to make requests between these origins.
Depending on the application architecture, you may need:
CORS configuration
A proxy
A shared origin
Authentication configuration
The Gateway can be part of the local development routing architecture, but it does not remove the need to understand browser security rules.
For example, a direct API call might look like:
var response =
await Http.GetAsync("https://localhost:8001/api/products");
If the two applications use different origins, the API must permit the browser request where CORS applies.
CORS Still Matters
A common mistake during migration is assuming that changing the development server automatically fixes cross-origin requests.
It does not.
If the browser reports a CORS error, investigate the API configuration.
A typical ASP.NET Core API might have:
builder.Services.AddCors(options =>
{
options.AddPolicy("BlazorClient", policy =>
{
policy.WithOrigins("https://localhost:7001")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Join the conversation! Your thoughts help the community grow.