SEO para Astro

O Astro é um dos frameworks mais fortes para SEO — as páginas são pré-renderizadas em HTML estático por padrão e enviam JS apenas onde você pede, com Core Web Vitals fortes. Mas padrões não são garantias, e ele não escreve meta tags, sitemap ou canonicals por você. Veja como mantenho meu próprio site Astro e como acertar a arquitetura.

Publicado pela primeira vez: 26 de jun. de 2026 · Última atualização: 11 de ago. de 2026 · Avançado
Idiomas

O Astro é uma das escolhas de framework mais fortes para SEO porque pré-renderiza para HTML estático por padrão — seu conteúdo está no HTML bruto no primeiro rastreamento, sem uma fila de renderização para esperar nessa rota. A arquitetura de ilhas hidrata apenas os componentes que você marca com uma diretiva do cliente, então a maior parte da página é enviada sem seu próprio JS de hidratação (o Astro ainda pode adicionar scripts da página e JS do roteador em outros lugares) — nada disso garante rastreabilidade, indexação ou rankings por si só, portanto verifique as rotas publicadas. Sites Astro também apresentam números fortes de Core Web Vitals. O ponto negativo: o Astro gera HTML limpo, mas não escreve suas meta tags, canonicals, sitemap ou dados estruturados — essas são etapas deliberadas do build, e a descoberta do sitemap tem como alvo rotas geradas estaticamente, então URLs somente de runtime precisam de tratamento explícito. Server Islands (que exigem um adapter) e View Transitions são seguras para SEO quando você entende o que os rastreadores realmente buscam. Eu mantenho patrickstox.com no Astro, então esta é a stack que realmente uso.

TL;DR — O Astro é bem estruturado para SEO: páginas e endpoints são pré-renderizados em HTML estático por padrão, então não há uma onda da fila de renderização para esperar por esse conteúdo — mas isso é um padrão, não uma garantia universal, e o HTML estático/no servidor, por si só, não prova rastreabilidade, indexação, rankings ou Core Web Vitals das suas URLs em produção. A arquitetura de ilhas hidrata apenas os componentes que você marca com uma diretiva client:* — todo o restante envia HTML sem seu próprio JavaScript de hidratação, embora scripts da página, outras ilhas e aprimoramentos do roteador ainda possam adicionar JavaScript em outras partes da página. O Astro não gera automaticamente meta tags, canônicas, sitemaps ou dados estruturados — conecte tudo isso explicitamente, de preferência validado por Content Collections + Zod. Server Islands (que exigem um adapter) servem a casca estática com conteúdo de fallback no documento inicial e buscam o conteúdo adiado de forma independente depois — verifique o que cada rastreador realmente recupera, em vez de presumir. View Transitions usam history.pushState e são seguras para SEO; o Google rastreia as páginas MPA subjacentes normalmente. Eu mantenho patrickstox.com no Astro, e os recursos abaixo são os que realmente uso — validados contra o site publicado, não apenas no ambiente local.

Evidence for this claim Astro prerenders pages as static HTML by default and only sends client JavaScript for explicitly hydrated components. Scope: Astro default static output and islands architecture. Confidence: high · Verified: Astro: Why Astro

Por que o Astro contorna totalmente o problema de renderização de JavaScript

A razão principal de SEO para JavaScript ser difícil é a segunda onda. O Google busca primeiro seu HTML bruto e depois coloca a página em uma fila para renderização posterior em um Chromium headless — e essa fila é o risco. A própria documentação do Google descreve assim: “Googlebot queues all pages with a 200 HTTP status code for rendering unless a robots meta tag tells Google not to index the page. The page may stay on this queue for a few seconds, but it can take longer than that.” (tradução) «O Googlebot coloca todas as páginas com código de status HTTP 200 em uma fila para renderização, a menos que uma meta tag robots diga ao Google para não indexar a página. A página pode permanecer nessa fila por alguns segundos, mas isso pode demorar mais.» Em uma SPA renderizada no cliente, seu conteúdo não existe até essa onda de renderização acontecer.

