< BACK Headless WordPress + Astro: Uma Configuração Funcional para Sites com Muito Conteúdo -- ilustração em arte linear

WordPress Headless + Astro: Uma Setup Funcional para Sites com Muito Conteúdo

Um cliente me ligou no início de 2023, um publisher de mídia rodando cerca de 14.000 posts no WordPress, um tema remendado entre quatro desenvolvedores ao longo de seis anos, e um Core Web Vitals que era genuinamente constrangedor. Seu LCP estava marcando 7.2 segundos em mobile. Eles já tinham tentado WP Rocket, tinham tentado um CDN, até tinham removido metade dos plugins. Ainda lento. O problema não era o WordPress em si. Era que cada render de página passava por PHP, um tema inchado, e uma sequência de queries de banco de dados que não era revisada desde 2018.

Ponto-chave: WordPress headless com Astro é o ponto ideal para sites de conteúdo: wp-admin para editores, front end estático-rápido para visitantes, e WPGraphQL conectando os dois.

Esse foi o momento em que me comprometi de verdade com uma setup headless usando Astro como frontend. Não porque é moda, mas porque para um site com milhares de posts e conteúdo editorial pesado, era a única arquitetura que fazia sentido.

Aqui está exatamente como configure tudo. Os tradeoffs, a config real, as partes que me prejudicaram.

---

Por que Astro e Não Next.js

Recebo essa pergunta com frequência. Next.js é a resposta óbvia se você já tem um time focado em React ou precisa de interatividade complexa no lado do cliente. Mas para sites com muito conteúdo? Astro vence, e não é nem um pouco perto.

Astro entrega zero JavaScript por padrão. Para um blog, um site de notícias ou um portal de documentação, esse é o padrão correto. Você opta por JavaScript onde precisa, em vez de optar por sair de um bundle React de 200kb que na maioria das vezes você não quer. A documentação do Astro sobre partial hydration, que chama de Islands architecture, explica melhor do que eu consigo em uma frase, mas resumindo: apenas as partes interativas ganham JS. O corpo do artigo, o header, a barra lateral? HTML estático.

Construí um site de conteúdo jurídico no final de 2022 com Next.js e WordPress. Rápido o suficiente, mas o cliente ficava perguntando por que o score do Lighthouse deles era 74 em mobile quando "era para ser rápido agora". Overhead de hidratação. Com Astro, esse mesmo tipo de site agora rotineiramente atinge 95-98. Não é exibicionismo, é só o que a arquitetura te dá de graça.

O Que Astro Não É Bom

Vale ser honesto. Se seu site precisa de personalização em tempo real, um carrinho de compras pesado, ou qualquer coisa que realmente dependa de estado no cliente entre muitos componentes, Astro começa a parecer desconfortável. Não é um app React. O padrão Islands é poderoso, mas é um modelo mental diferente do que construir SPAs. Tentei forçar um dashboard do cliente em um projeto Astro em meados de 2023 e acabei revertendo para Next.js em duas semanas. Saiba o que você está construindo.

---

Configurando WordPress como um CMS Headless

WordPress é genuinamente um bom backend headless. A WP REST API vem no core, é bem documentada, e seu time editorial não precisa aprender nada novo. Esse último ponto importa mais do que os desenvolvedores geralmente admitem.

