CategoriaConteúdo e busca

SEO multilíngue em Astro: declarar versões e regiões

8 minutos de leitura

Um site multilíngue tem uma tarefa antes de qualquer outra: dizer ao buscador que as URLs em inglês, português e espanhol são a mesma página em três idiomas. Sem essa declaração, cada tradução vira um documento separado disputando a mesma consulta.

Por que a relação entre as versões vem antes da tradução

O Google Search Central afirma em versões localizadas da página que o hreflang existe para o buscador entender que as páginas são variações localizadas do mesmo conteúdo.

Sem a anotação, o buscador vê três URLs com sentido parecido e nenhuma relação declarada. Cada uma passa a ser candidata para a mesma consulta.

Isso não gera punição. O que acontece é que o buscador escolhe por você, e a escolha costuma favorecer a versão com sinais mais fortes, não a versão de que o leitor precisa.

Idioma, região e alternativa são três declarações diferentes

A maioria dos sites mistura as três coisas, e é aí que o erro começa.

  • A declaração de idioma é o atributo lang no elemento html. O padrão HTML (em inglês) o define como o idioma do conteúdo do elemento, e ele não diz nada sobre as outras versões.
  • A declaração de região é a segunda metade de um código como pt-BR, escrito no formato ISO 3166-1 Alpha 2 (versões localizadas da página). Um código como pt sozinho nomeia o idioma e nenhuma região.
  • A declaração de alternativa é rel="alternate" hreflang, que liga uma URL a outra. Ela é a única das três que descreve uma relação entre documentos.

A documentação de i18n do Astro (em inglês) usa uma chave de locale como pt-br para nomear a pasta da rota. A opção i18n (em inglês) do @astrojs/sitemap converte essa chave em atributo de idioma. A chave nomeia o endereço, o atributo nomeia o idioma, e os dois não precisam ser iguais.

Como o hreflang é escrito e o que a reciprocidade exige

O Google documenta três formas de publicar a anotação: elementos de link no head, cabeçalhos HTTP de resposta e o sitemap.

A forma no head é esta:

<link rel="alternate" hreflang="en" href="https://www.example.com/blog/post/" />
<link rel="alternate" hreflang="pt-BR" href="https://www.example.com/pt-br/blog/post/" />
<link rel="alternate" hreflang="es" href="https://www.example.com/es/blog/post/" />
<link rel="alternate" hreflang="x-default" href="https://www.example.com/blog/post/" />

Duas regras vêm junto, e o Google declara as duas como diretrizes de todos os métodos.

  • Cada versão de idioma precisa listar a si mesma e também todas as outras versões.
  • As URLs alternativas precisam ser completas, incluindo o método de transporte.

O que mais costuma faltar é a página apontar para si mesma. Uma página em português que lista inglês e espanhol mas não a si mesma deixa o conjunto incompleto, e o buscador pode descartar o grupo. O Google afirma que tags que não apontam uma para a outra são ignoradas.

O valor x-default marca a página para quem fala um idioma fora da lista. O Google cita seletores de idioma e páginas iniciais com redirecionamento automático como o caso de uso.

O que o sitemap acrescenta à anotação

O sitemap carrega a mesma relação em XML, com entradas xhtml:link que listam cada variante, inclusive a própria página (versões localizadas da página).

<url>
  <loc>https://www.example.com/pt-br/blog/post/</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://www.example.com/blog/post/" />
  <xhtml:link rel="alternate" hreflang="pt-BR" href="https://www.example.com/pt-br/blog/post/" />
  <xhtml:link rel="alternate" hreflang="es" href="https://www.example.com/es/blog/post/" />
</url>

O protocolo do sitemap exige a declaração de namespace no urlset, escape de entidades em todo valor e codificação UTF-8.

A documentação de sitemap do Google impõe um limite ao lastmod: o valor só é usado quando é consistente e verificavelmente exato. O Google ignora priority e changefreq.

Em um blog, o lastmod correto por idioma é a data do frontmatter daquele idioma. Carimbar a data do build em toda URL ensina o buscador a ignorar o campo.

O hreflang órfão e como pegá-lo no build

O defeito mais comum é uma URL alternativa que devolve 404. Ele aparece quando o slug muda em um idioma, quando uma tradução é removida ou quando o caminho é escrito à mão.

A página com a tag continua válida, então o relatório dela não muda nada. O grupo só perde um integrante.

Essa conferência deve acontecer no build. Depois que o site compila, leia o HTML gerado, recolha cada href de hreflang e confirme que cada caminho existe como pasta com um index.html.

