SEO
SEO multilingua: hreflang e canonical senza scontri
Un sito multilingua dichiara con hreflang ogni versione linguistica, con URL assoluti e link di ritorno, e dà a ciascuna un canonical verso se stessa. Senza reciprocità Google ignora le annotazioni.
In sintesi
- Ogni versione linguistica elenca se stessa e tutte le altre, con URL assoluti.
- Se A dichiara B, B deve dichiarare A: senza link di ritorno le annotazioni possono essere ignorate.
- hreflang non è un fattore di ranking: serve a mostrare la versione giusta, e il canonical resta per lingua.
Un sito multilingua dichiara ogni versione linguistica con hreflang, e ogni versione deve elencare se stessa e tutte le altre. Senza URL assoluti e senza link di ritorno Google può ignorare l'intero gruppo di annotazioni.
Tre modi, un solo elenco
Google accetta hreflang in tre punti: un elemento <link rel="alternate" hreflang="..."> nella head, un'intestazione HTTP Link, oppure un blocco xhtml:link nella sitemap. Le regole non cambiano con il metodo, e i metodi si possono combinare. La documentazione di Google sulle versioni localizzate, letta il 1 novembre 2026, chiede URL completi di schema e host, e specifica che Google non ricava la lingua dall'attributo lang: la ricava dal contenuto.
Le regole che non si negoziano
- Ogni pagina elenca se stessa insieme a tutte le altre versioni: un elenco parziale è un gruppo rotto.
- Gli URL alternati sono assoluti, con https e host, mai percorsi relativi.
- I link di ritorno sono obbligatori: se la pagina italiana dichiara quella inglese, la inglese deve dichiarare quella italiana.
- x-default indica la pagina neutra o il selettore di lingua, e non sostituisce le altre annotazioni.
- Il canonical di ogni versione punta a se stessa: un canonical verso l'altra lingua cancella una delle due.
La verifica di reciprocità
cat > hreflang.mjs ([^/g)].map((m) => m[1]).slice(0, 20);
for (const loc of locs) {
const html = await (await fetch(loc)).text();
const alts = [...html.matchAll(/hreflang="([^"]+)"/g)].map((m) => m[1]);
const self = html.includes(`rel="canonical" href="${loc}"`);
console.log(loc, alts.join(","), self ? "self" : "canonical?");
await new Promise((r) => setTimeout(r, 500));
}
console.log(`${locs.length} pages checked`);
EOF
node hreflang.mjs
Lo script prende i primi venti URL dalla sitemap, legge le annotazioni di ogni pagina e stampa la lingua dichiarata accanto al canonical. La colonna 2 o 3 lingue è il dato che conta: se la pagina italiana dichiara due lingue e quella inglese tre, il gruppo non è reciproco. Sul sito EneUI questo succede su tutte le coppie: la sitemap dichiara en, it e x-default per ogni URL, la head italiana ne dichiara due.
Il catalogo EneUI
La struttura bilingue vale anche per il catalogo: le 111.985 schede sotto /components, i 1.556 blocchi sotto /blocks e le 12.808 icone sotto /icons hanno una versione inglese e una italiana con URL distinti, e le 30 categorie come /blocks/category/table seguono la stessa regola. Un URL per lingua, un canonical per URL. Verificato il 1 novembre 2026.
La limitazione
hreflang non migliora il posizionamento: sceglie la versione da mostrare, non alza la pagina. E la reciprocità si rompe facilmente, come nel nostro caso: la sitemap dichiara en, it e x-default, la head italiana no, e Google documenta che in quel caso le annotazioni possono essere ignorate. Infine una traduzione automatica senza revisione produce due pagine quasi uguali: hreflang non le rende diverse, e il canonical non risolve un contenuto che non è stato localizzato.
Dove continuare
Gli errori che rompono i gruppi sono in hreflang, gli errori comuni; l'implementazione in App Router è in i18n in Next.js App Router; la relazione con il canonical è in canonical, la guida pratica.
Domande frequenti
hreflang migliora il ranking?
No. Serve a mostrare la versione linguistica giusta a chi cerca in quella lingua. Il posizionamento dipende dal contenuto e dai link, non dall'annotazione.
Devo usare codici di lingua o di regione?
La lingua è obbligatoria, la regione è opzionale: it, it-IT, en, en-GB. Usa la regione solo quando il contenuto cambia davvero per quel paese.
Che cosa metto in x-default?
La pagina neutra o il selettore di lingua, quella che serve a chi non corrisponde a nessuna versione. Non è obbligatoria, ma evita di spedire un utente alla lingua sbagliata.
Posso dichiarare hreflang solo nella sitemap?
Sì. La sitemap è uno dei tre metodi accettati e basta da sola, purché gli URL siano assoluti e ogni pagina elenchi se stessa e le altre.
Perché Google mostra la versione sbagliata?
Di solito per un gruppo non reciproco, un URL relativo o un canonical che punta all'altra lingua. Controlla le tre cose nell'ordine, poi chiedi una nuova scansione.