Ir para o conteúdo
Acecore

Armadilhas e soluções do Astro View Transitions — Guia de melhoria de UX e qualidade de código

by Gui
Índice
Armadilhas e soluções do Astro View Transitions — Guia de melhoria de UX e qualidade de código

Introdução

O View Transitions (ClientRouter) do Astro é uma funcionalidade poderosa que torna as transições de página suaves como um SPA. No entanto, ao introduzi-lo, surgem problemas: o menu hamburger não abre, o botão de busca não responde, o slider para…

Neste artigo, apresentamos as armadilhas do View Transitions e suas soluções, além de técnicas práticas para melhorar UX e qualidade de código.


Problema de scripts do View Transitions

Por que os scripts param de funcionar

Em transições de página normais, o navegador re-parseia o HTML e executa todos os scripts. No entanto, o View Transitions atualiza a página por diferencial de DOM, fazendo com que scripts inline não sejam re-executados.

Os seguintes processos são afetados:

  • Abertura/fechamento do menu hamburger
  • Handler de clique do botão de busca
  • Slider de imagem hero
  • Seguimento de scroll do sumário
  • Padrão façade do embed YouTube

Padrão de solução

Unifique todos os scripts no padrão de encapsular em funções nomeadas e re-registrar com astro:after-swap.

<script>
  function initHeader() {
    const menuBtn = document.querySelector('[data-menu-toggle]')
    menuBtn?.addEventListener('click', () => { /* ... */ })
  }

  // Execução inicial
  initHeader()

  // Re-execução após View Transitions
  document.addEventListener('astro:after-swap', initHeader)
</script>

Diferença entre astro:after-swap e astro:page-load

  • astro:after-swap: Dispara imediatamente após a troca do DOM. Não dispara no carregamento inicial, então é necessário chamar a função diretamente
  • astro:page-load: Dispara tanto no carregamento inicial quanto após View Transitions. Permite omitir a chamada inicial

Para embeds do YouTube e funcionalidades que devem funcionar com certeza no carregamento inicial, astro:page-load é conveniente.


Introdução de busca full-text com Pagefind

Se você quer implementar busca full-text em um site estático, Pagefind é recomendado. Gera o índice no build e executa a busca no lado do navegador, sendo rápido e sem necessidade de servidor.

Configuração básica

{
  "scripts": {
    "build": "astro build && pagefind --site dist"
  }
}

Execute o Pagefind após o build do Astro para gerar o índice em dist/pagefind/.

Busca facetada

Com o atributo data-pagefind-filter, é possível filtrar por 3 eixos: autor, ano e tag.

<span data-pagefind-filter="author">gui</span>
<span data-pagefind-filter="year">2026</span>
<span data-pagefind-filter="tag">Astro</span>

Implemente um modal de busca que abre com o atalho Ctrl+K. Quando não há resultados, exiba links para a lista de artigos, página de serviços e contato para prevenir abandono do usuário.

Integração SearchAction

Ao definir o parâmetro ?q= nos dados estruturados SearchAction do Google, é possível transitar diretamente dos resultados de busca para a busca interna do site. Adicione processamento para detectar o parâmetro da URL e abrir automaticamente o modal de busca.

Configuração de cache

Os arquivos de índice do Pagefind têm baixa frequência de alteração, então habilite o cache nas configurações de cabeçalhos do Cloudflare Pages.

