Blazor upgrade do Framework CSS Bootstrap v5.1.0 para v5.3.3

Atualizar o Bootstrap no Blazor é uma tarefa simples, mas que exige atenção a alguns detalhes do template. Neste artigo, vamos fazer o upgrade do framework CSS Bootstrap da v5.1.0 para a v5.3.3, organizar os novos arquivos no projeto e, em seguida, identificar e ajustar as quebras no front-end.

Para uma compreensão mais sólida, primeiro vamos conceituar os dois tópicos centrais do artigo. Depois, partimos para a prática com um projeto criado do zero.

O que é Blazor

O Blazor é uma estrutura de desenvolvimento web da Microsoft que permite criar aplicativos interativos usando C#. Ele faz parte do ecossistema .NET e trabalha com componentes Razor.

Esses componentes podem rodar no servidor, com o ASP.NET Core, ou no navegador, sobre um runtime .NET baseado em WebAssembly. Se quiser se aprofundar no assunto, confira esta visão geral do Blazor.

O que é Bootstrap

O Bootstrap é um framework front-end de código aberto que facilita o desenvolvimento de sites e aplicativos responsivos. Além disso, ele fornece uma coleção de componentes CSS e JavaScript fáceis de integrar a qualquer interface.

Grids, botões, formulários, menus e modais são alguns exemplos do que o framework entrega pronto. Por isso, ele continua presente em boa parte dos projetos web, inclusive nos templates oficiais da Microsoft.

Por que usar Bootstrap no Blazor

Combinar Bootstrap no Blazor permite criar aplicativos modernos e responsivos com uma experiência de desenvolvimento mais eficiente. O Blazor cuida da lógica do aplicativo e da interação do usuário, enquanto o Bootstrap fornece os componentes visuais e o estilo.

Na prática, os templates do Blazor já trazem o Bootstrap embutido na pasta wwwroot. No entanto, a versão que acompanha o template nem sempre é a mais recente, e é justamente isso que vamos resolver.

Manter o framework atualizado traz correções de bugs, melhorias de acessibilidade e recursos novos, como o dark mode nativo. Além disso, a documentação oficial passa a corresponder exatamente ao que roda no seu projeto, o que evita confusão ao copiar exemplos.

Como o Bootstrap não depende do Blazor, o upgrade não exige mudanças no código C#. Ou seja, todo o trabalho acontece nos arquivos estáticos, nas referências do App.razor e em eventuais ajustes de classes CSS.

Criando a aplicação Blazor com Bootstrap

O template Blazor Web App fornece toda a estrutura necessária para o desenvolvimento web. Com ele, você cria interfaces interativas usando C# e já recebe o Bootstrap configurado.

Execute os comandos abaixo no terminal:

dotnet new blazor -int auto -o article-blazor-upgrade-bootstrap
cd article-blazor-upgrade-bootstrap

Entendendo os parâmetros do dotnet new blazor

Para começar, o parâmetro -int auto define o modo de interatividade do projeto como automático. Dessa forma, o projeto alterna entre a renderização no servidor e no cliente, dependendo do contexto.

Além disso, o parâmetro -o article-blazor-upgrade-bootstrap especifica o diretório de saída do novo projeto. Portanto, o CLI cria o projeto em uma pasta com esse nome.

Estrutura do projeto com o template Blazor Auto

Ao abrir o projeto no VS Code, você encontra dois projetos na solução.

Explorer do VS Code exibindo os projetos article-blazor-upgrade-bootstrap e article-blazor-upgrade-bootstrap.Client
O template com interatividade automática gera um projeto de servidor e um projeto cliente.

Inicialmente, o projeto principal é o article-blazor-upgrade-bootstrap, que representa o Blazor Server. Nele ficam as interfaces, componentes e códigos que executam e renderizam no lado do servidor.

Em seguida, temos o article-blazor-upgrade-bootstrap.Client, que corresponde ao Blazor WebAssembly. Nesse projeto ficam as interfaces, componentes e códigos que podem executar e renderizar no lado do cliente.

Como funciona o InteractiveAuto

Um aspecto relevante desse template, que já traz o Bootstrap no Blazor, é o modo InteractiveAuto. Ele adota uma abordagem híbrida de renderização, que podemos dividir em três etapas.

