SEO & GEO

Por que o Google não indexa o meu site em React?

By Jake Luo · Published 7 de set. de 2026

Quase sempre porque a página que o rastreador recebe não é a que você vê. Um app React que renderiza no navegador serve um esqueleto HTML quase vazio e o preenche com JavaScript, e embora o Google execute esse JavaScript, ele faz isso numa passagem posterior, não no momento do rastreamento. Tudo o que é decidido na primeira passagem — se a página é duplicada, qual é a URL canônica, qual versão de idioma se aplica — é decidido em cima desse esqueleto. Então, antes de mudar qualquer coisa, leia o HTML bruto que o seu servidor realmente devolve, e não a página que o seu navegador desenha.

A página que o rastreador recebe não é a que você vê

Abra o seu site em produção e escolha ver código-fonte, não inspecionar. Inspecionar mostra o DOM depois que o seu JavaScript rodou; ver código-fonte mostra os bytes que o servidor de fato enviou. Num app React renderizado no cliente, esses bytes costumam ser um título, algumas tags link, um contêiner vazio e um bundle de scripts. É esse documento que um rastreador lê primeiro, e num site novo pode ser a única versão que alguém lê por um bom tempo.

O Google é explícito ao dizer que trata JavaScript em etapas separadas: rastreia a URL, coloca a página numa fila de renderização e indexa o que volta de lá — e essa renderização é adiada, não imediata. Daí saem duas consequências. A primeira é a óbvia: conteúdo que só existe depois que o bundle roda é indexado tarde, quando é indexado. A segunda faz mais estrago porque nunca se resolve sozinha. Alguns sinais são lidos apenas dessa primeira resposta, e nenhuma renderização posterior os recupera.

A tag canônica é o caso mais claro. A própria orientação do Google diz que o elemento canônico fica dentro do cabeçalho do documento, e o mesmo vale para as anotações hreflang que ligam as versões de idioma. Uma tag que o seu framework injeta depois — no corpo, ou quando o cabeçalho já foi enviado — é uma tag que não estava lá quando a decisão foi tomada. A página parece correta no navegador, porque o navegador aplica a tag de qualquer jeito. Ela só chega tarde demais para o único leitor cuja opinião você queria mudar.

Descubra o que o Google recebeu de verdade

Isso leva uns vinte minutos e encerra a dúvida antes de você reescrever qualquer coisa. Faça contra a URL em produção, não contra um preview.

  1. Leia a resposta bruta. Baixe a página com curl ou use ver código-fonte. Faça duas perguntas ao que voltar: o texto pelo qual você quer ranquear está aí, e a tag canônica está dentro do elemento head e não mais abaixo no documento? Se a resposta a qualquer uma for não, o problema já apareceu.
  2. No Search Console, leia a página rastreada e não o teste ao vivo. A inspeção de URL mostra as duas. O teste ao vivo é uma busca nova feita na hora; o HTML rastreado é o que ficou guardado da última vez. Quando os dois divergem, acredite na cópia rastreada — essa divergência já é a descoberta.
  3. Peça uma URL interna diretamente. Roteadores do lado do cliente podem produzir caminhos que o servidor não serve. Abra uma das suas páginas internas numa aba limpa, ou baixe com curl, e confirme que ela responde com o próprio conteúdo em vez de redirecionar para a home ou devolver uma página que diz que nada foi encontrado e ainda assim reporta sucesso.
  4. Confirme que você serve um host só, não três. Peça a forma com www, a forma sem www e a forma insegura do seu domínio. Duas das três deveriam redirecionar para a terceira. Se mais de uma serve o site inteiro, você publicou o mesmo site em dois endereços e pediu ao Google que escolhesse.

A falha que se escondeu dos nossos próprios testes

Publicamos o AgentCeres — o AI Growth Officer, em agentceres.com — sobre um framework React, e perdemos meses de indexação por uma versão desse problema que todas as nossas verificações classificavam como saudável. Vale contar por inteiro, porque cada parte falhou de um jeito que parecia sucesso.

O Search Console marcou um bloco grande das nossas páginas como duplicadas sem canônica escolhida pelo usuário, ou seja: não encontrou nenhuma canônica em que confiasse e escolheu uma por conta própria. A tag estava lá. Estava a uns quarenta kilobytes dentro da resposta, porque o framework envia os metadados em streaming em qualquer página que renderiza dinamicamente, enquanto o elemento head tinha fechado por volta de um kilobyte e meio a partir do topo. Todo navegador aplicava a tag. A primeira passagem de rastreamento nunca a viu.

O motivo de aquelas páginas serem dinâmicas foi a segunda falha. Uma dúzia de rotas que acreditávamos estar pré-renderizadas no build tinham parado de estar, sem aviso: um componente de cabeçalho compartilhado chamava um helper de tradução que lê cabeçalhos da requisição, e ler um cabeçalho da requisição já basta para tornar a página dinâmica. A tabela de rotas do próprio build continuava imprimindo todas como estáticas. O manifesto de arquivos HTML gerados não continha nenhuma. O resumo e o artefato se contradiziam, e nós vínhamos lendo o resumo.