O modo de saída padrão do Astro é estático: páginas e endpoints são pré-renderizados em um arquivo HTML completo no momento do build. Assim, para uma rota que usa esse padrão, o HTML bruto é a página renderizada. Evidence for this claim Astro uses static output and prerenders routes at build time by default. Scope: Astro default output mode; routes can opt out of prerendering. Confidence: high · Verified: Astro: On-demand rendering Não há uma segunda onda para esperar nessa rota, porque não resta nada para executar. O Googlebot vê todo o conteúdo na primeira busca. Como diz Joost de Valk (fundador do Yoast): “From an SEO perspective, static HTML on a CDN is a better starting point than most CMSes will ever give you.” (tradução) «Do ponto de vista de SEO, HTML estático em uma CDN é um ponto de partida melhor do que a maioria dos CMSs jamais oferecerá.»

Esse é o padrão, porém — não uma propriedade universal de todas as rotas. Defina output: 'server' e o padrão muda para a renderização sob demanda (mais sobre isso abaixo); mesmo em um projeto com padrão estático, um adapter permite que uma rota individual opte por sair dele com export const prerender = false. Nada disso é garantido apenas pela arquitetura: HTML estático ou no servidor, ilhas e adapters não garantem, por si só, rastreabilidade, indexação, rankings ou Core Web Vitals — isso depende da rota publicada e do rastreador específico, portanto verifique em vez de presumir que o framework resolve tudo.

Isso também ajuda com rastreadores que não conseguem renderizar. O Google observa claramente que “not all bots can run JavaScript” (tradução) «nem todos os bots conseguem executar JavaScript» — e essa é a realidade de 2026 para a maioria dos rastreadores de IA e muitas ferramentas de terceiros. A saída HTML-first do Astro é legível por todos eles onde realmente é pré-renderizada, não apenas pelo Googlebot. (Esse é o mesmo ponto que faço em SEO para um CMS headless: o modo de renderização é o produto.)

Arquitetura de ilhas: JS apenas onde você pede

O Astro renderiza seus componentes em HTML e, nas palavras dele, envia “just HTML & CSS, stripping out all client-side JavaScript automatically.” (tradução) «apenas HTML e CSS, removendo automaticamente todo o JavaScript do lado do cliente.» A interatividade é opcional. Você marca um componente com uma diretiva client:*client:load, client:idle ou client:visible — e apenas aquela ilha é hidratada com JavaScript. Todo o restante continua sendo HTML estático. Evidence for this claim Astro client directives selectively hydrate interactive islands while other components remain static HTML. Scope: Astro islands and client directives. Confidence: high · Verified: Astro: Islands

Para SEO, isso chega perto do ideal. O conteúdo que o Googlebot precisa indexar é HTML simples, e seus widgets interativos não o prejudicam. client:visible é especialmente útil: um componente abaixo da dobra nem começa a hidratar até entrar na área visível, então nunca bloqueia seu LCP. O conceito vem de Jason Miller (criador do Preact), que descreveu “rendering HTML pages on the server, and inject[ing] placeholders or slots around highly dynamic regions” (tradução) «renderizar páginas HTML no servidor e injetar placeholders ou slots ao redor de regiões altamente dinâmicas» para a hidratação seletiva.

Duas nuances merecem precisão, porque a cobertura dos concorrentes tende a misturá-las:

  • client:only é outra coisa. Diferentemente de client:load/client:idle/client:visible, um componente client:only ignora completamente a renderização no servidor — ele não produz HTML no servidor. Qualquer conteúdo indexável colocado apenas dentro de um componente client:only não está no documento que o Googlebot busca; só existe depois que o navegador o hidrata. Não coloque ali o conteúdo principal.
  • Isso é hidratação seletiva, não resumability. O Astro executa novamente o código do cliente de cada ilha do zero no navegador; ele não retoma o estado de execução serializado no servidor como faz um modelo de resumability (como o do Qwik, por exemplo). Os dois conceitos são confundidos em textos — não são o mesmo mecanismo.
