|
8 | 8 | - [Virtualize keeps the viewport stable when content above it changes](#virtualize-keeps-the-viewport-stable-when-content-above-it-changes) |
9 | 9 | - [Virtualize AnchorMode for stable viewports during prepend and append](#virtualize-anchormode-for-stable-viewports-during-prepend-and-append) |
10 | 10 | - [Blazor WebAssembly service defaults template](#blazor-webassembly-service-defaults-template) |
| 11 | +- [Blazor Gateway for hosting standalone Blazor WebAssembly apps](#blazor-gateway-for-hosting-standalone-blazor-webassembly-apps) |
11 | 12 | - [MCP Server template ships with the .NET SDK](#mcp-server-template-ships-with-the-net-sdk) |
12 | 13 | - [TLS handshake observability in Kestrel](#tls-handshake-observability-in-kestrel) |
13 | 14 | - [Response compression always emits `Vary: Accept-Encoding`](#response-compression-always-emits-vary-accept-encoding) |
@@ -144,6 +145,89 @@ The generated library wires up OpenTelemetry logging/metrics/tracing with the OT |
144 | 145 | builder.AddBlazorClientServiceDefaults(); |
145 | 146 | ``` |
146 | 147 |
|
| 148 | +## Blazor Gateway for hosting standalone Blazor WebAssembly apps |
| 149 | + |
| 150 | +Standalone Blazor WebAssembly apps now have a new development-time host: the **Blazor Gateway** ([dotnet/aspnetcore #65982](https://github.com/dotnet/aspnetcore/pull/65982)). The Blazor Gateway replaces `Microsoft.AspNetCore.Components.WebAssembly.DevServer` with a real ASP.NET Core host that adds two capabilities the Dev Server never had: **YARP-based proxying to backend APIs** and a **runtime config endpoint** that flows JSON configuration to the client. Future templates will use the Blazor Gateway by default, but you can opt in today by swapping the package reference in any standalone Blazor WebAssembly project. |
| 151 | + |
| 152 | +To switch a standalone Blazor WebAssembly app from the Dev Server to the Gateway, replace the `Microsoft.AspNetCore.Components.WebAssembly.DevServer` reference in the `.csproj`: |
| 153 | + |
| 154 | +```xml |
| 155 | +<ItemGroup> |
| 156 | + <PackageReference Include="Microsoft.AspNetCore.Components.Gateway" Version="11.0.0-preview.4.*" PrivateAssets="all" /> |
| 157 | +</ItemGroup> |
| 158 | +``` |
| 159 | + |
| 160 | +`dotnet run` and `dotnet watch` then launch the Gateway instead of the Dev Server. The Gateway reads its configuration from `appsettings.Development.json` (or any standard configuration source), so all of the features below are configured the same way you'd configure any ASP.NET Core app. |
| 161 | + |
| 162 | +### Proxy `/api/*` to backend services with YARP |
| 163 | + |
| 164 | +The Gateway hosts [YARP](https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/yarp-overview) and reads the standard `ReverseProxy` configuration section. That means you can proxy API calls from the WebAssembly client to one or more backend services without setting up a custom dev-time proxy. For example, this configuration proxies any request that starts with `/api/` to a backend at `http://localhost:5180/`, stripping the `/api` prefix on the way through: |
| 165 | + |
| 166 | +```json |
| 167 | +{ |
| 168 | + "ReverseProxy": { |
| 169 | + "Routes": { |
| 170 | + "weather-api": { |
| 171 | + "ClusterId": "backend", |
| 172 | + "Match": { "Path": "/api/{**catch-all}" }, |
| 173 | + "Transforms": [ |
| 174 | + { "PathRemovePrefix": "/api" } |
| 175 | + ] |
| 176 | + } |
| 177 | + }, |
| 178 | + "Clusters": { |
| 179 | + "backend": { |
| 180 | + "Destinations": { |
| 181 | + "d1": { "Address": "http://localhost:5180/" } |
| 182 | + } |
| 183 | + } |
| 184 | + } |
| 185 | + } |
| 186 | +} |
| 187 | +``` |
| 188 | + |
| 189 | +In the Blazor client, `HttpClient` calls to relative URLs like `api/weather` are then routed through the Gateway to the backend — no CORS configuration, no extra middleware in the backend, and no dev-only `BaseAddress` switching: |
| 190 | + |
| 191 | +```csharp |
| 192 | +var forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("api/weather"); |
| 193 | +``` |
| 194 | + |
| 195 | +### Flow runtime config to the client through a config endpoint |
| 196 | + |
| 197 | +The Gateway can also expose a configuration endpoint that returns inline JSON to the WebAssembly client, so settings like `ApiBaseUrl` or feature flags don't have to be baked into the published assets. Configure the endpoint with `ClientApps:<name>:ConfigEndpointPath` and `ClientApps:<name>:ConfigResponse`: |
| 198 | + |
| 199 | +```json |
| 200 | +{ |
| 201 | + "ClientApps": { |
| 202 | + "app": { |
| 203 | + "ConfigEndpointPath": "/_app/config", |
| 204 | + "ConfigResponse": "{ \"apiBaseUrl\": \"/api\", \"featureFlags\": { \"newCheckout\": true } }" |
| 205 | + } |
| 206 | + } |
| 207 | +} |
| 208 | +``` |
| 209 | + |
| 210 | +Fetch the response from a Razor component to drive client-side behavior: |
| 211 | + |
| 212 | +```csharp |
| 213 | +@inject HttpClient Http |
| 214 | + |
| 215 | +@code { |
| 216 | + AppConfig? config; |
| 217 | + |
| 218 | + protected override async Task OnInitializedAsync() |
| 219 | + { |
| 220 | + config = await Http.GetFromJsonAsync<AppConfig>("_app/config"); |
| 221 | + } |
| 222 | + |
| 223 | + record AppConfig(string ApiBaseUrl, Dictionary<string, bool> FeatureFlags); |
| 224 | +} |
| 225 | +``` |
| 226 | + |
| 227 | +### End-to-end sample |
| 228 | + |
| 229 | +A complete working setup — standalone Blazor WebAssembly client, ASP.NET Core backend, and a Gateway wired up with both YARP proxying and a config endpoint — is in the [`GatewayDemo` sample](https://github.com/danroth27/AspNetCore11Samples/tree/dotnet11p4/GatewayDemo). The sample also shows how to wire up [`Microsoft.Extensions.ServiceDiscovery`](https://learn.microsoft.com/dotnet/core/extensions/service-discovery) so YARP destinations can be resolved by service name in addition to absolute URLs. |
| 230 | + |
147 | 231 | ## MCP Server template ships with the .NET SDK |
148 | 232 |
|
149 | 233 | The `mcpserver` project template, previously available only by installing `Microsoft.McpServer.ProjectTemplates`, now ships as a bundled template in the .NET SDK ([dotnet/aspnetcore #66520](https://github.com/dotnet/aspnetcore/pull/66520)). |
|
0 commit comments