Aqui está a configuração que uso:

  1. Instale WordPress em um subdomínio, eu uso cms.yourdomain.com ou api.yourdomain.com. Mantenha por trás de basic auth ou no mínimo restrinja tráfego público direto. O frontend é yourdomain.com. Dois deployments separados.
  2. Instale o [plugin WPGraphQL](https://www.wpgraphql.com/), eu prefiro GraphQL sobre REST para sites de conteúdo porque você pode colocar suas queries junto com seus componentes e buscar exatamente os campos que precisa. Sem over-fetching. A REST API é boa, mas quando você tem 15+ campos customizados por post type, a abordagem GraphQL é notavelmente mais limpa.
  3. Instale Advanced Custom Fields (ACF) e a extensão WPGraphQL for ACF. Essa combinação é o que torna WordPress genuinamente flexível como um modelo de conteúdo headless, você pode definir dados estruturados por post type, expô-los através de GraphQL, e Astro consome tudo de forma limpa.
  4. Desabilite comentários, emojis e o XML-RPC padrão se ainda não o fez. Eles adicionam sobrecarga e superfície de ataque que você não precisa.
  5. Configure os permalinks para algo sensato antes de começar a construir. Mudá-los no meio do projeto quando suas rotas do Astro já estão definidas é genuinamente incômodo.

Uma coisa que pega as pessoas: CORS. Por padrão, o WordPress não deixa seu servidor dev do Astro (rodando em localhost:4321) fazer requisições para sua instalação do WP. Coloque isso no functions.php do seu tema ou em um pequeno plugin utilitário durante o desenvolvimento:

`` add_action('init', function() { header("Access-Control-Allow-Origin: *"); }); ``

Aperte isso para origens específicas em produção. Obviamente.

---

A Estrutura do Projeto Astro

Mantenho isso opinado e consistente entre projetos. Depois de uma dúzia ou mais de builds headless, isso é o que funciona:

`` src/ components/ layouts/ pages/ index.astro blog/ [slug].astro lib/ wpgraphql.ts ← toda a lógica de query WP fica aqui styles/ ``

O arquivo lib/wpgraphql.ts é onde eu centralizo todo fetch de GraphQL. Sem chamadas fetch inline espalhadas por arquivos de página. Toda query é uma função async nomeada e exportada. Debugar isso em 14.000 posts quando algo quebra às 2 da manhã, você vai se agradecer depois.

Buscando Posts no Momento da Build

O getStaticPaths do Astro é seu pão com manteiga aqui. Para um blog com milhares de posts:

`` export async function getStaticPaths() { const posts = await getAllPostSlugs(); // chama WPGraphQL return posts.map(post => ({ params: { slug: post.slug }, })); } ``

getAllPostSlugs pagina através de WPGraphQL usando after cursors, a camada GraphQL do WordPress retorna 100 posts por request por padrão, então para 14.000 posts você está fazendo 140 requests em tempo de build. Isso parece assustador. Na prática, em um servidor decente, o build completo roda em cerca de 4-5 minutos. Perfeitamente aceitável para um site que reconstrói algumas vezes por dia.

---

Lidando com Imagens Sem Perder a Sanidade

Esse é o detalhe que ninguém fala o suficiente. O WordPress armazena URLs de imagens apontando para o subdomínio do seu CMS. Quando o Astro faz uma build estática, essas imagens continuam vivendo em cms.yourdomain.com, o que significa que os navegadores dos seus visitantes estão buscando imagens do seu servidor WordPress, potencialmente contornando seu CDN.

Algumas formas que lido com isso:

  • Cloudflare na frente de ambos os domínios. Opção mais simples. Faça proxy de yourdomain.com e cms.yourdomain.com através do Cloudflare, configure cache agressivo em /wp-content/uploads/*, e você está praticamente pronto.
  • Use um plugin de offload de mídia. Eu gosto do WP Offload Media, ele move uploads para S3 (ou storage compatível) e reescreve as URLs automaticamente. Essa é a abordagem que uso para qualquer site esperando tráfego sério. Seu servidor WordPress para de servir imagens completamente.
  • Astro's Image component. Para imagens que você controla no momento da build (imagens em destaque puxadas via GraphQL), você pode passar a URL remota para o componente <Image> do Astro e ele vai otimizar, redimensionar e servir a partir do seu output de build. Funciona brilhantemente. Não funciona para imagens embutidas no HTML do corpo do post, isso requer uma abordagem diferente.

Seahawk tinha um cliente de conteúdo de viagens no ano passado, cerca de 8.000 posts, extremamente pesado em imagens, média de 12 imagens por artigo. O servidor WordPress deles estava sendo martelado puramente por requisições de imagens mesmo com o setup headless. Mover para S3 + CloudFront reduziu a largura de banda de origem deles em 94%. Genuinamente transformador para a conta de hosting deles.

---

Builds Incrementais e o Problema do Rebuild

Aqui está um problema real com geração estática em escala: seu editor publica uma correção de post às 3 da tarde e tem que esperar 5 minutos por um rebuild completo. Isso não é aceitável em uma redação.

Algumas abordagens que usei:

Opção 1: Netlify ou Vercel com ISR sob demanda. Astro suporta renderização server-side com adapters, você pode rodar Astro em modo híbrido onde a maioria das páginas são estáticas mas rotas específicas são renderizadas sob demanda. Para um site de notícias, frequentemente vou fazer pré-renderização estática dos últimos 30 dias de posts (alto tráfego, precisa de velocidade) e configurar páginas de arquivo mais antigas para renderização server-side sob demanda. O melhor dos dois mundos.

Opção 2: Builds parciais disparadas por webhook. O WordPress dispara um webhook no save do post (fácil com o plugin WP Webhooks). Esse webhook bate em um hook de deploy do Netlify ou Vercel. A build executa, ela busca apenas o que mudou. Não é verdadeiramente parcial, Astro ainda reconstrói tudo, mas se você manter sua build rápida, 4 minutos é viável.

Opção 3: Apenas use SSR para tudo. Deploy do Astro com o adapter Node em uma VPS (eu uso Hetzner para isso, barato, rápido, confiável). Cada página renderiza na requisição, você faz cache agressivo no nível do Nginx ou Cloudflare, e você tem atualizações de post instantâneas. Isso é o que eu faria para uma operação de publicação adequada com mais de 50.000 posts.

Opinião honesta? A maioria dos sites não precisa da complexidade da Opção 1 ou 3. Um rebuild de 4 minutos acionado por webhook é ok para 90% dos sites de conteúdo.

---

Performance: O Que Você Realmente Consegue

No projeto do publisher da abertura, aqui está o que aconteceu depois da migração do Astro:

  • LCP caiu de 7.2s para 1.1s em mobile (testado com WebPageTest de um nó em Londres)
  • Total Blocking Time foi de ~800ms para 0ms (zero JS por padrão, lembre-se)
  • O relatório Core Web Vitals do Google Search Console deles foi de 3% de URLs "Good" para 91% "Good" em seis semanas após o deployment
  • Os custos de hosting caíram porque seu servidor WordPress não estava mais servindo páginas, apenas respostas de API

Nada disso é mágica. É só o que acontece quando você remove a renderização de PHP do caminho crítico e para de enviar um bundle JavaScript de tema de 400kb para cada leitor.

---

Os Detalhes Que Vão Te Confundir

Conversa real, coisas que tive que debugar em projetos reais:

  • Previsualizações de rascunhos. Isso é genuinamente chato em uma configuração headless. A prévia nativa do WordPress depende de renderização no front-end. Você precisa construir um endpoint customizado de prévia no Astro que aceite um nonce de prévia do WordPress e busque o rascunho via WPGraphQL. Não é difícil, mas leva um dia para fazer direito.
  • Redirecionamentos. Se o site antigo tinha centenas de redirecionamentos em .htaccess, eles agora vivem no servidor WordPress. Você precisa replicá-los na config do Astro, ou manter WordPress acessível e fazer proxy de caminhos específicos. Já fiz os dois. Replicar no Astro é mais limpo a longo prazo.
  • Busca. A busca integrada do WordPress é inútil em uma configuração headless. Eu uso Algolia com o plugin WP Search with Algolia. Indexe seus posts no WP, consulte o Algolia a partir de um componente Astro Island. Funciona bem.
  • Menus e navegação. Menus do WordPress são estranhamente complicados de expor através do WPGraphQL. A rota wpgraphql-acf frequentemente acaba sendo mais limpa, apenas modele sua nav como um repeater de ACF e pronto.

---

FAQ

Preciso de WPGraphQL ou posso apenas usar a REST API?

Você pode absolutamente usar a REST API, ela já vem integrada no WordPress core e não precisa de plugins extras. Para sites simples com tipos de post padrão e campos customizados mínimos, tudo bem. Onde GraphQL se destaca é quando você tem modelos de conteúdo complexos com muitos campos customizados por tipo. Conseguir buscar exatamente os campos que você precisa em uma única requisição, sem lidar com parâmetros _embed e chamadas REST aninhadas, economiza tempo a cada query que você escreve. Fica a seu critério. Eu só acho GraphQL mais limpo acima de um certo nível de complexidade.

Como faço para lidar com autenticação WordPress para conteúdo exclusivo de membros?

Autenticação JWT é a abordagem padrão. Instale o plugin JWT Authentication for WP REST API, emita tokens no login, passe-os nos headers da sua requisição GraphQL. No lado do Astro, você lidaria com isso usando uma rota SSR (não estática) para que o conteúdo específico do usuário seja buscado server-side a cada requisição. Não tente fazer isso de forma estática, esse caminho só leva à loucura.

Isso não é exagero para um blog pequeno?

Sim, provavelmente. Se você tem menos de 500 posts e um editor, o overhead de manter uma configuração headless não vale a pena. Basta usar um bom tema WordPress, otimizar suas imagens e seguir com a vida. Essa arquitetura compensa quando você tem volume, complexidade editorial ou níveis de tráfego onde a performance realmente impacta a receita.

Como é a configuração de hospedagem em produção?

WordPress (apenas CMS) em uma VPS pequena ou host WordPress gerenciado, eu uso Kinsta ou Cloudways. Frontend Astro no Vercel, Netlify ou uma VPS Hetzner com Nginx dependendo do projeto. Cloudflare na frente de tudo. O custo mensal total para um site de conteúdo médio geralmente fica entre £60-£120, o que muitas vezes é menos do que os clientes pagavam em um host WordPress all-in-one que não conseguia lidar com a carga.

---

O resumo honesto é este: WordPress headless com Astro é uma das melhores coisas que aconteceram para sites de conteúdo em um tempo. Não porque é novo, mas porque o tooling finalmente alcançou a ideia. WPGraphQL é estável, o sistema de build do Astro é rápido, e os ganhos de performance são reais e mensuráveis.

Acerte a arquitetura no início, especialmente sua estratégia de imagens e sua abordagem de rebuild, e você vai gastar muito menos tempo apagando incêndios depois. É realmente só isso.

< BACK