Primeiro, acontece a renderização inicial no servidor, quando a aplicação carrega pela primeira vez. Assim, a página aparece rapidamente para o usuário, mesmo antes do download dos recursos do Blazor WebAssembly.

Depois, vem a transição para o cliente. Enquanto a aplicação está em exibição, o navegador baixa o runtime .NET e os recursos necessários em segundo plano.

Por fim, ocorre a renderização no cliente. Depois que todos os recursos carregam, a aplicação passa a renderizar no navegador, o que torna a interação mais rápida porque a lógica roda localmente.

Essa abordagem combina o melhor dos dois mundos: a rapidez da renderização inicial no servidor e a interatividade da renderização no cliente. Para conhecer todas as opções, leia nosso artigo sobre render modes no Blazor.

Identificando a versão do Bootstrap no Blazor

Os arquivos estáticos ficam no projeto principal, o Blazor Server, dentro da pasta wwwroot. Ali, a pasta bootstrap guarda os arquivos CSS do framework.

Ao abrir o arquivo bootstrap.min.css, o cabeçalho mostra a versão em uso. Nesse template, encontramos a v5.1.0 do Bootstrap no Blazor.

Arquivo bootstrap.min.css aberto no VS Code mostrando a versão v5.1.0 do Bootstrap no Blazor
O comentário no topo do arquivo minificado indica a versão do framework.

Executando o projeto Blazor com o Bootstrap v5.1.0

Antes de qualquer mudança, vamos executar a aplicação para ter uma referência visual. Assim, fica fácil comparar o layout antes e depois do upgrade.

dotnet run
Página inicial da aplicação Blazor rodando com o Bootstrap v5.1.0
Página inicial do template antes da atualização.
Outra página do template com o menu lateral estilizado pelo Bootstrap no Blazor na v5.1.0
O menu lateral serve de referência para comparar com o resultado final.

O que muda no Bootstrap 5.3

Antes de trocar os arquivos do Bootstrap no Blazor, vale entender o que a versão 5.3 trouxe. A principal novidade é o suporte a color modes, com dark mode ativado pelo atributo data-bs-theme.

<html lang="en" data-bs-theme="dark">

Além disso, a versão ampliou o uso de variáveis CSS para cores de texto, fundo e temas. Por isso, componentes como alerts e list groups passam a responder automaticamente ao modo de cor.

A versão também trouxe novos utilitários de link, como controle de opacidade e de sublinhado, e o helper icon-link. Outro acréscimo é o helper focus-ring, que substitui o contorno padrão por um box-shadow customizável.

Algumas classes do Bootstrap que você usa no Blazor entraram em processo de descontinuação. Por exemplo, a .text-muted deu lugar à .text-body-secondary, então vale revisar o seu CSS depois do upgrade.

Por fim, a 5.3 adicionou a variante .nav-underline e o utilitário .d-inline-grid. A v5.3.3, que usamos aqui, é uma versão de correções dentro dessa mesma linha.

Upgrade do Bootstrap no Blazor para a v5.3.3

Agora vamos acessar o site oficial do Bootstrap e baixar os arquivos compilados. Em seguida, substituímos os arquivos antigos no projeto.

Página inicial do site getbootstrap.com com a versão 5.3.3 em destaque
O site oficial é o ponto de partida para baixar a nova versão.
Seção de download do Bootstrap com o pacote de CSS e JavaScript compilados
Baixe o pacote compilado, que já traz os arquivos minificados.

Copiando os novos arquivos para o wwwroot

Depois de descompactar o arquivo baixado, você encontra duas pastas: css e js. Vamos manter essa mesma estrutura no projeto, copiando as duas pastas para dentro de wwwroot\bootstrap\.

Pastas css e js do Bootstrap 5.3.3 copiadas para wwwroot/bootstrap no projeto Blazor
As pastas css e js mantêm a estrutura original do pacote baixado.

Agora podemos excluir os dois arquivos da v5.1.0 que estavam soltos na pasta wwwroot\bootstrap\. Ou seja, removemos o bootstrap.min.css antigo e o respectivo arquivo .map.

Exclusão dos arquivos antigos da v5.1.0 do Bootstrap no Blazor dentro da pasta wwwroot
Somente a nova estrutura de pastas permanece no projeto.

