Blazor Rendering Modes in .NET 8/9: Static, Server, WebAssembly & Auto
Master Blazor rendering modes in .NET 8/9: static SSR, interactive Server, WebAssembly, and Auto.
20+ years shipping production .NET services in enterprise systems. Drawn from code that ran under real load.
- ✓Basic knowledge of C# and .NET
- ✓Familiarity with Blazor fundamentals (components, pages, routing)
- ✓Visual Studio 2022 or later with .NET 8/9 SDK installed
- Blazor offers four rendering modes: Static Server-Side Rendering (SSR), Interactive Server, Interactive WebAssembly, and Interactive Auto.
- Static SSR renders HTML on the server without interactivity; best for content-heavy pages.
- Interactive Server maintains a real-time SignalR connection for UI updates.
- Interactive WebAssembly runs entirely in the browser using WebAssembly.
- Interactive Auto starts with Server mode and switches to WebAssembly on subsequent visits.
Think of Blazor rendering modes like different ways to serve a meal. Static SSR is like a pre-cooked meal delivered to your door – you get it ready to eat, but can't change it. Interactive Server is like a personal chef who cooks in your kitchen and adjusts the recipe based on your feedback, but needs constant communication. Interactive WebAssembly is like a frozen meal you heat up at home – all the cooking instructions are already there, so you don't need the chef. Interactive Auto starts with the chef but leaves the frozen meal for next time, so you get quick service initially and then faster load times later.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
Blazor in .NET 8 and .NET 9 introduces a powerful new feature: multiple rendering modes that let you choose how your components render and interact with users. Whether you're building a content-heavy blog, a real-time dashboard, or a progressive web app, understanding these modes is crucial for performance, scalability, and user experience. In this tutorial, we'll dive deep into each mode – Static SSR, Interactive Server, Interactive WebAssembly, and Interactive Auto – with practical code examples, real-world scenarios, and debugging strategies. You'll learn not just how to use them, but when to use each one to avoid common pitfalls like slow load times, high server costs, or broken interactivity. By the end, you'll be able to architect Blazor applications that are fast, responsive, and maintainable.
Understanding Blazor Rendering Modes
Blazor in .NET 8/9 introduces four rendering modes that determine how components are rendered and how they handle interactivity. The mode is set at the component level using the @rendermode directive or globally in the App.razor file. The modes are:
- Static Server-Side Rendering (SSR): The component renders HTML on the server and sends it to the client. No interactivity; any user interaction requires a full page reload. Ideal for content-heavy pages like blogs or documentation.
- Interactive Server: The component renders on the server and maintains a real-time SignalR connection for UI updates. Interactivity is handled server-side, which means low client resources but higher server load. Best for real-time apps like dashboards.
- Interactive WebAssembly: The component runs entirely in the browser using WebAssembly. All code executes on the client, reducing server load but increasing download size. Great for offline-capable apps.
- Interactive Auto: A hybrid mode that starts with Interactive Server for the first visit (fast initial load) and then downloads the WebAssembly assets in the background. On subsequent visits, it switches to Interactive WebAssembly for faster interactions. Best for apps that need a balance between initial load time and interactivity.
You can set the render mode on a per-component basis using the @rendermode directive. For example: @rendermode InteractiveServer. You can also define custom render modes using the RenderMode class.
Static SSR: Fast Content Delivery
Static SSR is the simplest mode: it renders HTML on the server and sends it to the client without any interactivity. This mode is perfect for pages that don't require user input, such as blog posts, product listings, or documentation. Since there's no SignalR connection or WebAssembly download, the page loads extremely fast and uses minimal server resources.
To use Static SSR, simply omit the @rendermode directive or set it to @rendermode Static (though Static is the default for pages without an interactive mode). You can also explicitly set it:
@rendermode RenderMode.Static
Static SSR components can still contain interactive child components if those children have their own render mode. However, the static parent will not be interactive. This is useful for layouts where you want a static shell with interactive islands.
One important consideration: Static SSR components cannot use @onclick or other event handlers directly. If you need interactivity, you must either switch to an interactive mode or use JavaScript interop.
Interactive Server: Real-Time UI Updates
Interactive Server mode renders components on the server and maintains a persistent SignalR connection between client and server. All UI events (button clicks, form submissions) are sent to the server via SignalR, processed, and the updated UI is sent back. This mode is ideal for applications that require real-time updates, such as dashboards, chat apps, or collaborative tools.
To enable Interactive Server, use @rendermode InteractiveServer. You can also set it globally in App.razor:
<Routes @rendermode="InteractiveServer" />
One key advantage is that all .NET code runs on the server, so you have access to server resources like databases without exposing secrets to the client. However, the downside is that each client consumes server memory and CPU, and latency can be an issue for users far from the server.
Interactive Server components can use @onclick, @bind, and other event handlers. They also support Blazor's built-in forms and validation.
Interactive WebAssembly: Client-Side Execution
Interactive WebAssembly mode runs Blazor components entirely in the browser using WebAssembly. The .NET code is compiled into WebAssembly and downloaded to the client, where it executes. This mode eliminates the need for a persistent server connection, reducing server load and enabling offline scenarios.
To use Interactive WebAssembly, set @rendermode InteractiveWebAssembly. Note that the initial download includes the .NET runtime and assemblies, which can be large (several MB). However, subsequent visits can be faster if the assets are cached.
Interactive WebAssembly components can access browser APIs via JavaScript interop and can use local storage, geolocation, etc. They cannot directly access server resources like databases; instead, they must call web APIs.
One important consideration: Interactive WebAssembly runs on the client, so sensitive logic (e.g., authentication) should not be exposed. Always validate on the server.
Interactive Auto: The Best of Both Worlds
Interactive Auto mode is a hybrid that combines Interactive Server and Interactive WebAssembly. On the first visit, the component renders using Interactive Server mode, providing fast initial load and interactivity. Meanwhile, the WebAssembly assets are downloaded in the background. On subsequent visits, the component switches to Interactive WebAssembly mode, eliminating the server round-trip for faster interactions.
To use Interactive Auto, set @rendermode InteractiveAuto. You can also configure the render mode globally:
<Routes @rendermode="InteractiveAuto" />
This mode is ideal for applications that need a fast first load but also want to reduce server load over time. However, there are caveats:
- State is not automatically preserved when switching from Server to WebAssembly. You must implement state persistence (e.g., using local storage or a state container).
- The initial Server mode still requires a SignalR connection, so server resources are used on the first visit.
- The switch to WebAssembly happens on subsequent navigations, not on the same page. So if a user stays on the same page, it remains in Server mode.
To detect the current rendering mode at runtime, use the RendererInfo service:
@inject IHostEnvironment HostEnvironment @inject RendererInfo RendererInfo
<p>Current render mode: @RendererInfo.RenderMode</p>
Choosing the Right Rendering Mode
Selecting the appropriate rendering mode depends on your application's requirements. Here's a decision guide:
- Static SSR: Use for content pages that don't need interactivity (blogs, documentation, landing pages). Best for SEO and fast initial load.
- Interactive Server: Use for real-time applications (dashboards, chat, collaborative editing) where server-side processing is needed and low latency is acceptable.
- Interactive WebAssembly: Use for client-heavy applications (games, offline tools, complex calculators) where you want to offload processing to the client and reduce server costs.
- Interactive Auto: Use for applications that need a balance between initial load time and interactivity, especially when you expect users to visit multiple pages (e.g., e-commerce sites).
You can also mix modes within a single page. For example, a product listing page can be Static SSR for the list, but each product card can have an Interactive Server 'Add to Cart' button. This is known as 'islands architecture'.
- Static SSR: Fastest initial load, no interactivity.
- Interactive Server: Moderate initial load (SignalR negotiation), high server load.
- Interactive WebAssembly: Slow initial load (download .NET runtime), low server load.
- Interactive Auto: Fast initial load (Server), then fast subsequent loads (WebAssembly).
- Interactive Server: Code runs on server, so sensitive logic is safe.
- Interactive WebAssembly: Code runs on client; avoid exposing secrets or performing security-sensitive operations on the client.
- Static SSR: No client-side code, so minimal attack surface.
Debugging Rendering Mode Issues
Debugging rendering mode issues can be tricky because the behavior differs between development and production. Here are common issues and how to resolve them:
Issue: Component not interactive - Check that the component has an interactive render mode (InteractiveServer, InteractiveWebAssembly, or InteractiveAuto). Static SSR components cannot handle events. - Verify that the render mode is not overridden by a parent component. Use the browser's developer tools to inspect the HTML; interactive components will have additional attributes (e.g., blazor-server).
Issue: Slow initial load - For Interactive WebAssembly, consider using InteractiveAuto to provide a fast initial load with Server mode while downloading WebAssembly assets. - Enable prerendering for InteractiveServer and InteractiveAuto modes to speed up perceived load time.
Issue: State lost on navigation - When using InteractiveAuto, state is not preserved when switching from Server to WebAssembly. Implement a state container service that persists state in browser storage (e.g., ProtectedLocalStorage). - For InteractiveServer, state is preserved as long as the circuit is alive. If the circuit disconnects, state is lost. Implement reconnection logic.
Issue: High server resource usage - Switch from InteractiveServer to InteractiveWebAssembly for less interactive pages. - Use Static SSR for content pages. - Scale out your server or use Azure SignalR Service.
To debug rendering modes, use the RendererInfo service to log the current mode:
@inject RendererInfo RendererInfo @code { protected override void OnInitialized() { Console.WriteLine($"Render mode: {RendererInfo.RenderMode}"); } }
The Case of the Disappearing Form: When Auto Mode Broke User Input
- Auto mode does not preserve component state across mode switches; use a persistent state service.
- Always test multi-step forms and stateful interactions in all rendering modes.
- Consider using Interactive Server mode for complex forms to avoid state loss.
- Document the rendering mode behavior for your team to prevent assumptions.
- Use the RendererInfo service to detect the current rendering mode and adapt behavior.
Inspect HTML: look for blazor-server or blazor-webassembly script tagsCheck browser console for errors| File | Command / Code | Purpose |
|---|---|---|
| RenderModesExample.razor | @page "/counter" | Understanding Blazor Rendering Modes |
| StaticSSRExample.razor | @page "/about" | Static SSR |
| InteractiveServerExample.razor | @page "/realtime" | Interactive Server |
| InteractiveWasmExample.razor | @page "/wasm" | Interactive WebAssembly |
| InteractiveAutoExample.razor | @page "/auto" | Interactive Auto |
| MixedModesExample.razor | @page "/products" | Choosing the Right Rendering Mode |
| DebugRenderingMode.razor | @page "/debug" | Debugging Rendering Mode Issues |
Key takeaways
Common mistakes to avoid
5 patternsUsing InteractiveServer for all pages without considering server load.
Assuming InteractiveAuto preserves component state across mode switches.
Setting a global render mode without considering page-specific needs.
Not testing mixed rendering modes thoroughly.
Forgetting to enable prerendering for InteractiveServer and InteractiveAuto modes.
Interview Questions on This Topic
Explain the four Blazor rendering modes in .NET 8/9 and when you would use each.
Frequently Asked Questions
20+ years shipping production .NET services in enterprise systems. Drawn from code that ran under real load.
That's ASP.NET. Mark it forged?
5 min read · try the examples if you haven't