Faça sua pergunta e obtenha um resumo do documento referenciando esta página e o provedor AI de sua escolha
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsSe você tiver uma ideia para melhorar esta documentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.
Link do GitHub para a documentaçãoCopiar o Markdown do documento para a área de transferência
Hreflang: o guia para SEO multilíngue
Você traduziu seu app. Você fez deploy de /en, /fr, /es. E usuários franceses ainda caem na página em inglês.
Traduzir é a metade fácil. A metade difícil é dizer aos search engines que essas páginas são a mesma página em outro idioma, não três documentos competindo entre si. É isso que hreflang faz, e é onde a maioria dos sites multilíngues perde silenciosamente seu tráfego.
O que hreflang realmente é
Uma anotação em uma página dizendo: esta URL tem versões equivalentes ali, para esses idiomas.
Copiar o código para a área de transferência
Isso oferece duas coisas: a versão correta mostrada ao usuário certo, e suas locales consolidadas em um cluster em vez de canibalizarem uma à outra como duplicatas.
É importante ser claro sobre o que não é. Não é um redirecionamento — é uma dica, e o Google pode sobrescrevê-la. Não é um aumento de ranking — muda qual versão classifica, não se você classifica. E o Bing ignora completamente, confiando em content-language e geolocalização em vez disso.
Onde declarar
Três posicionamentos, todos válidos. Escolha um e mantenha-se — o mesmo cluster declarado em dois lugares é como os conjuntos divergem.
HTML <head> é a escolha usual. Uma ressalva: tags injetadas após hidratação são não confiáveis. Se seu framework apenas as adiciona do lado do cliente, o rastreador pode nunca vê-las.
XML sitemap é melhor em escala. Dez locales em 5 000 páginas significa 50 000 elementos <link> enviados para browsers desnecessariamente; em um sitemap custa zero bytes nas suas páginas.
HTTP Link header é a única opção para arquivos não-HTML como PDFs.
As regras
Auto-referência e reciprocidade
O conjunto em /fr/about deve incluir hreflang="fr" apontando para /fr/about. E se /about aponta para /fr/about, /fr/about deve apontar de volta. Google chama uma referência unidirecional de "no return tag" e a descarta.
Na prática isto significa cada página em um cluster envia o conjunto idêntico de links. Gerá-los a partir de uma lista de locale compartilhada não é uma conveniência, é a única forma de manter-se correto uma vez que você tenha mais de dois locales.
URLs absolutas, sempre
Copiar o código para a área de transferência
A razão vale a pena ser compreendida em vez de memorizada. hreflang é uma referência entre documentos: os mecanismos de busca constroem um cluster codificado por URL, compartilhado em todas as páginas nele. Um caminho relativo só tem significado em relação ao documento em que está, portanto não pode expressar isso. Também não pode cruzar um host — e uma alternativa muito frequentemente faz isso, quando uma localidade vive em example.fr ou fr.example.com. Em um sitemap ou em um cabeçalho HTTP não há documento base para resolver.
Isso tem uma consequência direta no código. getLocalizedUrl("/about", "fr") retorna /fr/about — relativo dentro, relativo fora. Para hreflang você deve fornecer uma URL absoluta:
Copiar o código para a área de transferência
A única exceção é um framework que resolve valores relativos para você antes de renderizar: Next.js expande alternates relativos contra metadataBase. Tudo bem — mas a regra se aplica ao HTML emitido, então verifique com curl, não com o inspetor DevTools.
Códigos de idioma
ISO 639-1 para o idioma, ISO 3166-1 Alpha 2 para a região opcional: fr, fr-CA, pt-BR.
Duas armadilhas pegam quase todo mundo. Uma região sozinha é inválida — hreflang="ca" é catalão, não Canadá; você precisa de en-CA ou fr-CA. E en-UK não existe: o código de país para o Reino Unido é GB, então é en-GB.
Adicione uma região apenas quando você realmente servir a essa região conteúdo diferente — preços diferentes, avisos legais diferentes. fr e fr-FR em conteúdo idêntico é ruído.
x-default
Copiar o código para a área de transferência
Um conceito que é o mais frequentemente esquecido, e mal compreendido, é x-default — menos de 30% das apps o implementam corretamente.
É o fallback para usuários cuja língua não corresponde a nada em seu conjunto. Um falante de holandês em um site oferecendo inglês, francês e espanhol não corresponde a nenhuma entrada; sem x-default, o Google escolhe por você.
O que as pessoas entendem errado é o que significa. x-default não é "a versão em inglês" e não é "a locale padrão", mesmo que geralmente aponte para lá. Significa a página para usuários que este conjunto não cobre. É por isso que é legítimo — e frequentemente melhor — apontá-lo para um seletor de idioma ou uma página de destino com redirecionamento geográfico em vez de para /en. Se você não tem tal página, seu idioma principal é a resposta sensata.
Duas coisas para esclarecer: x-default é uma entrada extra no conjunto, não uma substituição para a auto-referenciada, e como todas as outras entradas, deve aparecer identicamente em todas as páginas do cluster.
A armadilha do canonical
Cada página localizada deve ser seu próprio canonical:
Copiar o código para a área de transferência
Apontando o canonical de todas as locales para a versão em inglês:
Copiar o código para a área de transferência
diz que a página francesa é uma duplicata que não deve ser indexada, enquanto hreflang diz que é a página a servir para usuários franceses. Os sinais se contradizem, canonical vence, e suas páginas em francês caem do índice.
Canonical é auto-referencial por locale. hreflang descreve o cluster.
Escolhendo uma estrutura de URL
hreflang anota URLs, então a estrutura vem em primeiro lugar.
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Structure | Example | Trade-off |
|---|---|---|
| Subdirectories | example.com/fr/ | Um domínio, autoridade compartilhada — sinal geográfico mais fraco |
| Subdomains | fr.example.com | Fácil adicionar ou remover um locale — pode parecer um site separado |
| ccTLDs | example.fr | Sinal de país mais forte — autoridade construída por domínio |
Subdirectórios são a escolha padrão correta para a maioria dos projetos. Recorra a ccTLDs apenas quando você realmente operar como negócios separados por país.
A única estrutura a evitar: servir diferentes idiomas na mesma URL com base em Accept-Language ou IP. Os crawlers veem uma versão e indexam uma versão; tudo o mais é invisível.
Intlayer cobre todos os três através derouting.modeerouting.domains. Veja custom domains e a referência de configuração.
Implementação
Escrever essas tags manualmente não sobrevive ao contato com um segundo locale. Derive-as da sua lista de locales em vez disso.
Emitir o cluster em cada página
Mesmo conjunto em todos os lugares, canonical por locale, URLs absolutas,
x-defaultincluído.A Metadata API expõe
alternates.languages, egetMultilingualUrlsconstrói todo o registro a partir dos seus locales configurados:src/app/[locale]/about/page.tsxCopiar códigoCopiar o código para a área de transferência
Setup completo: Guia i18n Next.js 16.
A função
headda rota constrói os links.localeMapitera sobre as localizações configuradas, portanto adicionar uma localização à configuração a adiciona em todos os lugares de uma vez:src/routes/{-$locale}/about.tsxCopiar códigoCopiar o código para a área de transferência
headexecuta no servidor, então as tags chegam no HTML inicial. Setup completo: guia i18n do TanStack Start.Ou mova tudo para o sitemap
Em larga escala, mantenha as anotações fora de suas páginas completamente.
generateSitemapemite alternatesxhtml:linkpor entrada, lendo locales e modo de roteamento de sua config:src/routes/sitemap[.]xml.tsCopiar códigoCopiar o código para a área de transferência
Duas opções que vale a pena conhecer:
xhtmlLinks(padrãotrue) — alternates são emitidos apenas onde as URLs de locale realmente diferem. No modono-prefixcada locale compartilha uma URL, então são ignorados a menos querouting.domainsdê aos locales seus próprios hostnames.entryPerLocale(padrãofalse) — por padrão uma entrada<url>carrega todos os alternates. Ambas as formas são válidas, mas apenas uma URL listada como<loc>conta como enviada no Search Console; locales alternativas permanecem descobríveis mas atribuídas a nenhum sitemap. Ativar isso dá a cada URL localizada sua própria entrada com o conjunto completo de alternates repetido. Multiplica as entradas pela contagem de locale, então fique atento ao limite de 50 000 URLs / 50 MB e divida em um índice de sitemap se ultrapassar.
Verifique o que o crawler recebe
hreflangfalha silenciosamente, então verifique-o em vez de assumir.Leia a fonte, não o inspector —
curl https://example.com/fr/about | grep hreflangmostra o que um crawler recebe; DevTools mostra o DOM após JavaScript ser executado. Em seguida, siga cada alternativa e confirme que ela aponta de volta com o mesmo conjunto, e que nenhuma delas redireciona. O relatório de Direcionamento Internacional do Search Console captura o resto em todo o site.Para um crawl específico multilíngue, o Intlayer SEO Scanner verifica tags ausentes, alternativas quebradas e conflitos canônicos em suas páginas localizadas.
Lista de verificação
- Cada locale possui uma URL distinta e rastreável
- Toda página se auto-referencia, e toda referência é recíproca
- O mesmo conjunto é entregue em todas as páginas do cluster
- Todos os valores
hrefsão absolutos no HTML emitido - Os códigos são ISO 639-1 + ISO 3166-1 Alpha 2 (
en-GB, nãoen-UK) -
x-defaultestá presente e aponta para onde os usuários não correspondidos devem ir - Canonical é autorreferencial por locale
- Tags são renderizadas no servidor, não injetadas após hidratação
- Declaradas em exatamente um lugar
- Sem redirecionamentos alternados
Finalizando
hreflang é simples e implacável. Uma tag de retorno ausente, uma URL relativa, um canonical entre locales, e o cluster é descartado sem nenhum erro em lugar nenhum. Cada um desses problemas vem de escrever as tags manualmente.
Derive the set from a single locale list, render it server-side, keep canonical self-referential, and give x-default the thought it deserves. Do that once and correctness stops being something you maintain.
Going further
- SEO and Internationalization — the broader multilingual SEO picture
- SEO and i18n in Next.js —
next-intlvsnext-i18nextvs Intlayer - Next.js 16 i18n guide
- Guia i18n do TanStack Start
- Domínios personalizados por locale
- Referência de configuração
Comentários
Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.
