Alternar tema

Astro View Transitions: 2 linhas de código para deixar seu site tão fluido quanto um app

Easton editorial illustration: build pipeline conveyor

Você passou um bom tempo criando um blog com Astro, cuidou do design e da diagramação, mas, ao clicar em um link, a página inteira pisca em branco antes de carregar a próxima. É como sair das animações fluidas de um iPhone e cair de repente nas transições rígidas do Windows 98.

No ano passado, eu estava criando um site para um amigo. Depois de ver o portfólio de outra pessoa, ele me perguntou: “Por que, quando clicamos em um projeto naquele site, a imagem aumenta com uma transição suave, enquanto o nosso apenas recarrega de forma brusca?” Fiquei um pouco sem graça e pensei: será que eu teria de reescrever tudo como uma SPA em React? Nesse caso, perderia as vantagens da geração estática do Astro.

Foi então que descobri a combinação da View Transitions API com Astro. Na primeira vez que usei, fiquei realmente impressionado: bastou adicionar 2 linhas de código ao <head> do componente Layout para a troca de páginas ganhar uma animação fluida. Sem React, sem Vue e sem sequer instalar uma biblioteca JavaScript.

Neste artigo, vou mostrar passo a passo:

  • O que é a View Transitions API e por que ela ganhou tanta popularidade em 2025, quando o suporte dos navegadores superou 85%
  • 3 maneiras de ativar transições de página no Astro, das 2 linhas mais simples à personalização avançada
  • Como implementar aparecimento e desaparecimento gradual, deslizamento, transformação de elementos e outros efeitos
  • Um exemplo prático completo de transição da lista de artigos para a página de detalhes
  • Problemas comuns e suas soluções — acredite, eu já passei por todos eles

Pronto para deixar seu site Astro com uma experiência tão fluida quanto a de um app? Vamos começar.

O que é a View Transitions API e por que ela é tão útil?

A “mágica” nativa do navegador, sem nenhuma biblioteca

A View Transitions API é um recurso nativo do navegador. Em termos simples, você avisa ao navegador: “Vou trocar o conteúdo.” Ele captura automaticamente duas “fotos”, uma da página antiga e outra da nova, e gera uma animação suave entre elas.

Parece abstrato? Imagine que a página inicial do seu blog tenha um artigo chamado “Tutorial de Astro”. Ao clicar nele, você acessa a página de detalhes. Na navegação tradicional, a página inicial desaparece → surge uma tela branca → a página de detalhes aparece. Com View Transitions, o navegador reconhece que o título da página inicial e o da página de detalhes são o “mesmo elemento”. Em seguida, move o título suavemente da posição na lista até o topo da página de detalhes, enquanto o restante do conteúdo aparece e desaparece gradualmente.

O melhor é que todas essas animações são geradas automaticamente pelo navegador. Você não precisa escrever animações CSS complexas nem adicionar bibliotecas como GSAP ou Framer Motion.

Por que é possível obter um efeito de SPA sem React ou Vue?

Quando se fala em animações de troca de página, muita gente pensa imediatamente: “Preciso usar React Router” ou “Vou precisar de Vue Router com o componente transition”. Mas essas soluções têm um problema em comum: são pesadas.

Para implementar transições de página em um framework SPA tradicional, é preciso:

  • Transformar toda a aplicação em uma página única, com todas as rotas controladas por JavaScript
  • Aumentar o bundle e tornar o carregamento inicial mais lento
  • Tratar o SEO separadamente, embora isso tenha melhorado bastante

A combinação Astro + View Transitions é mais elegante:

  • Mantém a arquitetura multipágina (MPA): cada página é um HTML independente e já favorece o SEO
  • Carrega sob demanda: traz apenas o JS e o CSS necessários para a página atual
  • Usa uma API nativa: tem custo de desempenho mínimo e não aumenta o tamanho do bundle
  • Aplica aprimoramento progressivo: navegadores sem suporte fazem fallback automático para a navegação comum, sem afetar a funcionalidade

Eu já testei as duas opções no mesmo site de blog. A versão React SPA ficou com mais de 300 KB após o build, enquanto a versão Astro ficou com cerca de 50 KB. E o tamanho praticamente não mudou depois de adicionar View Transitions.

85%+
Suporte dos navegadores
Suporte à View Transitions API em 2025
50 KB vs. 300 KB
Comparação do tamanho do bundle
A versão Astro é 6 vezes menor que a React SPA
2 linhas
Código de configuração
Adicione <ViewTransitions /> ao head do componente Layout

Suporte dos navegadores em 2025: já dá para usar com tranquilidade

Aqui vai uma boa notícia: em 2025, o suporte à View Transitions API nos navegadores já supera 85%.

Em detalhes:

  • Chrome 111+: oferece transições no mesmo documento, ao alternar estados dentro da mesma página
  • Chrome 126+: oferece transições entre documentos, ao navegar entre páginas diferentes — que é o caso usado no Astro
  • Safari: já oferece suporte
  • Edge: por ser baseado em Chromium, oferece suporte completo
  • Firefox 144+, lançado em outubro de 2025: View Transitions é um dos projetos prioritários do Interop 2025, e o Firefox finalmente acompanhou a evolução