Evidence for this claim A client:only component skips server rendering, so indexable content placed only inside it cannot be assumed to exist in the initial page HTML. Scope: client and server islands Confidence: high · Verified: Template directives reference

E um componente não hidratado não representa todo o cenário de JavaScript da página. “Zero JS” descreve um componente sem uma diretiva client:* — o Astro ainda pode enviar tags <script> no nível da página, o roteador de View Transitions e outras ilhas em outras partes da mesma página. Descreva o que é enviado por componente/rota, não como uma afirmação geral sobre a página.

O que o Astro NÃO faz automaticamente

O Astro gera HTML semântico limpo — e nada mais, do ponto de vista de SEO. Não há metadados, canonical, sitemap ou dados estruturados prontos. O mito de que “o Astro é automaticamente otimizado para SEO” é exatamente isso: um mito. Você é responsável por:

  • Meta tags (title, description, Open Graph, Twitter)
  • URLs canônicas
  • O sitemap (por meio da integração oficial)
  • Dados estruturados / JSON-LD
  • robots.txt

O Astro é a melhor fundação que já usei, mas é uma fundação, não uma casa pronta.

O sitemap: @astrojs/sitemap

Instale-o com npx astro add sitemap. Ele rastreia suas rotas geradas estaticamente e emite um sitemap-index.xml mais arquivos sitemap-0.xml divididos em partes durante o build. Duas coisas costumam pegar as pessoas: Evidence for this claim Astro's official sitemap integration generates sitemap files from statically generated routes. Scope: Astro @astrojs/sitemap integration. Confidence: high · Verified: Astro: Sitemap integration

  • Você precisa definir site: em astro.config.mjs. Sem isso, a integração não gera nada silenciosamente. Essa é a causa mais comum de “onde está meu sitemap?”.
  • Você precisa adicionar a linha do sitemap a robots.txt por conta própria. O Astro não faz isso.

Para ter controle, filter() exclui rotas (páginas de preview/draft — exatamente para isso que uso aqui), serialize() permite definir lastmod/changefreq/priority, e a opção i18n emite entradas hreflang no sitemap. É isso que a documentação atual de @astrojs/sitemap especifica — confirme na versão instalada se você estiver em uma versão mais antiga, pois o comportamento da integração já mudou entre versões principais.

O escopo que confunde as pessoas: a descoberta da integração tem como alvo rotas geradas estaticamente. Se alguma das suas URLs só existe em tempo de execução — rotas renderizadas no servidor (output: 'server') ou rotas geradas sob demanda, e não no build — não presuma que estejam no sitemap. Adicione-as explicitamente com customPages e depois abra de fato o sitemap-index.xml após um build para confirmar que estão lá. Não aceite que “a integração resolve isso” sem verificar algo que não seja uma rota estática de build.

Meta tags e canônicas: o padrão BaseLayout

O Astro não tem um componente especial <Head> — você controla <head> diretamente nos arquivos .astro. O padrão comum (e o que eu faço) é um único BaseLayout.astro que recebe title, description e canonicalURL como props e escreve o head. Defina a canonical explicitamente em cada página e mantenha-a consistente com og:url. Você não precisa de uma biblioteca, mas o pacote comunitário astro-seo (npm) é um wrapper conveniente de um componente para title/description/OG/Twitter/canonical, se quiser.

Content Collections como rede de segurança para SEO

