Render modes no Blazor: qual escolher em cada cenário

Os render modes no Blazor definem onde cada componente executa e se ele responde às interações do usuário. Desde o .NET 8, a escolha deixou de ser feita no momento de criar o projeto e passou a ser feita por página ou por componente.
Por isso, a pergunta "Blazor Server ou Blazor WebAssembly?" perdeu o sentido original. Hoje, uma única aplicação pode combinar páginas estáticas, telas interativas no servidor e componentes que rodam no navegador.
Este artigo explica os quatro modos de renderização do Blazor Web App, o Blazor Hybrid e os critérios práticos para escolher cada um. Os exemplos usam o .NET 10, a versão LTS atual, e também citam o que muda com o .NET 11.
O que são render modes no Blazor
Todo componente de um Blazor Web App adota um modo de renderização. Esse modo determina o modelo de hospedagem, o local da renderização e a presença ou não de interatividade.
Interatividade, nesse contexto, significa reagir a eventos do DOM e a mudanças de estado ligadas a membros C#. Na prática, é o que faz um @onclick executar código e atualizar a tela.
A documentação oficial do ASP.NET Core lista quatro render modes no Blazor. A tabela a seguir resume cada um deles.
| Render mode | Onde executa | Interativo |
|---|---|---|
| Static Server (static SSR) | Servidor | Não |
| Interactive Server | Servidor, via SignalR | Sim |
| Interactive WebAssembly | Navegador, via WebAssembly | Sim |
| Interactive Auto | Servidor primeiro, depois navegador | Sim |
O Blazor Hybrid não aparece nessa lista porque não roda em um navegador. Ainda assim, ele faz parte da mesma decisão, e por isso ganha uma seção própria mais adiante.
Razor e Blazor não são a mesma coisa
Antes de seguir, vale separar dois termos que confundem quem chega ao .NET. Razor é a sintaxe de template que mistura HTML e C# em arquivos .razor e .cshtml.
Blazor, por sua vez, é o framework de UI que pega componentes Razor e os torna interativos. Ele faz isso no servidor, no navegador por meio do WebAssembly ou dentro de um app nativo.
Do modelo de projetos aos render modes no Blazor
Até o .NET 7, o desenvolvedor escolhia entre dois tipos de projeto: Blazor Server ou Blazor WebAssembly. Essa decisão acontecia antes da primeira linha de código e valia para a aplicação inteira.
Com o .NET 8, a Microsoft unificou tudo no template Blazor Web App. Assim, Server e WebAssembly passaram a ser render modes no Blazor aplicados a cada componente, e não mais tipos de projeto.
Essa mudança tem uma consequência direta. Caso a escolha inicial se mostre errada, basta editar uma diretiva, sem reconstruir o projeto.
Se você quer revisar como esse conceito surgiu, o artigo Blazor Render Modes do blog do balta.io mostra a chegada do recurso no .NET 8.
Um detalhe importante: aplicações Blazor WebAssembly standalone não têm o conceito de render mode. Nelas, todo o código já roda no cliente, então a diretiva não altera nada.
Como configurar render modes no Blazor
A configuração acontece em duas etapas. Primeiro, a aplicação habilita os modos interativos que pretende usar, e depois cada componente declara o seu.
Habilitando os modos no Program.cs
O template já gera esse código quando você seleciona as opções de interatividade. Esse trecho habilita Interactive Server, Interactive WebAssembly e, por consequência, Interactive Auto.
var builder = WebApplication.CreateBuilder(args);
// Registra os serviços dos componentes e dos dois runtimes interativos
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
var app = builder.Build();
// Mapeia o componente raiz e habilita os endpoints de cada modo
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode();
app.Run();
O método AddRazorComponents registra os serviços base. Em seguida, cada extensão adiciona o suporte a um runtime interativo.
Componentes que usam Interactive WebAssembly ou Interactive Auto precisam ficar em um projeto separado, cujo nome termina em .Client. Isso acontece porque esse projeto compila o pacote que o navegador baixa.
Aplicando o modo na página ou no componente
A diretiva @rendermode define o modo. Quando ela aparece na definição de uma página, vale para todas as instâncias daquele componente.
@page "/dashboard"
@rendermode InteractiveServer
<h1>Dashboard</h1>
Também é possível aplicar o modo em uma instância específica. Dessa forma, uma mesma página pode misturar componentes que rodam em lugares diferentes.
<WeatherPanel @rendermode="InteractiveServer" />
<SalesChart @rendermode="InteractiveWebAssembly" />
O template adiciona @using static Microsoft.AspNetCore.Components.Web.RenderMode ao arquivo _Imports.razor. Por isso, você escreve InteractiveServer em vez de RenderMode.InteractiveServer.
Para aplicar um modo à aplicação inteira, a documentação recomenda declarar o modo no componente Routes, dentro do App.razor. O componente HeadOutlet normalmente recebe o mesmo modo.
Pré-renderização e propagação
Os três modos interativos fazem pré-renderização por padrão. Ou seja, o servidor entrega o HTML inicial e o componente fica interativo quando o runtime correspondente termina de carregar.
O modo também se propaga para os filhos. Um componente sem diretiva herda o modo do pai, mas um filho não pode trocar para outro modo interativo diferente do pai.
Além disso, parâmetros enviados de um pai estático para um filho interativo precisam ser serializáveis em JSON. Na prática, isso impede passar RenderFragment ou conteúdo filho nesse cenário.
Static SSR: o padrão dos render modes no Blazor
O Static SSR gera HTML no servidor sem circuito, sem WebAssembly e sem tratamento de eventos. Ele também é o padrão entre os render modes no Blazor, porque vale para qualquer componente sem diretiva.
Esse modo atende páginas centradas em conteúdo, como landing pages, posts de blog, documentação e qualquer página que o Google precisa ler. Onde HTML puro resolve, ele custa menos e responde mais rápido que a interatividade.
Mesmo assim, a página estática pode ter uma ilha interativa. Para isso, basta aplicar @rendermode em um único componente filho, como no exemplo a seguir.
@page "/products"
@* A página é estática, mas o carrinho é interativo *@
<ProductCatalog />
<ShoppingCart @rendermode="InteractiveServer" />
Outra alternativa é adicionar comportamento no cliente com uma biblioteca como o htmx. Nesse caso, o servidor continua entregando HTML e o JavaScript cuida das trocas parciais.
Há, contudo, uma limitação conhecida. Durante o static SSR, recursos do roteador como o conteúdo de NotAuthorized não funcionam, porque o pipeline do ASP.NET Core processa a autorização antes da renderização.
O que muda no .NET 11
O .NET 11, previsto para novembro de 2026, amplia bastante o static SSR, o mais simples dos render modes no Blazor. Duas novidades fecham lacunas que antes empurravam o desenvolvedor para um modo interativo.
A primeira é a validação de formulários no navegador. Formulários estáticos com o componente DataAnnotationsValidator passam a mostrar erros sem ida ao servidor e sem baixar o WebAssembly.
@page "/signup"
<EditForm Model="Customer" FormName="signup" method="post">
@* Ativa a validação no cliente em páginas static SSR *@
<DataAnnotationsValidator />
<InputText @bind-Value="Customer.Email" />
<ValidationMessage For="() => Customer.Email" />
<button type="submit">Create account</button>
</EditForm>
@code {
[SupplyParameterFromForm]
private CustomerInput Customer { get; set; } = new();
}
O recurso vem ligado por padrão. Ainda assim, a validação no servidor continua obrigatória, porque o usuário pode desativar o JavaScript.
A segunda novidade é o QuickGrid com paginação e ordenação via query string. Os links passam a ter o formato ?page=2&sort=Name&direction=asc, então a grade funciona sem modo interativo.
Interactive Server
O Interactive Server renderiza o componente no servidor e mantém uma conexão SignalR em tempo real com o navegador. A documentação chama essa conexão de circuito.
Cada clique ou tecla viaja até o servidor. Lá, o C# executa, o Blazor calcula a diferença da interface e devolve apenas as alterações.
Os ganhos aparecem logo no primeiro acesso:
- O navegador baixa quase nada, então a interatividade começa imediatamente.
- O componente acessa banco de dados, segredos e serviços internos sem uma API no meio.
- A depuração segue o fluxo normal de uma aplicação no servidor.
Por outro lado, o modelo traz custos que crescem com o uso:
- Toda interação faz uma ida e volta pela rede, então a latência pesa em conexões lentas.
- O servidor guarda o estado de cada circuito ativo, e isso consome memória.
- Quando a conexão cai, a interface trava até reconectar, e não existe modo offline.
Entre os render modes no Blazor, escolha esse quando os usuários estão próximos do servidor. Sistemas internos, painéis administrativos e aplicações de linha de negócio se encaixam bem.
Interactive WebAssembly
O Interactive WebAssembly leva os render modes no Blazor para dentro do navegador. O runtime do .NET e o pacote da aplicação descem uma vez, ficam em cache e, depois disso, o C# roda no cliente.
Com isso, os eventos da interface não dependem mais do servidor. As vantagens principais são estas:
- As interações respondem na hora depois da carga, porque rodam localmente.
- A aplicação suporta uso offline, empacotamento como PWA e hospedagem estática em CDN.
- O servidor trabalha menos, já que o cliente assume o processamento.
Em contrapartida, o primeiro acesso cobra o download do runtime e uma inicialização a frio. Além disso, o desempenho fica limitado aos recursos do dispositivo do usuário.
Há também um ponto de segurança que não admite exceção. Nada que chega ao navegador é secreto, então strings de conexão, chaves de API e regras privilegiadas devem ficar atrás de uma API.
// Program.cs do projeto .Client: o navegador só conhece a URL da API
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped(sp => new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
await builder.Build().RunAsync();
Escolha esse modo quando você precisa de suporte offline, quer reduzir o custo de servidor ou publica uma aplicação com cara de app em uma CDN.
Interactive Auto: o meio-termo entre os render modes no Blazor
O Interactive Auto combina os dois modos anteriores. Na primeira visita, o componente roda com Interactive Server, então o usuário interage sem esperar nenhum download.
Enquanto isso, o runtime do WebAssembly desce em segundo plano e fica em cache. Nas visitas seguintes, o mesmo componente passa a rodar no navegador.
@page "/counter"
@rendermode InteractiveAuto
<button @onclick="Increment">Clicked @count times</button>
@code {
private int count;
// O mesmo código roda no servidor ou no navegador
private void Increment() => count++;
}
Entre os render modes no Blazor, esse é o que exige mais atenção ao comportamento. A decisão acontece quando o componente carrega, e ele mantém o modo escolhido enquanto continua na página.
Além disso, o Auto prefere o modo dos componentes interativos que já estão na página. A documentação explica que isso evita subir um segundo runtime que não compartilha estado com o primeiro.
Como o mesmo componente pode rodar nos dois lados, o código precisa funcionar em ambos. Portanto, dependências exclusivas do servidor, como um DbContext injetado direto no componente, ficam de fora.
// Contrato compartilhado entre servidor e cliente
public interface IOrderService
{
Task<IReadOnlyList<OrderSummary>> GetRecentAsync();
}
// No servidor: acesso direto ao banco
public sealed class ServerOrderService(AppDbContext db) : IOrderService
{
public async Task<IReadOnlyList<OrderSummary>> GetRecentAsync() =>
await db.Orders
.OrderByDescending(o => o.CreatedAt)
.Take(10)
.Select(o => new OrderSummary(o.Id, o.Total))
.ToListAsync();
}
// No navegador: chamada HTTP para a API
public sealed class ClientOrderService(HttpClient http) : IOrderService
{
public async Task<IReadOnlyList<OrderSummary>> GetRecentAsync() =>
await http.GetFromJsonAsync<List<OrderSummary>>("/api/orders/recent") ?? [];
}
Esse padrão registra uma implementação em cada projeto. Assim, o componente depende apenas da interface e funciona em qualquer lado.
Na prática, o Auto serve como padrão para aplicações gerais que querem uma primeira carga rápida sem abrir mão do WebAssembly depois.
Como escolher entre os render modes no Blazor
A escolha começa por duas perguntas: o produto roda no navegador e a página precisa de interatividade? Depois disso, a latência, o custo de servidor e a necessidade de uso offline decidem o resto.
A tabela abaixo resume a relação entre cenário e modo.
| Cenário | Modo indicado |
|---|---|
| Páginas de conteúdo voltadas a SEO | Static SSR |
| Sistema interno, usuários perto do servidor, acesso direto a dados | Interactive Server |
| Uso offline, PWA, hospedagem em CDN, baixo custo de servidor | Interactive WebAssembly |
| Primeira carga rápida e velocidade no cliente depois | Interactive Auto |
| App instalável de desktop ou celular feito com habilidades web | Blazor Hybrid |
Note que nenhuma linha exige escolher um modo para sempre. Afinal, cada página pode responder à tabela de forma diferente.
Combinando modos na mesma aplicação
Em um Blazor Web App, os render modes não se excluem. Uma mesma aplicação pode servir uma landing page estática, um painel administrativo com Interactive Server e um dashboard com Interactive Auto.
Para quem quer praticar essa combinação, o curso Fundamentos do Blazor com .NET 8 mostra Stream Rendering, render mode e Enhanced Navigation na prática.
Um cuidado ajuda bastante nesse desenho. A documentação recomenda que componentes reutilizáveis não dependam de um modo específico e degradem com elegância quando renderizados de forma estática.
@if (RendererInfo.IsInteractive)
{
<button @onclick="SaveAsync">Save</button>
}
else
{
@* Durante a pré-renderização, o botão fica desabilitado *@
<button disabled>Loading...</button>
}
Com esse tipo de verificação, o mesmo componente funciona em qualquer página, independentemente do modo que ela adota.
Conclusão sobre render modes no Blazor
Os render modes no Blazor transformaram uma decisão de projeto em uma decisão de componente. Por isso, a pergunta certa deixou de ser "Server ou WebAssembly?" e passou a ser "qual modo cada tela precisa?".
Em resumo, o Static SSR atende conteúdo e SEO, o Interactive Server atende sistemas internos e o Interactive WebAssembly atende cenários offline e de baixo custo. O Interactive Auto equilibra primeira carga e resposta no cliente, enquanto o Hybrid leva os componentes para apps nativos.
Comece pelo modo estático e adicione interatividade apenas onde ela faz diferença. Assim, a aplicação fica mais leve, mais barata de hospedar e mais simples de manter.
Com o .NET 11, essa recomendação ganha ainda mais força, porque formulários e grades passam a funcionar bem sem nenhum modo interativo.
FAQ
Qual é o render mode padrão de um componente Blazor?
O padrão é o Static SSR. Um componente sem @rendermode e sem pai interativo gera apenas HTML no servidor.
Posso usar modos diferentes na mesma página?
Sim, desde que os componentes sejam irmãos. Um filho, porém, não pode adotar um modo interativo diferente do pai.
O Interactive Auto troca de modo durante a navegação?
Não. Ele decide quando o componente carrega e mantém o mesmo modo enquanto o componente continua na página.
Por que meu componente WebAssembly precisa ficar no projeto .Client?
Porque esse projeto gera o pacote que o navegador baixa. Componentes fora dele não chegam ao cliente.
O Blazor Hybrid usa WebAssembly?
Não. Os componentes rodam no processo .NET do app nativo e aparecem na tela por meio do BlazorWebView.
Posso guardar uma chave de API em um componente WebAssembly?
Não. Todo código que chega ao navegador fica visível, então segredos devem ficar no servidor, atrás de uma API.