Um detalhe interessante é que até a equipe do React integrou View Transitions ao núcleo da biblioteca em 2025, com suporte em react@canary. Isso mostra que a API já se tornou um recurso “padrão” no desenvolvimento frontend.

E o que acontece com os 15% de navegadores sem suporte? O Astro faz fallback automaticamente: nesses navegadores, a navegação ocorre normalmente. A funcionalidade não é afetada; apenas a animação deixa de aparecer. Essa é a grande vantagem do aprimoramento progressivo.

3 maneiras de ativar View Transitions no Astro

Agora que a teoria está clara, vamos à prática. Começarei pelo método mais simples, que você poderá usar assim que terminar a leitura.

Método 1: ativação global — recomendado, com apenas 2 linhas

Se você quer transições em todo o site, esta é a forma mais simples. Abra seu componente Layout, normalmente src/layouts/BaseLayout.astro ou src/layouts/Layout.astro, e adicione estas duas linhas ao <head>:


---

import { ViewTransitions } from 'astro:transitions';

---

<html>
  <head>
    <title>My Astro Site</title>
    <ViewTransitions />
  </head>
  <body>
    <slot />
  </body>
</html>

É só isso. Inicie o servidor de desenvolvimento com npm run dev e clique em qualquer link. Você verá que a troca de páginas passa a usar uma animação suave de aparecimento e desaparecimento.

Na primeira vez que usei, cheguei a pensar que fosse efeito do cache do navegador, porque o resultado apareceu com facilidade demais. Depois de recarregar várias vezes, confirmei: era realmente simples assim.

Quando usar: blogs, sites de documentação, portfólios e outros sites que precisam de transições em todas as páginas.

Método 2: ativação sob demanda — apenas em páginas específicas

Em alguns casos, você pode querer transições apenas em páginas específicas. Por exemplo, a página inicial e a página “Sobre” podem usar animações mais elaboradas, enquanto o painel administrativo não precisa delas. Nesse caso, adicione o componente ao <head> de uma página individual:


---

import { ClientRouter } from 'astro:transitions';

---

<html>
  <head>
    <title>About Page</title>
    <ClientRouter />
  </head>
  <body>
    <!-- Conteúdo da página -->
  </body>
</html>

Vale observar que ClientRouter é o novo nome; antes ele se chamava ViewTransitions. A equipe do Astro mudou o nome para descrever melhor sua função: ele não apenas cria transições visuais, mas também intercepta a navegação e transforma a MPA em uma “pseudo-SPA”. O nome antigo, porém, ainda funciona e não gera erro.

Quando usar: aplicações híbridas e sites em que apenas algumas páginas exigem tratamento especial.

Método 3: teste rápido sem alterar o código

Se você quer apenas experimentar o efeito sem mexer no código do projeto, pode usar o site de demonstração oficial do Astro:

👉 Demonstração de View Transitions

A demonstração inclui diferentes efeitos: transição da lista para a página de detalhes, galeria de imagens, player de música e outros. Recomendo experimentar primeiro, escolher o efeito de que você gosta e depois implementá-lo no projeto.

Dica: abra a demonstração em um navegador compatível com View Transitions, como Chrome 126+, Safari ou a versão mais recente do Firefox.

3 sinais de que tudo está funcionando

Depois de adicionar o código, como confirmar que View Transitions foi ativado? Observe estes sinais:

  1. A tela não pisca mais em branco durante a troca de página: ao clicar em um link, o conteúdo faz uma transição suave, sem o salto de “tela branca → página nova”
  2. Elementos compartilhados, como a barra de navegação, não são renderizados novamente: repare que ela não desaparece e reaparece, mas permanece no lugar — falaremos de transition:persist adiante
  3. Não há erros no console do navegador: se houver, talvez a versão do Astro seja antiga ou exista algum problema de configuração

Sinceramente, na primeira vez em que vi a barra de navegação parar de piscar, achei que meus olhos estivessem me enganando. Só depois de comparar com uma versão sem View Transitions tive certeza de que o recurso estava funcionando.

Personalize as animações de transição para combinar com sua marca

O efeito padrão de aparecimento e desaparecimento é simples, mas às vezes você pode querer uma animação com mais personalidade. Nesta seção, veremos 4 técnicas de personalização, do básico ao avançado.

Técnica 1: altere o tipo de animação com transition:animate

O Astro inclui 4 efeitos de animação que podem ser usados pela diretiva transition:animate. Por exemplo, para fazer o conteúdo do artigo deslizar da direita:

<article transition:animate="slide">
  <h1>Título do artigo</h1>
  <p>Conteúdo do artigo...</p>
</article>

As 4 animações integradas são:

  1. fade, padrão: aparecimento e desaparecimento gradual, a opção mais versátil
  2. slide: efeito de deslizamento, com o conteúdo entrando pela direita; funciona bem em páginas de detalhes
  3. initial: usa o estilo padrão do navegador, praticamente sem animação
  4. none: desativa totalmente a animação; útil em elementos que não devem ter transição

