Home C# / .NET Blazor Rendering Modes in .NET 8/9: Static, Server, WebAssembly & Auto
Advanced 5 min · July 13, 2026

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.

N
Naren Founder & Principal Engineer

20+ years shipping production .NET services in enterprise systems. Drawn from code that ran under real load.

Follow
Production
production tested
July 13, 2026
last updated
2,043
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic knowledge of C# and .NET
  • Familiarity with Blazor fundamentals (components, pages, routing)
  • Visual Studio 2022 or later with .NET 8/9 SDK installed
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • 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.
✦ Definition~90s read
What is Blazor Rendering Modes in .NET 8/9?

Blazor rendering modes in .NET 8/9 are a set of options that determine how your Blazor components are rendered and how they handle interactivity, allowing you to optimize for performance, server load, and user experience.

Think of Blazor rendering modes like different ways to serve a meal.
Plain-English First

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.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

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.

RenderModesExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@page "/counter"
@rendermode InteractiveServer

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}
Output
Renders a counter button that updates the count via SignalR without full page reload.
🔥Render Mode Inheritance
📊 Production Insight
In production, avoid mixing interactive modes on the same page unless you carefully manage state. For example, an InteractiveServer component inside an InteractiveWebAssembly page will cause a full page reload when interacting with the server component.
🎯 Key Takeaway
Blazor rendering modes control where and how components execute: server-side, client-side, or hybrid. Choose based on interactivity needs and performance goals.

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.

StaticSSRExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
@page "/about"
@rendermode RenderMode.Static

<PageTitle>About Us</PageTitle>

<h1>About Our Company</h1>

<p>We are a leading provider of Blazor solutions. Our team has years of experience in building high-performance web applications.</p>

<p>Contact us at info@example.com</p>
Output
Renders a static HTML page with no interactivity. Fast initial load.
💡Use Static SSR for SEO
📊 Production Insight
In production, you can combine Static SSR with interactive components using 'islands' architecture. For example, a static product page can have an interactive 'Add to Cart' button that uses InteractiveServer mode.
🎯 Key Takeaway
Static SSR is the fastest rendering mode for content delivery but lacks interactivity. Use it for pages that don't need user input.

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.

InteractiveServerExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@page "/realtime"
@rendermode InteractiveServer
@using Microsoft.AspNetCore.SignalR
@inject IHubContext<ChatHub> HubContext

<h1>Real-Time Chat</h1>

<div>
    <input @bind="message" placeholder="Type a message" />
    <button @onclick="SendMessage">Send</button>
</div>

<ul>
    @foreach (var msg in messages)
    {
        <li>@msg</li>
    }
</ul>

@code {
    private string message;
    private List<string> messages = new();

    private async Task SendMessage()
    {
        messages.Add(message);
        await HubContext.Clients.All.SendAsync("ReceiveMessage", message);
        message = string.Empty;
    }
}
Output
A real-time chat interface where messages appear instantly for all connected users via SignalR.
⚠ Server Resource Management
📊 Production Insight
In production, monitor SignalR connections and consider scaling out with Azure SignalR Service for high-traffic apps. Also, implement circuit reconnection logic to handle temporary disconnections.
🎯 Key Takeaway
Interactive Server provides real-time interactivity with full server-side processing, but at the cost of server resources and network latency.

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.

InteractiveWasmExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@page "/wasm"
@rendermode InteractiveWebAssembly
@inject IJSRuntime JS

<h1>Client-Side Calculator</h1>

<input @bind="number1" type="number" />
<select @bind="operation">
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
</select>
<input @bind="number2" type="number" />
<button @onclick="Calculate">=</button>

<p>Result: @result</p>

@code {
    private double number1, number2, result;
    private string operation = "+";

    private void Calculate()
    {
        result = operation switch
        {
            "+" => number1 + number2,
            "-" => number1 - number2,
            "*" => number1 * number2,
            "/" => number2 != 0 ? number1 / number2 : double.NaN,
            _ => 0
        };
    }
}
Output
A calculator that runs entirely in the browser without server round-trips.
🔥Offline Support
📊 Production Insight
In production, use lazy loading for assemblies to reduce initial download size. Also, consider using the InteractiveAuto mode to provide a fast initial load with Server mode while downloading WebAssembly assets in the background.
🎯 Key Takeaway
Interactive WebAssembly offloads processing to the client, reducing server costs and enabling offline scenarios, but requires a larger initial download.

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>

InteractiveAutoExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@page "/auto"
@rendermode InteractiveAuto
@inject RendererInfo RendererInfo

<h1>Auto Mode Demo</h1>

<p>Current render mode: @RendererInfo.RenderMode</p>

<button @onclick="Increment">Count: @count</button>

@code {
    private int count = 0;

    private void Increment()
    {
        count++;
    }
}
Output
On first visit, the button updates via SignalR (Server mode). On subsequent visits, it updates via WebAssembly (client-side). The render mode label changes accordingly.
⚠ State Persistence in Auto Mode
📊 Production Insight
In production, test Auto mode thoroughly with stateful components. Consider using the InteractiveAuto mode only for pages that don't maintain complex state, or implement a robust state persistence strategy.
🎯 Key Takeaway
Interactive Auto provides a fast initial load with Server mode and then switches to WebAssembly for subsequent visits, but requires careful state management.

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'.

Performance considerations
  • 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).
Security considerations
  • 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.
MixedModesExample.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@page "/products"
@rendermode RenderMode.Static

<h1>Products</h1>

@foreach (var product in products)
{
    <div class="product-card">
        <h3>@product.Name</h3>
        <p>@product.Description</p>
        <AddToCartButton ProductId="@product.Id" />
    </div>
}

@code {
    private List<Product> products = new();

    protected override async Task OnInitializedAsync()
    {
        // Load products from database
        products = await ProductService.GetAllAsync();
    }
}
Output
A static product list with interactive 'Add to Cart' buttons (defined in a separate component with InteractiveServer mode).
💡Islands Architecture
📊 Production Insight
In production, monitor performance metrics like Time to Interactive (TTI) and server resource usage. Use Application Insights to track SignalR connections and WebAssembly download times.
🎯 Key Takeaway
Choose rendering modes based on interactivity needs, performance goals, and security requirements. Mixing modes within a page is possible with islands architecture.

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}"); } }

DebugRenderingMode.razorCSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@page "/debug"
@rendermode InteractiveAuto
@inject RendererInfo RendererInfo
@inject ILogger<DebugRenderingMode> Logger

<h1>Debug Rendering Mode</h1>

<p>Current mode: @RendererInfo.RenderMode</p>
<p>Is interactive: @RendererInfo.IsInteractive</p>

<button @onclick="LogMode">Log Mode</button>

@code {
    private void LogMode()
    {
        Logger.LogInformation("Current render mode: {Mode}", RendererInfo.RenderMode);
    }
}
Output
Displays the current render mode and logs it when the button is clicked.
🔥RendererInfo Service
📊 Production Insight
In production, add telemetry to track render mode switches and user interactions. This helps identify performance bottlenecks and user experience issues.
🎯 Key Takeaway
Debugging rendering modes involves checking the mode at runtime, monitoring performance, and implementing state persistence for Auto mode.
● Production incidentPOST-MORTEMseverity: high

The Case of the Disappearing Form: When Auto Mode Broke User Input

Symptom
Users filling out a multi-step form would see their input vanish when navigating to the next step, forcing them to re-enter data.
Assumption
The developer assumed Auto mode would seamlessly preserve state across navigations because it uses Server mode initially.
Root cause
Auto mode switches from Server to WebAssembly on subsequent visits, but the component state is not persisted across modes. The form component was re-initialized in WebAssembly mode, losing all user input.
Fix
The developer implemented a state container service that persists form data in the browser's session storage, shared between Server and WebAssembly modes. They also added a check to detect mode switches and restore state accordingly.
Key lesson
  • 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.