Ajustando o App.razor no .NET 8 e no .NET 9

No projeto Blazor Server, ajuste o arquivo App.razor para apontar para a v5.3.3. A mudança é pequena: basta incluir a pasta css no caminho, porque mantivemos a estrutura do pacote baixado.

Usando .NET 9:

<link rel="stylesheet" href="@Assets["bootstrap/css/bootstrap.min.css"]" />

Usando .NET 8:

<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />

A diferença entre as duas versões tem um motivo. No .NET 9, o MapStaticAssets passou a gerar fingerprint e compressão dos arquivos estáticos em tempo de build, e a propriedade Assets resolve a URL com esse fingerprint.

Com isso, o navegador nunca reaproveita uma versão antiga do CSS em cache depois do upgrade. A documentação de arquivos estáticos do Blazor detalha esse comportamento.

Arquivo App.razor com o link do Bootstrap no Blazor apontando para bootstrap/css/bootstrap.min.css
O link do stylesheet passa a incluir a pasta css.

Agora execute a aplicação novamente e observe o resultado com a v5.3.3.

Aplicação rodando com o Bootstrap 5.3.3 e o menu lateral sem o espaçamento correto
Depois da troca, o menu lateral perde parte do espaçamento.

Corrigindo o menu de navegação

Repare que o menu principal não ficou como na v5.1.0, porque perdeu as configurações de espaçamento. Para resolver, basta adicionar a classe nav na <div> que inicia a estrutura do menu, no arquivo NavMenu.razor.

Como estava:

<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">

Como ficou:

<div class="nav nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">

A classe nav aplica as regras de layout que os itens do menu do Blazor esperam na nova versão do Bootstrap. Então, execute o projeto mais uma vez para conferir.

Menu lateral corrigido com o Bootstrap no Blazor na v5.3.3, igual ao layout original
Com a classe nav, o menu volta ao visual da versão anterior.

Pronto, agora o menu ficou como na v5.1.0. Com isso, concluímos o upgrade para o Bootstrap v5.3.3.

Bônus: JavaScript do Bootstrap no Blazor

O template original só referencia o CSS do framework. No entanto, componentes como modal, dropdown e tooltip dependem do JavaScript do Bootstrap.

Por isso, vamos incorporar o arquivo JS do Bootstrap no Blazor Server. Adicione a instrução abaixo no arquivo App.razor.

Usando .NET 9:

<script src="@Assets["bootstrap/js/bootstrap.bundle.min.js"]"></script>

Usando .NET 8:

<script src="bootstrap/js/bootstrap.bundle.min.js"></script>

O arquivo bootstrap.bundle.min.js já inclui o Popper, biblioteca que posiciona dropdowns e tooltips. Assim, você não precisa referenciar nenhuma dependência adicional.

Testando o componente Modal

Para testar o JavaScript do Bootstrap no Blazor, copie o exemplo do controle Modal da documentação. Em seguida, cole o código no arquivo Home.razor.

Exemplo do componente Modal na documentação oficial do Bootstrap 5.3
A documentação oferece o markup pronto do modal.
Arquivo Home.razor com o markup do modal do Bootstrap no Blazor colado no componente
O markup do modal entra direto no componente da página inicial.

O markup segue o padrão da documentação, com um botão que abre o modal pelo atributo data-bs-toggle:

<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    Launch demo modal
</button>

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

Execute o projeto novamente e faça os testes com o modal adicionado.

Página inicial com o botão que abre o modal do Bootstrap
O botão do exemplo aparece na página inicial.
Modal do Bootstrap 5.3.3 aberto sobre a página da aplicação Blazor
Ao clicar no botão, o modal abre com a animação padrão do framework.

Fique à vontade para experimentar os demais controles do framework CSS Bootstrap v5.3.3. Por exemplo, vale testar o atributo data-bs-theme para ver o dark mode em ação.

Código fonte

O código completo deste exemplo está disponível no GitHub, no repositório jfs-dev/article-blazor-upgrade-bootstrap. Assim, você pode clonar o projeto e comparar cada etapa com a sua implementação.

Alternativas para gerenciar o Bootstrap no Blazor

Copiar os arquivos manualmente funciona bem e deixa o processo transparente. No entanto, existem outras formas de manter o Bootstrap no Blazor atualizado sem baixar pacotes a cada nova versão.