Minha combinação mais frequente é slide no conteúdo principal e fade na barra lateral, pois isso cria uma hierarquia visual melhor.

Você também pode ajustar a duração da animação. O Astro oferece as funções fade() e slide():


---

import { fade, slide } from 'astro:transitions';

---

<article transition:animate={slide({ duration: '0.5s' })}>
  <!-- O deslizamento dura 0,5 segundo -->
</article>

<aside transition:animate={fade({ duration: '0.2s' })}>
  <!-- O fade dura 0,2 segundo -->
</aside>

Técnica 2: transforme elementos com transition:name

Este é o recurso mais interessante. transition:name permite dizer ao navegador: “Estes elementos de duas páginas são, na verdade, a mesma coisa; crie uma animação de transformação entre eles.”

O exemplo clássico é a transição do título na lista de artigos para a página de detalhes.

Página da lista (index.astro):

<ul>
  <li>
    <a href="/posts/astro-guide">
      <h2 transition:name="post-title-astro-guide">Guia completo de Astro</h2>
    </a>
  </li>
</ul>

Página de detalhes (posts/astro-guide.astro):

<article>
  <h1 transition:name="post-title-astro-guide">Guia completo de Astro</h1>
  <p>Conteúdo do artigo...</p>
</article>

Percebeu? Os títulos das duas páginas usam transition:name="post-title-astro-guide". Assim, ao clicar no item da lista, o navegador move o título suavemente até o topo da página de detalhes, ajustando ao mesmo tempo o tamanho da fonte e a cor.

Observação importante: o valor de transition:name precisa ser único em cada página. Se houver vários artigos, use um valor dinâmico:

{posts.map(post => (
  <h2 transition:name={`post-title-${post.slug}`}>{post.title}</h2>
))}

Na primeira vez que usei esse recurso e vi o título “voar” até o topo da página de detalhes, tive a sensação de estar vendo uma espécie de “tecnologia secreta”.

Técnica 3: preserve o estado do elemento com transition:persist

Alguns elementos devem permanecer inalterados durante a troca de página, como:

  • Player de música, para não interromper a reprodução ao navegar
  • Barra de navegação, para evitar uma nova renderização
  • Ícone do carrinho, para manter a quantidade exibida

Nesse caso, use transition:persist:

<MusicPlayer client:load transition:persist />

Ao navegar para outra página, o componente MusicPlayer não é destruído e recriado; ele é simplesmente “movido” para a nova página. Seu estado interno, como o ponto atual da reprodução, é preservado por completo.

Uso avançado: combine com transition:persist-props.

Por padrão, transition:persist faz o componente ser renderizado novamente com as novas props durante a navegação. Se você não quiser atualizar nem mesmo as props — por exemplo, para impedir que o texto digitado na busca da barra de navegação seja apagado — adicione transition:persist-props:

<SearchBar
  client:load
  transition:persist
  transition:persist-props
/>

Já usei isso em um site de documentação, e o resultado foi muito bom: se o usuário tinha digitado metade de uma busca e clicava em um link, o texto continuava no campo. A experiência melhora bastante.

Técnica 4: controle as animações globalmente

Para definir uma animação padrão para a página inteira, configure o elemento <html>:

<html transition:animate="slide">
  <head>
    <ViewTransitions />
  </head>
  <body>
    <!-- Todo o conteúdo usa slide por padrão -->
  </body>
</html>

Depois, sobrescreva a animação nos elementos filhos quando necessário:

<nav transition:animate="fade">
  <!-- A barra de navegação usa fade separadamente -->
</nav>

<article>
  <!-- O artigo herda o slide -->
</article>

Esse controle em camadas é flexível e funciona bem em projetos grandes.

Exemplo prático: uma experiência completa de transição em um blog

Depois de toda a teoria e das técnicas, vamos montar um projeto prático completo: a transição da página inicial de um blog para a página de detalhes do artigo.

Cenário

Imagine que o blog tenha esta estrutura:

  • Página inicial: mostra uma lista de artigos, cada um com título, resumo e imagem de capa
  • Página de detalhes: mostra o artigo completo, com título, imagem de capa e conteúdo

Queremos alcançar os seguintes resultados:

  1. Ao clicar no título, ele se move suavemente até o topo da página de detalhes, com uma animação de transformação
  2. A imagem de capa também usa uma animação de transformação
  3. O restante do conteúdo aparece e desaparece gradualmente
  4. A barra de navegação preserva o estado e não é renderizada novamente

Etapa 1: ative View Transitions no Layout

Primeiro, adicione ViewTransitions ao arquivo src/layouts/BaseLayout.astro:


---

import { ViewTransitions } from 'astro:transitions';

interface Props {
  title: string;
}

const { title } = Astro.props;

---

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
    <ViewTransitions />
  </head>
  <body>
    <nav transition:persist transition:name="main-nav">
      <a href="/">Página inicial</a>
      <a href="/about">Sobre</a>
    </nav>
    <main>
      <slot />
    </main>
  </body>
</html>

Observe que a barra de navegação recebeu transition:persist e transition:name="main-nav", evitando que ela pisque durante a troca de página.

Etapa 2: adicione transition:name ao título e à capa na lista de artigos