Este é um recurso de SEO subestimado do Astro. Content Collections são uma camada de conteúdo com tipagem segura para Markdown/MDX/JSON, com validação de schema Zod. Isso permite tornar title e description campos obrigatórios — e, se uma página não tiver um deles, o build falha. Você não consegue publicar acidentalmente uma página sem título. As funções de consulta (getCollection(), getEntry()) geram páginas estáticas no build, então a saída é HTML simples quando publicada. E, como o MDX mantém o Markdown bruto como fonte de verdade, esses arquivos também são conteúdo-fonte limpo para rastreadores de IA e padrões no estilo do llms.txt. Este mesmo site é construído com Content Collections e frontmatter validado por Zod.

astro:assets: imagens feitas corretamente (com uma armadilha)

O componente <Image /> converte automaticamente para WebP, infere dimensões para “avoid Cumulative Layout Shift (CLS),” (tradução) «evitar Cumulative Layout Shift (CLS)», define loading="lazy" por padrão e exige alt — a ausência de alt é um erro de compilação. <Picture /> amplia isso com elementos <source> de fallback AVIF/WebP.

A armadilha: o loading="lazy" automático é errado para sua imagem LCP (geralmente o hero). Carregar a imagem mais importante de forma lazy atrasa seu carregamento. Para imagens acima da dobra, substitua por loading="eager" e fetchpriority="high". Imagens remotas precisam de width e height explícitos.

Server Islands: o que os rastreadores realmente veem

Server Islands (Astro 4.12+) são o recurso que a maioria dos guias concorrentes entende errado. Com server:defer, um componente é renderizado no servidor independentemente da página principal. A casca estática é servida imediatamente; conforme a documentação do Astro, “Your page will be rendered immediately with any specified fallback content as a placeholder. Then, the component’s own contents are fetched on the client and displayed when available.” (tradução) «Sua página será renderizada imediatamente com qualquer conteúdo de fallback especificado como placeholder. Depois, o próprio conteúdo do componente será buscado no cliente e exibido quando estiver disponível.»

Duas coisas precisam ser exatas. Primeiro, Server Islands exigem um adapter — são um recurso sob demanda, não algo que um build puramente estático produz sozinho. Segundo, a sequência é: o documento inicial envia o conteúdo de fallback que você configurou, e o conteúdo real da ilha é uma solicitação separada e independente, buscada depois que a página carrega, por seu próprio endpoint. Esse é o limite concreto do que o primeiro documento contém — eu não generalizaria além disso sobre o que cada rastreador específico fará em seguida sem testar diretamente suas URLs publicadas.

A consequência para SEO é concreta: o HTML estático que um rastreador lê na primeira busca contém seu conteúdo de fallback, não o conteúdo adiado da ilha. Isso é perfeito para o que Server Islands foram feitas para oferecer — dados personalizados e específicos da sessão (estado de login, contagem do carrinho, recomendações) que não deveriam ser armazenados em cache nem indexados. É errado para o conteúdo principal indexável. Coloque no template principal do Astro tudo o que precisa ranquear e deixe Server Islands cuidarem dos trechos dinâmicos ao redor.

Modos de saída: estático versus servidor e a substituição por rota

O modo de saída padrão do Astro é static — páginas e endpoints são pré-renderizados em HTML no build. Defina output: 'server' em astro.config.mjs e o padrão muda para renderização sob demanda: as páginas são renderizadas por solicitação (com um adapter), o que é útil para autenticação, dados em tempo real ou personalização além do que Server Islands cobrem. De qualquer forma, você pode substituir o padrão por rota: em um projeto com padrão estático, export const prerender = false opta uma rota pela renderização sob demanda; em um projeto com padrão de servidor, export const prerender = true coloca uma rota de volta na pré-renderização do build. Portanto, “meu site é estático” ou “meu site é SSR” raramente é verdade para todas as rotas — verifique a configuração por rota, não apenas a configuração de nível superior. Evidence for this claim Astro uses static output and prerenders routes at build time by default. Scope: Astro default output mode; routes can opt out of prerendering. Confidence: high · Verified: Astro: On-demand rendering