A primeira alternativa é o LibMan, gerenciador de bibliotecas client-side da Microsoft. Com ele, você declara a biblioteca e a versão em um arquivo libman.json, e a ferramenta baixa os arquivos para a pasta indicada:

dotnet tool install -g Microsoft.Web.LibraryManager.Cli
libman install bootstrap@5.3.3 --provider cdnjs --destination wwwroot/lib/bootstrap

Nesse caso, lembre de ajustar o caminho no App.razor para a nova pasta de destino. Assim, uma atualização futura exige apenas trocar o número da versão e rodar o comando de novo.

A segunda alternativa é referenciar o framework por uma CDN, como o jsDelivr indicado na documentação oficial do Bootstrap:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" />

Por outro lado, a CDN cria uma dependência externa e não participa do fingerprint do MapStaticAssets. Por isso, se optar por ela, copie também o atributo integrity que a documentação do Bootstrap fornece para cada arquivo.

Checklist depois do upgrade

Depois de atualizar o Bootstrap no Blazor, vale revisar alguns pontos antes de publicar. Primeiro, navegue por todas as páginas e compare o layout com a versão anterior, como fizemos com o menu.

Em seguida, procure no projeto por classes em descontinuação, como a .text-muted. Nesse caso, troque pela .text-body-secondary para evitar problemas em versões futuras.

Também confira se o CSS próprio da aplicação, como o app.css e os arquivos de CSS isolation, não sobrescreve regras que mudaram. Por fim, limpe o cache do navegador ao testar no .NET 8, porque nessa versão o arquivo não ganha fingerprint automático.

Conclusão sobre Bootstrap no Blazor

Atualizar o Bootstrap no Blazor envolve poucos passos: baixar o pacote, organizar as pastas, ajustar o App.razor e revisar as quebras visuais. Neste exemplo, a única quebra apareceu no menu, e a classe nav resolveu o problema.

Além disso, incluir o JavaScript do framework libera componentes interativos como o modal. Por fim, a v5.3 abre espaço para recursos como dark mode e variáveis CSS, que deixam o visual da aplicação mais flexível.

FAQ

Preciso atualizar o Bootstrap em projetos Blazor novos?

Depende da versão que o template traz. Abra o bootstrap.min.css em wwwroot e confira a versão no cabeçalho do arquivo.

Por que o menu quebrou depois do upgrade?

A estrutura do menu do template dependia de regras que, na v5.3.3, exigem a classe nav. Adicionar essa classe na div do NavMenu.razor resolve o espaçamento.

Qual a diferença entre usar Assets no .NET 9 e o caminho direto no .NET 8?

No .NET 9, a propriedade Assets resolve a URL com fingerprint gerada pelo MapStaticAssets. No .NET 8, o arquivo é referenciado pelo caminho relativo à pasta wwwroot.

Preciso incluir o JavaScript do Bootstrap?

Somente se você usar componentes interativos como modal, dropdown ou tooltip. Para estilos puros, o CSS é suficiente.

O Bootstrap 5.3 tem dark mode?

Sim, a versão 5.3 trouxe color modes com o atributo data-bs-theme. Basta definir o valor dark no elemento desejado.

Glossário

Termo Significado
Blazor Framework da Microsoft para criar interfaces web interativas com C# e componentes Razor.
Bootstrap Framework front-end de código aberto com componentes CSS e JavaScript responsivos.
InteractiveAuto Modo de renderização que começa no servidor e migra para o WebAssembly depois do download dos recursos.
wwwroot Pasta raiz dos arquivos estáticos públicos de um projeto ASP.NET Core.
App.razor Componente raiz do Blazor Web App, onde ficam os links de CSS e scripts.
MapStaticAssets Recurso do ASP.NET Core 9 que comprime e aplica fingerprint aos arquivos estáticos.
Fingerprint Hash adicionado ao nome do arquivo para invalidar o cache quando o conteúdo muda.
Color modes Recurso do Bootstrap 5.3 que permite alternar temas como claro e escuro.
Modal Componente de caixa de diálogo sobreposta à página.
Popper Biblioteca de posicionamento usada por dropdowns e tooltips do Bootstrap.

Fontes