No arquivo src/pages/index.astro:


---

import BaseLayout from '../layouts/BaseLayout.astro';

const posts = await Astro.glob('./posts/*.md');

---

<BaseLayout title="Meu blog">
  <h1>Artigos mais recentes</h1>
  <div class="post-list">
    {posts.map(post => (
      <article class="post-card">
        <a href={post.url}>
          <img
            src={post.frontmatter.cover}
            alt={post.frontmatter.title}
            transition:name={`cover-${post.frontmatter.slug}`}
          />
          <h2 transition:name={`title-${post.frontmatter.slug}`}>
            {post.frontmatter.title}
          </h2>
          <p>{post.frontmatter.excerpt}</p>
        </a>
      </article>
    ))}
  </div>
</BaseLayout>

Pontos principais:

  • A imagem de capa usa transition:name={'cover-${post.frontmatter.slug}'}
  • O título usa transition:name={'title-${post.frontmatter.slug}'}
  • O slug garante que o transition name de cada artigo seja único

Etapa 3: use o mesmo transition:name na página de detalhes

No template Markdown do artigo, normalmente src/layouts/PostLayout.astro:


---

import BaseLayout from './BaseLayout.astro';

const { frontmatter } = Astro.props;

---

<BaseLayout title={frontmatter.title}>
  <article class="post-detail">
    <img
      src={frontmatter.cover}
      alt={frontmatter.title}
      transition:name={`cover-${frontmatter.slug}`}
      class="cover-image"
    />
    <h1 transition:name={`title-${frontmatter.slug}`}>
      {frontmatter.title}
    </h1>
    <div class="post-meta">
      <time>{frontmatter.date}</time>
      <span>{frontmatter.author}</span>
    </div>
    <div class="post-content" transition:animate="slide">
      <slot />
    </div>
  </article>
</BaseLayout>

Observe:

  • O transition:name da capa e do título é igual ao da página da lista
  • O conteúdo do artigo usa transition:animate="slide" para adicionar o efeito de deslizamento

Etapa 4: adicione CSS para deixar o efeito mais fluido

Inclua o seguinte no Layout ou nos estilos globais:

/* Otimiza o desempenho da transição */
[transition:name] {
  will-change: transform;
}

/* Estilos da imagem de capa na lista e na página de detalhes */
.post-card img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
}

.post-detail .cover-image {
  width: 100%;
  max-height: 400px;
  object-fit: cover;
  border-radius: 12px;
}

/* Estilos do título */
.post-card h2 {
  font-size: 1.5rem;
  color: #333;
}

.post-detail h1 {
  font-size: 2.5rem;
  color: #111;
  margin-top: 1rem;
}

A linha will-change: transform é importante: ela avisa ao navegador que o elemento passará por uma transformação, permitindo que ele se prepare e faça otimizações.

Etapa 5: teste o resultado

Inicie o servidor de desenvolvimento:

npm run dev

Abra a página inicial e clique no título de qualquer artigo. Você verá:

  1. O título se move suavemente da posição na lista até o topo da página de detalhes, enquanto o tamanho da fonte muda
  2. A imagem de capa também se move e aumenta
  3. A barra de navegação permanece totalmente imóvel, sem piscar
  4. Os demais conteúdos, como resumo e data de publicação, aparecem gradualmente

Quando vi esse efeito pela primeira vez, tive aquela sensação de “era exatamente isso que eu queria”. Em comparação com a navegação tradicional, a experiência do usuário melhora muito.

Opcional: adicione um estado de carregamento

Se o conteúdo do artigo for grande, pode haver um atraso no carregamento. O Astro oferece hooks para representar esse estado:

<script>
  document.addEventListener('astro:before-preparation', () => {
    // Exibe a animação de carregamento
    document.body.classList.add('loading');
  });

  document.addEventListener('astro:page-load', () => {
    // Oculta a animação de carregamento
    document.body.classList.remove('loading');
  });
</script>