Do ponto de vista puramente de SEO, HTML pré-renderizado e HTML sob demanda são equivalentes — ambos entregam HTML completo à primeira solicitação de um rastreador, depois que você confirmou de fato que a rota retorna 200 com a marcação completa. Rotas sob demanda podem transmitir seu HTML em streaming, e dados ou condições de rede lentos podem atrasar trechos posteriores, então uma resposta em streaming não prova automaticamente que todo o conteúdo chegou — verifique, não presuma. A diferença real entre os modos é operacional: conteúdo pré-renderizado fica fixo até o próximo build (ou uma atualização em runtime configurada separadamente) e é servido diretamente da borda da CDN; conteúdo sob demanda está sempre atual, mas depende de seu adapter e runtime estarem saudáveis em produção. Não trate isso como uma decisão de SEO — escolha com base na atualidade dos dados e na operação, depois valide as rotas publicadas, status, redirecionamentos e cabeçalhos de resposta em vez de extrapolar o que funcionou no ambiente local.

View Transitions: seguras para SEO, apesar da aparência de SPA

O <ClientRouter /> do Astro (antes <ViewTransitions />) oferece navegação suave semelhante à de uma SPA usando a View Transitions API e a History API do navegador. O fato importante: ele navega com history.pushState, exatamente o que o Google recomenda para navegação no cliente — o Google alerta que URLs baseadas em fragmentos (#hash) são algo que ele “can’t reliably resolve.” (tradução) «não consegue resolver de forma confiável». O ponto crucial é que View Transitions são um aprimoramento no lado do navegador. Quando o Googlebot rastreia, ele solicita cada URL e recebe uma página HTML normal e completa — a MPA subjacente permanece intacta. As transições afetam apenas o que uma pessoa vê no navegador.

Portanto, não: View Transitions não transformam seu site Astro em uma SPA e não quebram o SEO. Uma lacuna que vale notar: a documentação de View Transitions do Astro não tem uma seção de SEO, provavelmente por isso o mito de que “quebra SEO” persiste. Para verificar seu próprio site, busque algumas URLs diretamente e confirme que cada uma retorna HTML completo — não aceite isso por fé, confira a sua publicação.

Erros comuns de SEO no Astro

  1. Presumir que o Astro cuida do seu SEO. Ele cuida do HTML. Meta tags, canônicas, sitemap e schema são responsabilidade sua.
  2. Esquecer site: na configuração — seu sitemap não é gerado silenciosamente.
  3. Não adicionar o sitemap ao robots.txt — o Astro não fará isso.
  4. Carregar a imagem LCP com lazy — substitua no hero por eager + fetchpriority.
  5. Colocar conteúdo indexável em uma Server Island — os rastreadores veem o fallback, não o conteúdo, e Server Islands exigem um adapter desde o início.
  6. Perseguir uma pontuação perfeita no Lighthouse e parar aí. Velocidade é um sinal de ranking, não o sinal de ranking. Uma página rápida e vazia não ranqueia — conteúdo, links e E-E-A-T ainda fazem o trabalho pesado.
  7. Colocar conteúdo indexável apenas dentro de um componente client:only. Diferentemente das outras diretivas client:*, client:only ignora completamente a renderização no servidor — não há HTML para esse componente até o navegador hidratá-lo.
  8. Tratar “o Astro é estático/rápido” como garantia de resultado. HTML estático ou sob demanda, ilhas e adapters são mecanismos — não garantem, por si só, rastreabilidade, indexação, rankings ou Core Web Vitals. Valide a rota publicada, não o diagrama da arquitetura.

Onde isso se encaixa no cluster

Astro é uma resposta específica e excepcionalmente amigável para SEO às perguntas que JavaScript SEO levanta sobre renderização, além de ser um frontend popular para configurações de CMS headless. A parte de desempenho se conecta diretamente aos Core Web Vitals no cluster de performance web, e a disciplina de testar “meu conteúdo realmente está no HTML?” é a mesma dos clusters de rastreamento e indexação.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.