Production debug guideSymptom to Action4 entries
Symptom · 01
Page loads slowly on first visit but fast on subsequent visits.
Fix
Check if Interactive Auto mode is used; first visit uses Server mode which may have latency. Consider pre-rendering with Static SSR for initial load.
Symptom · 02
Interactive features (e.g., button clicks) don't work after navigation.
Fix
Verify that the component is rendered with an interactive mode (InteractiveServer, InteractiveWebAssembly, or InteractiveAuto). Use the RenderMode attribute.
Symptom · 03
High server resource usage during peak traffic.
Fix
Switch from Interactive Server to Interactive WebAssembly or Static SSR for less interactive pages. Monitor SignalR connections.
Symptom · 04
User input lost when navigating between pages.
Fix
Implement a state container service (e.g., using Blazor's ProtectedLocalStorage) to persist state across navigations and mode switches.
★ Quick Debug Cheat SheetCommon Blazor rendering mode issues and immediate fixes.
Component not interactive
Immediate action
Check RenderMode attribute on component or page
Commands
Inspect HTML: look for blazor-server or blazor-webassembly script tags
Check browser console for errors
Fix now
Add @rendermode InteractiveServer to the component
Slow initial load+
Immediate action
Enable prerendering with InteractiveAuto or Static SSR
Commands
Check network tab for large .wasm files
Measure Time to Interactive (TTI)
Fix now
Use @rendermode InteractiveAuto for faster first load
State lost on navigation+
Immediate action
Implement state persistence
Commands
Check if component is re-initialized (constructor called)
Use browser storage or a scoped service
Fix now
Store state in ProtectedLocalStorage and restore on OnInitialized
ModeInitial Load SpeedInteractivityServer LoadOffline CapableBest For
Static SSRFastestNoneLowNoContent pages, blogs
Interactive ServerFastReal-timeHighNoDashboards, chat apps
Interactive WebAssemblySlowFullLowYesClient-heavy apps, games
Interactive AutoFast (first visit), Fast (subsequent)FullMedium (first visit), Low (subsequent)Yes (after switch)E-commerce, multi-page apps
⚙ Quick Reference
7 commands from this guide
FileCommand / CodePurpose
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

1
Blazor rendering modes allow you to choose between static, server-interactive, client-interactive, and hybrid approaches.
2
Static SSR is best for content-heavy pages; Interactive Server for real-time apps; Interactive WebAssembly for client-heavy apps; Interactive Auto for a balance.
3
You can mix modes within a page using islands architecture for optimal performance.
4
State management is critical when using Interactive Auto mode due to mode switches.
5
Always consider security implications
server-side code is safe, client-side code is exposed.

Common mistakes to avoid

5 patterns
×

Using 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 PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
Explain the four Blazor rendering modes in .NET 8/9 and when you would u...
Q02SENIOR
How does Interactive Auto mode handle state persistence? What are the ch...
Q03SENIOR
What is islands architecture in Blazor and how does it relate to renderi...
Q04JUNIOR
How can you detect the current rendering mode at runtime in Blazor?
Q05SENIOR
What are the security implications of using Interactive WebAssembly vs I...
Q01 of 05SENIOR

Explain the four Blazor rendering modes in .NET 8/9 and when you would use each.

ANSWER
The four modes are: Static SSR (fast content delivery, no interactivity), Interactive Server (real-time UI via SignalR, server-side processing), Interactive WebAssembly (client-side execution, offline capable), and Interactive Auto (hybrid: starts with Server, switches to WebAssembly). Use Static SSR for content pages, Interactive Server for real-time apps, Interactive WebAssembly for client-heavy apps, and Interactive Auto for a balance between initial load and interactivity.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Can I use different rendering modes on the same page?
02
How does Interactive Auto mode handle state when switching from Server to WebAssembly?
03
What is the difference between InteractiveServer and InteractiveAuto?
04
Can I use Blazor rendering modes with existing ASP.NET Core applications?
05
How do I set the render mode globally for all pages?
N
Naren Founder & Principal Engineer

20+ years shipping production .NET services in enterprise systems. Drawn from code that ran under real load.

Follow
Verified
production tested
July 13, 2026
last updated
2,043
articles · all by Naren
🔥

That's ASP.NET. Mark it forged?

5 min read · try the examples if you haven't

Previous
Blazor Authentication and Authorization
23 / 35 · ASP.NET
Next
Model Validation in ASP.NET Core