<style>
  body.loading::after {
    content: '';
    position: fixed;
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #3498db;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
</style>

Assim, um indicador giratório aparece durante o carregamento do conteúdo e completa melhor a experiência.

Técnicas avançadas e problemas comuns

Depois dos fundamentos e do exemplo prático, veremos algumas técnicas avançadas, além dos problemas que encontrei e de como resolvê-los.

Técnica avançada 1: respeite a preferência do usuário por movimento reduzido

Algumas pessoas podem ter distúrbios vestibulares, como enjoo provocado por movimento, ou simplesmente não gostar de animações. Elas podem ativar a opção “reduzir movimento” nas configurações do sistema. Como desenvolvedores, devemos respeitar essa escolha.

O Astro e o navegador fazem esse tratamento automaticamente, mas também é possível controlá-lo manualmente no CSS:

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Ou desative determinadas animações em um componente Astro:

<div transition:animate={
  typeof window !== 'undefined' &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches
    ? 'none'
    : 'slide'
}>
  Conteúdo
</div>

É um detalhe fácil de esquecer, mas realmente importante para parte dos usuários.

Técnica avançada 2: trate o ciclo de vida dos scripts

Em uma MPA tradicional, os scripts são executados novamente a cada navegação. Com View Transitions, a navegação se torna uma “pseudo-SPA”, e o comportamento dos scripts muda um pouco.

O Astro oferece alguns eventos de ciclo de vida:

// Página carregada, incluindo o primeiro carregamento e após uma navegação
document.addEventListener('astro:page-load', () => {
  console.log('O conteúdo da página foi atualizado');
  // Reinicialize componentes de UI, vincule eventos etc.
});

// A navegação está prestes a começar
document.addEventListener('astro:before-preparation', () => {
  console.log('A navegação para uma nova página está prestes a começar');
  // Limpe timers, cancele solicitações de rede etc.
});

// A navegação foi cancelada, por exemplo, quando o usuário clicou no botão Voltar
document.addEventListener('astro:after-swap', () => {
  console.log('O DOM foi atualizado, mas a animação ainda não terminou');
});

Problema comum: se você vinculou event listeners em um script, lembre-se de removê-los em astro:before-preparation; caso contrário, pode ocorrer vazamento de memória.

Já trabalhei em um projeto em que um listener de rolagem não era removido. Depois de algumas navegações, a página começava a travar. O problema só foi resolvido após adicionar a lógica de limpeza.

Técnica avançada 3: otimize o desempenho

Embora View Transitions tenha um custo pequeno, animações numerosas ou complexas ainda podem causar travamentos. Algumas recomendações:

  1. Limite a quantidade de elementos em transição ao mesmo tempo: não adicione transition:name a todos; use-o apenas nos elementos principais
  2. Use will-change: transform: avise ao navegador que ele pode se preparar para a mudança
  3. Evite provocar reflow durante a animação: não altere propriedades de layout, como width, height ou padding, durante a animação
  4. Teste em dispositivos reais: uma máquina de desenvolvimento rápida não garante que a experiência será fluida no dispositivo do usuário
/* Boa prática */
.animated-element {
  will-change: transform, opacity;
  transform: translateX(0);
}

/* Má prática */
.animated-element {
  width: 100px; /* Alterar width provoca reflow e prejudica o desempenho */
}

Problema comum 1: a animação não funciona

Sintoma: você adicionou transition:name, mas a página continua mudando de forma brusca, sem animação.

Possíveis causas e soluções:

  1. O transition:name não é único: verifique se há nomes duplicados na mesma página
  2. Os nomes das duas páginas não correspondem: confirme que a página da lista e a de detalhes usam o mesmo nome
  3. O navegador não oferece suporte: abra o Console do DevTools e procure erros
  4. A versão do Astro é muito antiga: atualize para Astro 3.0+, pois View Transitions foi introduzido na versão 3.0
# Verifique a versão do Astro
npx astro --version

# Atualize o Astro
npm install astro@latest

Problema comum 2: o elemento pisca ou salta

Sintoma: o elemento pisca ou muda de posição bruscamente durante a transição.

Possíveis causas e soluções:

  1. Estilos CSS inconsistentes: mantenha iguais os estilos básicos do elemento nas duas páginas, como display e position
  2. A imagem ainda não terminou de carregar: adicione loading="eager" à imagem ou defina uma altura fixa
  3. Ausência de transition:persist: adicione transition:persist aos elementos que precisam preservar o estado, como barra de navegação e player
<!-- Evita que a imagem pisque -->
<img
  src={cover}
  loading="eager"
  style="height: 200px"
  transition:name="cover"
/>

Problema comum 3: a direção da animação está errada ao voltar

Sintoma: a animação está correta ao avançar, mas, ao clicar no botão Voltar, ela ainda ocorre da direita para a esquerda.

Solução: o Astro trata automaticamente a direção das animações de avanço e retorno. Porém, se você usa uma animação personalizada, talvez precise fazer isso manualmente:

document.addEventListener('astro:before-preparation', (event) => {
  const isBack = event.direction === 'back';
  if (isBack) {
    // Ajusta a direção da animação
    document.documentElement.classList.add('reverse-animation');
  }
});
.reverse-animation [transition:animate="slide"] {
  animation-direction: reverse;
}

Problema comum 4: conflito com scripts de terceiros

Sintoma: depois de adicionar View Transitions, ferramentas de terceiros, como Google Analytics e scripts de publicidade, deixam de funcionar.

Causa: esses scripts normalmente são executados uma vez no carregamento da página. Como View Transitions “intercepta” a navegação, eles não percebem que a página mudou.

Solução: acione novamente os scripts de terceiros no evento astro:page-load:

document.addEventListener('astro:page-load', () => {
  // Google Analytics
  if (typeof gtag !== 'undefined') {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: window.location.pathname,
    });
  }

  // Facebook Pixel
  if (typeof fbq !== 'undefined') {
    fbq('track', 'PageView');
  }
});

Também encontrei esse problema: depois de adicionar View Transitions, percebi que as estatísticas do GA estavam incorretas. Só então entendi que era preciso disparar o evento manualmente.

Compatibilidade e aprimoramento progressivo

Por fim, vale reforçar: embora o suporte a View Transitions já supere 85%, ainda existem navegadores incompatíveis. A boa notícia é que o Astro faz fallback automaticamente. Nesses navegadores, a navegação ocorre normalmente e toda a funcionalidade continua disponível.

