DEV Community

IronSoftware
IronSoftware

Posted on

.NET 10 Blazor: What's New For 2026 Developers

.NET 10 shipped with significant Blazor improvements. Smaller bundle sizes, persistent circuit state, passkey authentication, and better 404 handling. Here's what matters.

// .NET 10 Blazor — Persistent state is now simple
@code {
    [PersistentState]
    public string UserPreference { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

One attribute. State survives reconnections.

How Much Smaller Is the Blazor Bundle?

The core blazor.web.js script dropped from 183 KB to 43 KB — a 76% reduction.

How? The script is now served as a static asset with automatic compression and fingerprinting. Faster initial loads, better caching.

No code changes needed. Upgrade to .NET 10 and the improvement is automatic.

What Is Persistent State?

Blazor Server can now persist circuit state across reconnections:

@page "/preferences"

@code {
    [PersistentState]
    public UserSettings Settings { get; set; } = new();

    private void SaveTheme(string theme)
    {
        Settings.Theme = theme;
    }
}
Enter fullscreen mode Exit fullscreen mode

If a user disconnects and reconnects — or if the server evicts the circuit — state survives. Previously, users lost all state on reconnection.

Control circuit behavior programmatically:

// JavaScript control
Blazor.pause();  // Pause circuit
Blazor.resume(); // Resume circuit
Enter fullscreen mode Exit fullscreen mode

How Does Passkey Authentication Work?

ASP.NET Core Identity now supports WebAuthn/FIDO2 passkeys:

// Program.cs
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddPasskeys(); // New in .NET 10
Enter fullscreen mode Exit fullscreen mode

Users can sign in without passwords using biometrics or hardware keys. Phishing-resistant by design.

What's New in Form Validation?

Nested form validation is now supported:

// Program.cs
builder.Services.AddValidatableTypes();

// Models
[ValidatableType]
public class Order
{
    [Required]
    public string CustomerName { get; set; }

    [ValidateComplexType]
    public Address ShippingAddress { get; set; }
}

public class Address
{
    [Required]
    public string Street { get; set; }

    [Required]
    public string City { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Register the validation system, add [ValidatableType] to root types, and nested validation works automatically.

How Do I Handle 404 Pages?

.NET 10 introduces automatic 404 handling:

// In any component
NavigationManager.NotFound();
Enter fullscreen mode Exit fullscreen mode

This works in both static SSR and interactive render modes. New project templates include a default NotFound.razor page.

@* NotFound.razor — included in new templates *@
@page "/not-found"

<h1>Page Not Found</h1>
<p>The page you're looking for doesn't exist.</p>
<a href="/">Return Home</a>
Enter fullscreen mode Exit fullscreen mode

No more manual 404 handling boilerplate.

What's New in JS Interop?

JavaScript interop gained new capabilities:

// Create JS object instance
var instance = await JS.InvokeAsync<IJSObjectReference>(
    "createInstance", "MyClass", arg1, arg2);

// Read JS property
var value = await JS.GetValueAsync<string>("window.myObject.property");

// Set JS property
await JS.SetValueAsync("window.myObject.property", newValue);
Enter fullscreen mode Exit fullscreen mode

Direct property access without wrapper functions. Cleaner interop code.

How Did QuickGrid Improve?

Conditional row styling:

<QuickGrid Items="@customers" RowClass="GetRowClass">
    <PropertyColumn Property="@(c => c.Name)" />
    <PropertyColumn Property="@(c => c.Balance)" />
</QuickGrid>

@code {
    private string GetRowClass(Customer customer)
    {
        return customer.Balance < 0 ? "negative-balance" : "";
    }
}
Enter fullscreen mode Exit fullscreen mode

Programmatically close column options:

await quickGrid.HideColumnOptionsAsync();
Enter fullscreen mode Exit fullscreen mode

What Changed with NavLink?

NavLink with NavLinkMatch.All now correctly handles query strings and fragments:

@* Both now correctly show as active *@
<NavLink href="/products" Match="NavLinkMatch.All">Products</NavLink>

@* Works with: *@
@* /products *@
@* /products?category=electronics *@
@* /products#featured *@
Enter fullscreen mode Exit fullscreen mode

Previous versions had inconsistent matching. Now it works as expected.

How Does Reconnection UI Work?

New templates include a customizable ReconnectModal component:

@* ReconnectModal.razor — included in templates *@
<div class="reconnect-modal" @attributes="AdditionalAttributes">
    <div class="reconnect-content">
        <p>Connection lost. Attempting to reconnect...</p>
        <button @onclick="Retry">Retry Now</button>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Key improvements:

  • No programmatic style insertion (CSP compliant)
  • Collocated stylesheet and JavaScript
  • Full customization control

What About Preloading?

Blazor WebAssembly preloading is enhanced:

<!-- In index.html -->
<link rel="preload" href="_framework/blazor.webassembly.js" as="script" />
Enter fullscreen mode Exit fullscreen mode

Combined with the smaller bundle size, initial load times improve significantly.

What's New for Blazor Server Specifically?

Circuit state persistence — The headline feature. Users survive disconnections.

Memory pool eviction — Automatic eviction of unused memory pools. Better resource management for long-running apps.

Improved diagnostics — Better error messages and debugging information.

What's New for Blazor WebAssembly?

Smaller runtime — Continued trimming improvements.

Faster startup — Preloading and compression improvements.

Better debugging — Enhanced source maps and debugging experience.

How Do I Upgrade to .NET 10?

<!-- Update TargetFramework in .csproj -->
<PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode
# Install .NET 10 SDK
dotnet --version  # Should show 10.0.x

# Update packages
dotnet restore
dotnet build
Enter fullscreen mode Exit fullscreen mode

Most Blazor apps upgrade without code changes. Test thoroughly — some edge cases may need adjustment.

Should I Use Blazor Server or WebAssembly?

.NET 10 improvements favor both:

Scenario Recommendation
Internal apps Server (simpler deployment)
Public-facing WebAssembly (better scalability)
Offline support WebAssembly (required)
Fast initial load Server (no WASM download)
Lower server costs WebAssembly (client-side compute)

Blazor United (hybrid rendering) works well for most scenarios.

Quick Reference: .NET 10 Blazor Features

Feature Description
[PersistentState] Persist component state across reconnections
Smaller bundle 76% reduction in blazor.web.js
Passkey auth WebAuthn/FIDO2 password-less login
Nested validation [ValidatableType] for complex forms
NotFound() Automatic 404 handling
JS property access Direct read/write without wrappers
RowClass QuickGrid conditional styling
NavLink fixes Correct query/fragment matching
ReconnectModal CSP-compliant reconnection UI

.NET 10 is an LTS release — three years of support through November 2028. Upgrade when ready.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)