Verifique a consistência e a reciprocidade do hreflang
Encontre a página que quebra um grupo hreflang: informe as declarações de cada versão e receba os links exatos que faltam em cada uma. Uma página em inglês e outra em francês que citam as duas versões saem consistentes; qualquer falha aparece página por página. Grátis no seu navegador.
- Grátis
- Funciona no seu navegador
- Sem cadastro
- Seus dados não saem do seu aparelho
Executar grátis
Os grupos hreflang só funcionam de forma confiável quando cada página participante declara o mesmo conjunto completo de alternativas, incluindo uma autorreferência. Este verificador compara mapeamentos coletados em várias páginas e revela grupos incompletos sem acessar nenhuma URL. Ele forma o conjunto esperado com todas as URLs de origem e destino, confere cada origem e informa exatamente quais links faltam em cada página. O resultado é determinístico e adequado para lançamentos, migrações e controles recorrentes de SEO.
Por que grupos recíprocos completos são importantes
Uma anotação hreflang não é apenas uma recomendação de mão única entre duas páginas. Ela descreve a participação em um grupo de páginas equivalentes por idioma ou região, e cada página deve publicar o mesmo conjunto de destinos, inclusive ela própria. Se a página em inglês cita as alternativas francesa e alemã, mas a francesa cita somente a inglesa, o grupo está incompleto, embora várias tags isoladas pareçam corretas.
Os mecanismos de busca podem ignorar relações sem confirmação, exibir a versão linguística errada ou enfraquecer o sinal regional pretendido. A revisão manual fica pouco confiável à medida que o grupo cresce, pois o número de relações aumenta rapidamente. Em um grupo de quatro páginas, cada uma precisa declarar os quatro destinos: são dezesseis relações entre origem e destino.
Este verificador transforma a comparação visual em um teste exato de conjuntos. A consistência só é confirmada quando cada página representada declara todas as páginas do grupo, deixando explícitas as omissões e autorreferências ausentes.
Como preparar e interpretar os mapeamentos
Inclua registros de todas as páginas que devem integrar o grupo. O verificador deriva o grupo esperado da união das URLs de origem e destino. Assim, se uma página for citada pelas páginas irmãs, mas não fornecer declarações próprias, ela continuará no conjunto esperado e será indicada como ausente em todos os destinos.
As URLs são comparadas como textos exatos após a remoção de espaços externos; portanto, sua coleta deve usar a forma absoluta canônica emitida pelas páginas. A saída traz um resumo por página e uma lista de conflitos. Declarações duplicadas não criam uma falsa completude, porque os destinos são comparados como um conjunto.
Uso em lançamentos, migrações e auditorias recorrentes
O melhor momento para verificar a reciprocidade é antes que os rastreadores encontrem uma publicação multilíngue. Exporte as declarações hreflang das páginas renderizadas, converta-as em registros e interrompa a publicação quando consistent for falso. Você detectará ramificações de template que omitem a página atual, lançamentos regionais que atualizam somente o novo mercado e migrações em que uma localidade ainda emite URLs antigas.
A verificação também funciona após a inclusão ou retirada de idiomas. Como o algoritmo não faz solicitações de rede, ele não prova que o destino responde, é canônico ou possui conteúdo equivalente; isso exige rastreamento e análise editorial separados. Sua promessa é específica: verificar se cada página representada lista todas as demais e também a si própria.
Guarde os conflitos com as evidências da implantação para associar cada correção a uma origem e a um destino precisos.
Casos de uso
Validar um lançamento multilíngue
Confira se cada nova localidade e cada página irmã existente publicam o conjunto completo de alternativas antes do lançamento.
Auditar uma migração de plataforma
Compare os mapeamentos dos novos templates e encontre páginas que perderam autorreferências ou links de retorno durante a migração.
Proteger um pipeline de SEO
Transforme um grupo inconsistente em uma falha determinística com as relações exatas ausentes entre origem e destino.
Perguntas frequentes
O que torna um grupo hreflang consistente?
Cada URL representada precisa declarar todas as URLs do grupo, inclusive ela própria. O resultado só será verdadeiro quando todas as relações existirem.
Como páginas de origem ausentes são detectadas?
O grupo esperado reúne URLs de origem e destino. Uma URL presente apenas como destino é indicada como página sem declarações.
Declarações duplicadas são conflitos?
Elas não alteram a completude. Os destinos são comparados como conjunto, mas a contagem mantém todos os registros enviados.
As variantes de URL são normalizadas?
Não. As URLs são comparadas exatamente após retirar espaços externos. Normalize esquema, host, caminho e barra final antes do envio.
Quantos links um grupo hreflang precisa ter?
Cada página precisa citar todas as páginas do grupo, inclusive ela mesma. Com quatro versões de idioma, cada uma das quatro declara os quatro destinos, por isso as relações crescem muito rápido.
Ferramentas relacionadas
Para desenvolvedores — acesso via API
Tudo nesta página está disponível via API. Esta seção é para equipes que querem integrar a ferramenta aos próprios sistemas; quem não precisa disso pode simplesmente usar a ferramenta acima.
Endpoint
Autenticação por token Bearer. Um único POST coloca a tarefa na fila; o resultado chega por webhook ou link assinado.
Chame do seu código
curl -X POST https://api.kit.forhosting.com/seo/hreflang-conflict-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"mappings":[{"page_url":"https://example.com/en","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/en","language":"fr","target_url":"https://example.com/fr"},{"page_url":"https://example.com/fr","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/fr","language":"fr","target_url":"https://example.com/fr"}]}'const res = await fetch("https://api.kit.forhosting.com/seo/hreflang-conflict-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"mappings": [
{
"page_url": "https://example.com/en",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/en",
"language": "fr",
"target_url": "https://example.com/fr"
},
{
"page_url": "https://example.com/fr",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/fr",
"language": "fr",
"target_url": "https://example.com/fr"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/hreflang-conflict-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"mappings": [
{
"page_url": "https://example.com/en",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/en",
"language": "fr",
"target_url": "https://example.com/fr"
},
{
"page_url": "https://example.com/fr",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/fr",
"language": "fr",
"target_url": "https://example.com/fr"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/hreflang-conflict-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"mappings":[{"page_url":"https://example.com/en","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/en","language":"fr","target_url":"https://example.com/fr"},{"page_url":"https://example.com/fr","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/fr","language":"fr","target_url":"https://example.com/fr"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"mappings":[{"page_url":"https://example.com/en","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/en","language":"fr","target_url":"https://example.com/fr"},{"page_url":"https://example.com/fr","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/fr","language":"fr","target_url":"https://example.com/fr"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/hreflang-conflict-check", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Exemplo de requisição
{
"mappings": [
{
"page_url": "https://example.com/en",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/en",
"language": "fr",
"target_url": "https://example.com/fr"
},
{
"page_url": "https://example.com/fr",
"language": "en",
"target_url": "https://example.com/en"
},
{
"page_url": "https://example.com/fr",
"language": "fr",
"target_url": "https://example.com/fr"
}
]
}Exemplo de resposta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.hreflang_conflict_check",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}A API é assíncrona: cada chamada devolve um task_id na hora. Se preferir polling, consulte o status a até 1 requisição por segundo.
Preço
Preço publicado, sem tokens nem créditos escondidos. Tarefa que falha não é cobrada.
Erros
| HTTP | Código | O que significa |
|---|---|---|
401 | unauthorized | Token ausente ou inválido. Confira o header Authorization. |
402 | insufficient_balance | Saldo insuficiente para esta tarefa. Faça uma recarga e tente de novo. |
404 | unknown_type | Esse tipo de tarefa não existe. Confira o campo type no catálogo. |
429 | rate_limited | Muitas requisições em pouco tempo. Espere um instante e tente de novo. |
Notas técnicas
Como preparar e interpretar os mapeamentos
Envie um registro para cada declaração hreflang observada. page_url identifica a página que contém a tag, language registra o valor da tag e target_url indica o destino. Uma página incompleta inclui missing_urls com os destinos exatos a acrescentar. consistent só será verdadeiro quando a lista de conflitos estiver vazia.
Uso em lançamentos, migrações e auditorias recorrentes
As solicitações à API usam o preço-base publicado de US$ 0,002, enquanto o navegador executa localmente a mesma comparação pura.
Perguntas técnicas
O verificador acessa as páginas?
Não. Ele apenas compara os mapeamentos fornecidos e não verifica status HTTP, tags canônicas nem conteúdo.
Quanto custa uma solicitação à API?
Cada solicitação usa o preço-base publicado de US$ 0,002. A comparação não utiliza rede nem modelos.