Para verificar manualmente se o navegador oferece suporte:

if (document.startViewTransition) {
  console.log('O navegador oferece suporte a View Transitions');
} else {
  console.log('O navegador não oferece suporte; o fallback foi aplicado automaticamente');
}

Essa é a vantagem do aprimoramento progressivo: navegadores modernos oferecem uma experiência fluida, mas os antigos continuam funcionando.

Conclusão

Depois de tudo isso, vale resumir:

View Transitions API + Astro = a solução mais simples para transições de página. Sem React, sem Vue e sem bibliotecas de terceiros: basta adicionar 2 linhas de código ao <head> do componente Layout para deixar seu site Astro com uma experiência tão fluida quanto a de um app.

Começamos pelo aparecimento e desaparecimento gradual, passamos pelo deslizamento personalizado e chegamos às animações de transformação e à preservação de estado. Passo a passo, transformamos um site multipágina de navegação brusca em uma aplicação web moderna e fluida. Melhor ainda: tudo isso é baseado em uma API nativa, tem custo de desempenho mínimo e faz fallback automático em navegadores antigos.

Se você quer testar agora, recomendo:

  1. Comece pelo método mais simples: adicione <ViewTransitions /> ao Layout e observe o efeito padrão
  2. Identifique o ponto que mais melhora a experiência: pode ser a barra de navegação sem piscar ou a transformação do título
  3. Personalize apenas quando necessário: use transition:animate e transition:name de acordo com a identidade do seu site
  4. Teste cenários reais: valide o resultado em diferentes navegadores e dispositivos

Sinceramente, hoje adiciono View Transitions logo no início de cada projeto novo. O recurso é muito simples, mas o resultado é surpreendentemente bom. Às vezes, uma boa experiência do usuário não exige código complexo; basta escolher a ferramenta certa.

Se você encontrar algum problema durante a implementação:

E, se você criar um efeito interessante com View Transitions, compartilhe o link do seu site nos comentários. Quero muito ver as ideias que todos conseguirão desenvolver.

Agora, abra seu projeto Astro e comece a deixar seu site mais fluido.

Processo completo de configuração do Astro View Transitions

Deixe seu site tão fluido quanto um app com 2 linhas de código, da configuração básica à personalização avançada, incluindo um exemplo prático completo