/pagefind/*
  Cache-Control: public, max-age=604800, stale-while-revalidate=86400

Eliminação de onclick inline

Escrever onclick="..." diretamente no HTML é fácil, mas causa a necessidade de unsafe-inline no CSP (Content Security Policy).

Padrão de melhoria

Substitua onclick por atributos data-* + addEventListener.

<!-- Antes -->
<button onclick="window.openSearch?.()">Buscar</button>

<!-- Depois -->
<button data-search-trigger>Buscar</button>
document.querySelectorAll('[data-search-trigger]').forEach(btn => {
  btn.addEventListener('click', () => window.openSearch?.())
})

Organização da biblioteca de componentes

Ter componentes disponíveis para usar ao escrever artigos de blog aumenta o poder de expressão dos artigos.

ComponenteUso
CalloutAnotações em 4 tipos: info / warning / tip / note
TimelineExibição cronológica de eventos
FAQPerguntas e respostas com suporte a dados estruturados
GalleryGaleria de imagens com Lightbox
CompareTableTabela comparativa antes/depois
ProcessFigureDiagrama de processo passo a passo
LinkCardCard de link externo estilo OGP
YouTubeEmbedCarregamento lazy com padrão façade

Todos foram projetados para serem chamados a partir do frontmatter do Markdown. Se data.callout existir no template do artigo, renderiza <Callout>.


Melhoria da segurança de tipos TypeScript

Eliminação de tipos any

Especifique tipos concretos como any[]CollectionEntry<'blog'>[]. O autocompletar do IDE e a detecção de erros em tempo de compilação passam a funcionar, tornando o acesso a propriedades nos templates seguro.

Tipos literais no schema de conteúdo

type: z.enum(['info', 'warning', 'tip', 'note']).default('info')

Ao definir valores do frontmatter com union de tipos literais, ramificações como if (callout.type === 'info') no lado do template se tornam type-safe.

Asserção as const

Ao adicionar as const a objetos constantes, as propriedades se tornam readonly e a inferência de tipos se torna literal. Sempre adicione à constante SITE.

Migração de imports descontinuados

Altere import { z } from 'astro:content', que será removido no Astro 7, para import { z } from 'astro/zod'.


Gerenciamento centralizado de constantes

Valores hardcoded causam esquecimentos ao alterar. Os seguintes valores foram centralizados em src/data/site.ts.

ConstanteNº de locais antes da centralização
AdSense Client ID4 arquivos
GA4 Measurement ID2 locais
IDs de slot de anúncio4 arquivos
URLs de redes sociais (X, GitHub, Discord, Aceserver)17 locais
Telefone, e-mail, LINE3 arquivos
export const SITE = {
  name: 'Acecore',
  url: 'https://acecore.net',
  ga4Id: 'G-XXXXXXXXXX',
  adsenseClientId: 'ca-pub-XXXXXXXXXXXXXXXX',
  social: {
    x: 'https://x.com/acecore',
    github: 'https://github.com/acecore-systems',
    discord: 'https://discord.gg/...',
  },
} as const

Outras melhorias de UX

Seguimento de scroll do sumário

Monitore os títulos do conteúdo com IntersectionObserver e destaque o título ativo no sumário da sidebar. O ponto-chave é também fazer scroll do próprio sumário com scrollIntoView({ block: 'nearest', behavior: 'smooth' }).

Scroll spy

Em estruturas de página única como a página de serviços, faça o item ativo da navegação seguir automaticamente com IntersectionObserver.

Paginação

Implemente divisão automática de página a cada 6 artigos, navegação com reticências (1 2 ... 9 10) e links de texto ”← Anterior” “Próximo →”. A lógica de paginação deve ser centralizada em src/utils/pagination.ts.

Com cabeçalho sticky, o destino do link âncora fica escondido atrás do cabeçalho. Resolva configurando o seguinte no preflight do UnoCSS.

[id] { scroll-margin-top: 5rem; }
html { scroll-behavior: smooth; }

Conclusão

Se usar View Transitions, o mais importante é unificar o padrão de inicialização dos scripts. Entenda a diferença entre astro:after-swap / astro:page-load e teste todas as interações.

Em termos de qualidade de código, a segurança de tipos TypeScript e o gerenciamento centralizado de constantes contribuem enormemente para a manutenibilidade a longo prazo. Pode parecer trabalhoso no início, mas o benefício do autocompletar do IDE é sentido diariamente no desenvolvimento.


Série que inclui este artigo

Este artigo faz parte da série “Guia de melhoria de qualidade do site Astro”. Melhorias de performance, SEO e acessibilidade também são apresentadas em artigos individuais.

Como conduzir melhorias de UX

Descoberta do problema

Listar mau funcionamento após introdução de View Transitions.

Unificação de padrões

Converter todos os scripts para um padrão de inicialização unificado.

Implementação de busca

Introduzir busca full-text com Pagefind e organizar a navegação.

Garantia de segurança de tipos

Eliminar any e centralizar constantes para melhorar a manutenibilidade.

Comparação antes e depois da melhoria

Antes da melhoria
  • Menu hamburger não funciona após transição de página
  • Sem busca interna no site
  • Tipos any e constantes hardcoded espalhados
  • onclick inline com risco de violação de CSP

Depois da melhoria
  • Todos os scripts funcionam normalmente com astro:after-swap
  • Busca full-text com Pagefind com 3 eixos de filtro
  • Segurança de tipos TypeScript e gerenciamento centralizado de constantes
  • addEventListener + atributos data em conformidade com CSP
Perguntas frequentes
Essas melhorias são válidas sem View Transitions?
As melhorias além do padrão de inicialização de scripts (Pagefind, TypeScript, gerenciamento de constantes) são válidas independentemente do uso de View Transitions.
Até que escala de site o Pagefind suporta?
O Pagefind foi projetado para sites estáticos e funciona rapidamente mesmo com milhares de páginas. O índice de busca é gerado no build e executado no lado do navegador, então não há carga no servidor.
Erros de tipo TypeScript podem ser ignorados e o código funciona?
Funciona, mas erros de tipo são indícios de bugs. Especialmente os schemas de conteúdo do Astro, ao serem type-safe, permitem autocompletar do IDE no acesso a propriedades dentro dos templates, melhorando significativamente a eficiência de desenvolvimento.
G

Gui

CEO da Acecore. Engenheiro versátil que trabalha com desenvolvimento de sistemas, produção web, operações de infraestrutura e educação em TI. Gosta de resolver desafios organizacionais e humanos por meio da tecnologia.

Desenvolvimento de sistemas Produção web Operações de infraestrutura Educação em TI

Quer saber mais sobre nossos serviços?

Oferecemos suporte abrangente em desenvolvimento de sistemas, design web, design gráfico e educação em TI.

Artigos relacionados

Pesquisar artigos