Choosing a Blazor Render Mode: Static, InteractiveServer, WebAssembly, or Auto
Choose the right Blazor render mode per component: Static, InteractiveServer, InteractiveWebAssembly, or Auto.
08 Sept 2025, 20:43 UTC

Decision: pick a render mode per component
In an ASP.NET Core Blazor Web App (.NET 8 or later), a component’s @rendermode attribute decides whether its HTML is produced on the server, in the browser, or both. Picking the wrong mode creates one of three problems: a slow first load from a large WebAssembly download, a SignalR connection that drops on unstable networks, or a server running out of memory because every open tab holds a live circuit.
Useful takeaway: start with Static for public pages that need search-engine visibility, InteractiveServer for intranet tools with reliable connections, InteractiveWebAssembly when you want to move UI processing to the client or work offline, and Auto only when you can verify the server-to-client upgrade works in your target browsers.
Supported render modes
A render mode tells Blazor where a component executes and how it processes clicks, form submissions, and other UI events. A circuit is the server-side SignalR connection that represents one user’s session in InteractiveServer mode. SignalR is a library for real-time connections between client and server.
| Render mode | Where it runs | First load | Network requirement | Best for |
|---|---|---|---|---|
Static | Server only; no UI events after HTML is sent | Fast, small HTML | Standard HTTP only | Public pages, SEO, landing pages |
InteractiveServer | Server over SignalR | Fast HTML, then circuit setup | Persistent SignalR connection | Intranet apps, dashboards, low client download |
InteractiveWebAssembly | Browser via WebAssembly | Slower; .NET runtime download | HTTP for download, then optional | Offline-capable apps, offloading server CPU |
Auto | Starts server, upgrades to WebAssembly | Fast server render, then client download | SignalR initially, then client runtime | Mixed audiences; verify upgrade path |
Trade-offs to check before you commit
InteractiveServer consumes server memory per connection
Every user with an InteractiveServer page open holds a circuit on the server. Under unstable networks, the circuit can reconnect or terminate, which loses unsaved UI state unless you persist it. Monitor concurrent circuit count if you expect many simultaneous users.
InteractiveWebAssembly increases initial payload
The first visit downloads the .NET WebAssembly runtime and your app assemblies. Compression and browser caching reduce repeat visits, but constrained networks and older devices may still see a noticeable delay before interactivity is available.
Server and WebAssembly state do not mix
If the same logical page uses InteractiveServer in one context and InteractiveWebAssembly in another, the two circuits do not share memory. Store shared data in a database, local storage, or a service that both sides can reach through HTTP.
Auto is not free
Auto renders on the server first, then downloads the WebAssembly runtime in the background. Clients that never download the runtime stay on the server. Clients that do download it switch to WebAssembly. Test both paths because event handling differs after the upgrade.
Concrete implementation: set render mode on a component
Version assumption: .NET 8 SDK or later, Blazor Web App template. The @rendermode directive is stable in .NET 8; preview releases used different APIs.
Create the project
Run this in a terminal or command prompt. No administrator permissions are required.
dotnet new blazorweb -o BlazorRenderModeSample
cd BlazorRenderModeSample
Expected check: dotnet --version returns 8.0.x or later. If it returns 7.x or earlier, the Blazor Web App template and per-component render modes are not available.
Add an interactive server component
Create Components/Pages/CounterServer.razor:
@page "/counter-server"
@rendermode InteractiveServer
Counter - Server
Counter (InteractiveServer)
Current count: @currentCount
Increment
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
The @rendermode InteractiveServer directive means the button click runs a method on the server over SignalR. Open the browser developer tools Network tab and look for SignalR negotiation after the page loads.
Add a WebAssembly component
Create Components/Pages/CounterWasm.razor:
@page "/counter-wasm"
@rendermode InteractiveWebAssembly
Counter - WebAssembly
Counter (InteractiveWebAssembly)
Current count: @currentCount
Increment
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Expected check: the first request to /counter-wasm triggers a WebAssembly runtime download visible in the Network tab. Subsequent clicks run in the browser without a server round-trip.
Add an Auto component
@page "/counter-auto"
@rendermode Auto
Counter (Auto)
Current count: @currentCount
Increment
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Auto starts with InteractiveServer behavior and upgrades to WebAssembly if the client downloads the runtime. Verify by watching the Network tab: SignalR traffic first, then a Wasm download, then client-only clicks.
Validation steps
- Run
dotnet runin the project folder. - Open
https://localhost:<port>/counter-serverand confirm the button works without a full page reload. - Open browser developer tools, select the Network tab, and filter by WebSocket or SignalR for the server component.
- Open
/counter-wasmand confirm a runtime download appears before interactivity is available. - Compare server memory while opening multiple InteractiveServer tabs; each tab adds circuit overhead.
Limitations
- InteractiveServer does not work well without a stable connection; consider InteractiveWebAssembly for mobile or unreliable networks.
- InteractiveWebAssembly cannot call server APIs directly without HTTP; it also cannot access server-only resources such as local files or protected database connections.
- Static components cannot handle postbacks or button clicks; add a render mode to make them interactive.
- Render mode behavior changed between .NET 8 previews and the stable release. Confirm behavior against the installed SDK release notes before adopting Auto in production.
Practical way to check the result
Deploy the sample to a staging environment and open the same page from two devices: one on a fast local network and one on a throttled mobile connection. If InteractiveServer pages feel laggy or disconnect, switch those components to InteractiveWebAssembly or Static plus a lightweight JavaScript handler. If WebAssembly first loads are too slow, keep the component on InteractiveServer or use Auto and measure the upgrade time.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.