⏱️ Estimated time: 15 min

  1. 1

    Step 1: Entenda a View Transitions API e o suporte dos navegadores

    O que é a View Transitions API:
    • Um recurso nativo oferecido pelo navegador
    • Em termos simples, você diz ao navegador ‘vou trocar o conteúdo’
    • Ele captura automaticamente duas ‘fotos’, uma da página antiga e outra da nova
    • Depois, gera uma animação suave da imagem antiga para a nova
    • O melhor é que essas animações são geradas automaticamente pelo navegador
    • Você não precisa escrever animações CSS complexas nem adicionar bibliotecas como GSAP ou Framer Motion

    Mais de 85% de suporte nos navegadores em 2025:
    • Chrome 111+: transições no mesmo documento, ao alternar estados dentro da mesma página
    • Chrome 126+: transições entre documentos, ao navegar entre páginas diferentes, que é o caso usado no Astro
    • Safari: já oferece suporte
    • Edge: por ser baseado em Chromium, oferece suporte completo
    • Firefox 144+: oferece suporte, e View Transitions é um dos projetos prioritários do Interop 2025

    Um detalhe interessante é que até a equipe do React integrou View Transitions ao núcleo da biblioteca em 2025, com suporte em react@canary. Isso mostra que a API já se tornou um recurso padrão no desenvolvimento frontend.

    Tratamento de compatibilidade:
    • O Astro faz o fallback automaticamente
    • Em navegadores sem suporte, a navegação ocorre normalmente
    • A funcionalidade não é afetada; apenas não há animação
    • Essa é a grande vantagem do aprimoramento progressivo
  2. 2

    Step 2: Conheça as vantagens da combinação Astro + View Transitions

    Por que é possível criar um efeito de SPA sem React ou Vue:

    Problemas dos frameworks SPA tradicionais:
    • É preciso transformar toda a aplicação em uma página única
    • Todas as rotas passam a ser controladas por JavaScript
    • O bundle aumenta e o carregamento inicial fica mais lento
    • O SEO precisa de tratamento separado

    Vantagens da combinação Astro + View Transitions:
    • Mantém a arquitetura multipágina, ou MPA: cada página é um HTML independente e já favorece o SEO
    • Carregamento sob demanda: carrega apenas o JS e o CSS necessários para a página atual
    • API nativa: custo de desempenho mínimo e nenhum aumento no tamanho do bundle
    • Aprimoramento progressivo: navegadores sem suporte fazem fallback automático para a navegação comum, sem afetar a funcionalidade

    Comparação de desempenho:
    • Eu já testei as duas opções no mesmo site de blog
    • A versão React SPA ficou com mais de 300 KB após o build
    • A versão Astro ficou com cerca de 50 KB
    • E o tamanho praticamente não mudou depois de adicionar View Transitions
  3. 3

    Step 3: Use 3 formas de ativação, da mais simples à personalização avançada

    Método 1: a forma mais simples
    • Adicione <ViewTransitions /> ao <head> do componente Layout
    • São necessárias apenas 2 linhas de código
    • A troca de páginas passa imediatamente a usar uma transição suave
    • Não é preciso React, Vue nem sequer instalar uma biblioteca JavaScript

    Método 2: efeitos de transição personalizados
    • Use o atributo transition:animate para controlar o tipo de animação
    - fade: aparecimento e desaparecimento gradual
    - slide: deslizamento
    - none: sem animação
    • Use o atributo transition:name para nomear elementos
    • Assim, o navegador reconhece que o título da página inicial e o da página de detalhes são o ‘mesmo elemento’
    • Em seguida, move o título suavemente da posição na lista até o topo da página de detalhes

    Método 3: usos avançados
    • Animação de transformação de elementos: amplie suavemente uma miniatura da lista até a imagem grande da página de detalhes
    • Preservação de estado: mantenha a posição de rolagem, dados de formulário e outros estados durante a troca de página
    • Duração e função de easing personalizadas
  4. 4

    Step 4: Implemente um exemplo prático, da lista de artigos à página de detalhes

    Exemplo prático completo:

    Cenário:
    • Imagine que a página inicial do seu blog tenha um artigo chamado ‘Tutorial de Astro’
    • Ao clicar nele, você acessa a página de detalhes do artigo

    Navegação tradicional:
    • A página inicial desaparece → surge uma tela branca → a página de detalhes aparece

    Com View Transitions:
    • O navegador reconhece que os títulos da página inicial e da página de detalhes são o ‘mesmo elemento’
    • Depois, move o título suavemente da posição na lista até o topo da página de detalhes
    • Ao mesmo tempo, os demais conteúdos aparecem e desaparecem gradualmente

    Etapas de configuração:
    1. Adicione <ViewTransitions /> ao head do componente Layout
    2. Adicione o atributo transition:name ao título do artigo, por exemplo, transition:name="article-title"
    3. Opcional: use transition:animate="slide" para adicionar um efeito de deslizamento
    4. Teste o resultado em diferentes navegadores e dispositivos

    Resultado:
    • A barra de navegação não pisca
    • O título usa uma animação de transformação
    • As imagens fazem uma transição suave
    • A experiência deixa de ser uma troca brusca e passa a ser tão fluida quanto a de um app
  5. 5

    Step 5: Resolva problemas comuns e aplique boas práticas

    Problemas comuns: 1) a animação não funciona — verifique se o navegador é compatível e se há erros no console; 2) a transformação do elemento não parece natural — confirme que os valores de transition:name são iguais e que a estrutura dos elementos é semelhante; 3) problemas de desempenho — View Transitions é uma API nativa e tem custo mínimo, mas muitos elementos na página podem afetar o desempenho, por isso use-a apenas nos elementos principais. Boas práticas: comece pelo método mais simples, adicionando <ViewTransitions /> ao Layout e observando o efeito padrão; identifique o ponto que mais melhora a experiência, como a barra de navegação sem piscar ou a transformação do título; personalize apenas quando necessário, usando transition:animate e transition:name de acordo com a identidade do site; teste cenários reais em diferentes navegadores e dispositivos. Lembrete de compatibilidade: embora o suporte a View Transitions já supere 85%, ainda existem navegadores incompatíveis. O Astro faz fallback automático e usa a navegação comum nesses casos, mantendo toda a funcionalidade.

FAQ

O que é a View Transitions API e por que ela é tão útil?
A View Transitions API é um recurso nativo do navegador. Em termos simples, você avisa ao navegador que vai trocar o conteúdo; ele captura automaticamente duas ‘fotos’, uma da página antiga e outra da nova, e gera uma animação suave entre elas.

O melhor é que todas essas animações são geradas automaticamente pelo navegador. Você não precisa escrever animações CSS complexas nem adicionar bibliotecas como GSAP ou Framer Motion.

Por exemplo, imagine que a página inicial do seu blog tenha um artigo chamado ‘Tutorial de Astro’ e que um clique leve à página de detalhes.
• Na navegação tradicional: a página inicial desaparece → surge uma tela branca → a página de detalhes aparece
• Com View Transitions, o navegador reconhece que o título da página inicial e o da página de detalhes são o ‘mesmo elemento’
• Depois, move o título suavemente da posição na lista até o topo da página de detalhes, enquanto o restante do conteúdo aparece e desaparece gradualmente
Como está o suporte dos navegadores em 2025? Já posso usar com tranquilidade?
Em 2025, o suporte dos navegadores supera 85%:
• Chrome 111+ oferece transições no mesmo documento, ao alternar estados dentro da mesma página
• Chrome 126+ oferece transições entre documentos, ao navegar entre páginas diferentes, que é o caso usado no Astro
• Safari já oferece suporte
• Edge, por ser baseado em Chromium, oferece suporte completo
• Firefox 144+ também oferece suporte; View Transitions é um dos projetos prioritários do Interop 2025 e o Firefox finalmente acompanhou a evolução