O script é curto, e ele reprova o build quando uma alternativa aponta para um arquivo que nunca foi gerado.

O que fazer quando a tradução não existe

Existem três opções, e só uma delas é gratuita.

  • Publique a anotação apenas para as versões que existem. As versões que você nunca escreveu não são versões.
  • Evite o redirecionamento automático para o inglês. O guia do Google pede um seletor de idioma no lugar de um redirecionamento baseado no visitante.
  • Entregue uma tradução real ou não entregue nada. O mesmo guia alerta contra tradução de texto padrão e pede indicação clara de idioma na página.

Uma página traduzida por máquina com o mesmo slug é uma duplicata em um idioma novo, e a anotação não conserta isso.

O que o hreflang não resolve

A anotação é uma afirmação sobre relação. Ela não é sinal de ranqueamento, e não é detector de idioma.

  • O Google afirma que não usa hreflang nem o atributo lang do html para detectar o idioma de uma página, e usa algoritmos em vez disso.
  • Conteúdo duplicado de verdade continua duplicado. Quando duas URLs têm o mesmo texto no mesmo idioma, o guia do Google pede uma versão preferida com rel="canonical", junto com o hreflang.
  • Tradução fraca continua fraca. A anotação decide qual versão é mostrada, não o quanto essa versão casa com a consulta.
  • Páginas espelhadas custam manutenção. Cada idioma é uma página para construir, revisar e atualizar, e um site sem responsável por idioma sai de sincronia.

O Google descreve o hreflang como uma forma de relatar variações para que o buscador as entenda. A promessa é só essa: entender.

Onde a pesquisa diverge da documentação

A primeira divergência é sobre o seletor de idioma. O Nielsen Norman Group recomenda detectar país e idioma pelas preferências do navegador, para o visitante nunca abrir o seletor (NN/g, 6 Tips for Improving Language Switchers on Ecommerce Sites (em inglês)).

O guia do Google pede o oposto, um link visível para as outras versões (sites multirregionais e multilíngues). Ele avisa que o redirecionamento automático esconde versões do rastreador.

As duas posições não são simétricas. O Google lê o rastreador, que não envia cabeçalho Accept-Language e costuma partir dos Estados Unidos. O NN/g lê o visitante, que é interrompido por uma escolha que o navegador já sabe.

A segunda divergência é sobre tradução. O NN/g aceita tradução por máquina com rótulo visível e o original ao lado (NN/g, Translate User-Generated Content for Global Audiences (em inglês)).

O Google alerta contra traduzir só o texto padrão e manter o corpo do conteúdo em um idioma (o mesmo guia). A regra deste post fica mais perto do Google: tradução real ou nada.

O NN/g mostra o caso em que uma tradução por máquina rotulada vence uma seção de avaliações vazia. Esse é um meio caminho real, e ele não desculpa uma página com o mesmo slug em outro idioma.

A terceira divergência é de escopo. O NN/g encontrou falantes não nativos navegando em site de idioma estrangeiro por imagens e layout (NN/g, Imagery Helps International Shoppers Navigate Ecommerce Sites (em inglês)).

Isso qualifica a opção de não entregar nada. Uma página não traduzida com visual claro é prática estudada, e traduzir todos os idiomas muitas vezes não é viável.

O que decidir no Astro: rotas, slug e sitemap

Três decisões estruturais sustentam a anotação.

  • Forma da rota. O guia de i18n do Astro (em inglês) coloca o conteúdo em pastas [locale] dentro de src/pages/. Com prefixDefaultLocale: false, o idioma padrão fica na raiz e cada outro idioma carrega um prefixo.
  • Um slug por idioma. Guarde o slug no frontmatter e nunca o derive do título, porque editar o título moveria as URLs alternativas.
  • Uma fonte de verdade para o código. Derive o valor de hreflang do prefixo da rota por um único mapa. Assim o atributo lang do html, o locale do Open Graph, o sitemap e a propriedade inLanguage do dado estruturado não divergem (schema.org, inLanguage (em inglês)).

A opção i18n (em inglês) do @astrojs/sitemap escreve o bloco xhtml:link a partir do mesmo mapa de locales. A integração não emite x-default, então acrescente no serialize quando o site precisar de um destino padrão.

O build é onde tudo isso é conferido. Uma contagem de páginas, uma checagem de alternativas e uma auditoria de assets pegam os três defeitos que chegam à produção. São eles a versão ausente, a alternativa órfã e a capa que nenhuma página usa.

Fontes

Outros textos

Ver todos os textos