A terceira parte é a que vale levar. Frameworks que enviam metadados em streaming costumam manter uma lista de rastreadores que recebem o comportamento bloqueante antigo, e o nosso trazia essa lista por padrão. O Googlebot não estava nela. A ferramenta de inspeção do Google — o rastreador por trás do botão de teste ao vivo — estava. Ou seja, o botão que apertávamos para conferir o nosso trabalho baixava a versão boa todas as vezes, enquanto os rastreamentos normais continuavam recebendo a quebrada. Se a sua ferramenta de verificação é um caso especial dentro do seu próprio stack, ela não é verificação.

Duas notas de rodapé, ambas baratas. O nosso host com www servia o site inteiro sem redirecionar, então o Google o tinha indexado como uma segunda cópia e rebaixado o endereço do nosso sitemap; foram duas linhas de middleware. E se a configuração por rastreador te tentar, lembre que uma CDN na frente da sua origem normalmente faz cache sem olhar quem pediu, então a variante que cair no cache é a que o próximo rastreador vai receber. Atrás de uma CDN, tratar um rastreador de forma especial não é uma regra em que dá para se apoiar.

O que mudar, na ordem que compensa

  • Pré-renderize as páginas que você quer que sejam encontradas. Páginas de marketing, documentação, qualquer coisa que um desconhecido possa buscar: gere o HTML no build. A saída estática contorna o problema inteiro, porque a primeira passagem já traz o conteúdo e as tags.
  • Renderize no servidor o que realmente precisa ser dinâmico. Uma página que depende da requisição também pode devolver HTML completo. O que importa é que a primeira resposta esteja completa, não que tenha sido calculada com antecedência.
  • Mantenha título, descrição, canônica e idioma no cabeçalho dessa primeira resposta. Se o seu framework pode adiá-los, ache a configuração que impede isso e confirme a correção lendo o HTML bruto, não o DOM renderizado. Este é o passo que as pessoas acham que já fizeram.
  • Dê a cada página uma URL real e um link real para ela. Rotas que vivem atrás de um fragmento ou de um manipulador de clique não são rastreáveis. Rastreadores seguem elementos âncora com href, então uma navegação feita de botões é uma navegação que o Google não consegue percorrer.
  • Escolha um host e redirecione os outros. Depois envie um sitemap que liste só a forma escolhida, para que as suas próprias declarações não se contradigam.

Nada disso é estratégia de posicionamento. É a pré-condição para ter uma, e vale resolver numa tarde justamente para nunca mais pensar no assunto. Quando as suas páginas passarem a ser realmente lidas, as perguntas que decidem se elas rendem algo são por que uma página perfeitamente boa continua sem tráfego e de onde vêm de fato os primeiros visitantes. E se você preferir não manter essa tubulação, um gerador de sites estáticos com um editor sobre Git evita a questão da renderização por construção, porque o que ele publica já é HTML pronto.

FAQ

O Google indexa sites feitos em JavaScript?
Sim. O Googlebot executa JavaScript e indexa aquilo em que a página se transforma, mas faz isso numa passagem adiada e não durante o rastreamento, então tudo o que só existe depois do seu bundle é indexado mais tarde e com menos confiabilidade do que o conteúdo que já está no HTML. As partes lidas apenas nessa primeira resposta — a tag canônica e as anotações hreflang entre elas — não são recuperadas pela renderização. Trate a renderização no cliente como um atraso somado a um risco, não como um bloqueio absoluto.
Preciso de renderização no servidor para resolver isso?
Normalmente não. A pré-renderização estática basta para as páginas que um desconhecido chegaria a buscar, e é mais simples e mais barata de operar do que renderizar no servidor. Reserve o servidor para páginas cujo conteúdo dependa mesmo de quem está perguntando. A regra que importa não é qual técnica você escolhe, e sim se a primeira resposta já está completa: uma página pré-renderizada e uma renderizada no servidor cumprem isso, e uma renderizada no cliente não.
O teste ao vivo do Search Console parece perfeito, então por que a página não é indexada?
Porque o teste ao vivo é uma busca e uma renderização feitas na hora, e o seu stack pode entregar a ele uma resposta diferente da que um rastreamento normal recebe — o nosso entregava, porque a lista padrão de rastreadores que recebem metadados bloqueantes incluía a ferramenta de inspeção do Google mas não o Googlebot. Leia no lugar o HTML rastreado e guardado no mesmo relatório. Quando os dois divergem, a cópia rastreada é a que está sendo indexada, e o teste ao vivo está te falando de uma página que não é servida a mais ninguém.
Related questions
Por que meu site não recebe tráfego?Como fazer SEO para um site completamente novo?Como consigo tráfego para um site que fiz com IA?Devo usar IA para criar meu site?

Want this done for you?

AgentCeres is a managed AI marketing team — specialists draft the work, you approve what ships. 14-day free trial, from $39/month.

Start free trialMore answers