Um detalhe interessante é que até a equipe do React integrou View Transitions ao núcleo da biblioteca em 2025, com suporte em react@canary. Isso mostra que a API já se tornou um recurso padrão no desenvolvimento frontend.

E o que acontece com os 15% de navegadores sem suporte? O Astro faz fallback automaticamente. Neles, a navegação ocorre normalmente, sem afetar a funcionalidade; apenas a animação deixa de aparecer. Essa é a vantagem do aprimoramento progressivo.
Por que é possível obter um efeito de SPA sem React ou Vue?
Para implementar transições de página em um framework SPA tradicional:
• É preciso transformar toda a aplicação em uma página única, com todas as rotas controladas por JavaScript
• O bundle aumenta e o carregamento inicial fica mais lento
• O SEO precisa de tratamento separado, embora isso tenha melhorado bastante

A combinação Astro + View Transitions é mais elegante:
• Mantém a arquitetura multipágina, ou MPA: cada página é um HTML independente e já favorece o SEO
• Usa carregamento sob demanda, trazendo apenas o JS e o CSS necessários para a página atual
• Usa uma API nativa, com custo de desempenho mínimo e sem aumento no tamanho do bundle
• Aplica aprimoramento progressivo: navegadores sem suporte fazem fallback automático para a navegação comum, sem afetar a funcionalidade

Eu já testei as duas opções no mesmo site de blog. A versão React SPA ficou com mais de 300 KB após o build, enquanto a versão Astro ficou com cerca de 50 KB. E o tamanho praticamente não mudou depois de adicionar View Transitions.
Como ativar View Transitions no Astro? Quantos métodos existem?
Método 1, a forma mais simples:
• Adicione <ViewTransitions /> ao <head> do componente Layout
• Com apenas 2 linhas de código, a troca de páginas passa imediatamente a usar uma transição suave
• Não é preciso React, Vue nem sequer instalar uma biblioteca JavaScript

Método 2, efeitos de transição personalizados:
• Use o atributo transition:animate para controlar o tipo de animação: fade para aparecimento e desaparecimento gradual, slide para deslizamento e none para nenhuma animação
• Use o atributo transition:name para nomear elementos e permitir que o navegador reconheça que o título da página inicial e o da página de detalhes são o ‘mesmo elemento’
• Assim, o título se move suavemente da posição na lista até o topo da página de detalhes

Método 3, usos avançados:
• Animação de transformação de elementos, como ampliar suavemente uma miniatura da lista até a imagem grande da página de detalhes
• Preservação de estado, mantendo a posição de rolagem, dados de formulário e outros estados durante a troca de página
• Duração e função de easing personalizadas
Como criar uma transição fluida da lista de artigos para a página de detalhes?
Exemplo prático completo: imagine que a página inicial do seu blog tenha um artigo chamado ‘Tutorial de Astro’ e que um clique leve à página de detalhes.
• Na navegação tradicional: a página inicial desaparece → surge uma tela branca → a página de detalhes aparece
• Com View Transitions, o navegador reconhece que o título da página inicial e o da página de detalhes são o ‘mesmo elemento’
• Depois, move o título suavemente da posição na lista até o topo da página de detalhes, enquanto o restante do conteúdo aparece e desaparece gradualmente

Etapas de configuração:
1) Adicione <ViewTransitions /> ao head do componente Layout
2) Adicione o atributo transition:name ao título do artigo, por exemplo, transition:name="article-title"
3) Opcional: use transition:animate="slide" para adicionar um efeito de deslizamento
4) Teste o resultado em diferentes navegadores e dispositivos

Resultado:
• A barra de navegação não pisca
• O título usa uma animação de transformação
• As imagens fazem uma transição suave
• A experiência deixa de ser uma troca brusca e passa a ser tão fluida quanto a de um app
Quais são os problemas comuns e as boas práticas ao usar View Transitions?
Problemas comuns:
1) A animação não funciona:
• Verifique se o navegador oferece suporte
• Confira se há erros no console

2) A transformação do elemento não parece natural:
• Confirme que os valores de transition:name são iguais
• Verifique se a estrutura dos elementos é semelhante

3) Problemas de desempenho:
• View Transitions é uma API nativa e tem custo de desempenho mínimo
• Porém, muitos elementos na página podem afetar o desempenho; use-a apenas nos elementos principais

Boas práticas:
• Comece pelo método mais simples: adicione <ViewTransitions /> ao Layout e observe o efeito padrão
• Identifique o ponto que mais melhora a experiência, como a barra de navegação sem piscar ou a transformação do título
• Personalize apenas quando necessário, usando transition:animate e transition:name de acordo com a identidade do site
• Teste cenários reais em diferentes navegadores e dispositivos

Lembrete de compatibilidade: embora o suporte a View Transitions já supere 85%, ainda existem navegadores incompatíveis. O Astro faz fallback automático e usa a navegação comum nesses casos, mantendo toda a funcionalidade. Se quiser verificar o suporte manualmente, use if (document.startViewTransition).

21 min de leitura · Publicado em: 2 dez 2025 · Atualizado em: 8 set 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog