Spring til indhold

hreflang

attributten der parrer en side med dens oversættelser

Hvad det er

På et link angiver hreflang, hvilket sprog siden i den anden ende er skrevet på. HTML tillader attributten på elementerne a, area og link, men den er blevet kendt for en bestemt brug: et sæt link rel="alternate"-elementer i sidens head, ét pr. sprogversion, hvormed et site fortæller søgemaskiner, at flere adresser rummer det samme indhold på forskellige sprog.

<link rel="alternate" hreflang="en" href="https://example.com/guide/" />
<link rel="alternate" hreflang="da" href="https://example.com/da/guide/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/guide/" />

HTML-standarden kalder attributten »rent vejledende«. Værdien skal være et gyldigt sprogmærke efter BCP 47, og en browser skal tage en hentet sides sprog fra siden selv og aldrig fra det link, der førte derhen. Sammen med rel="alternate" markerer et hreflang, der afviger fra dokumentets eget sprog, at målet er en oversættelse.

Søgemaskinerne har gjort den vejledende bemærkning til et fast regelsæt. Google beskriver tre ligeværdige måder at levere sættet på: link-elementer i head, en HTTP-header af typen Link til PDF’er og andre filer uden head, og poster i et XML-sitemap. Hver version skal nævne sig selv og alle de andre versioner med fuldt kvalificerede adresser. Et par tæller kun, når begge sider nævner hinanden, så et fremmed site ikke kan erklære sig selv for en oversættelse af ens egne sider. Koderne er et sprog efter ISO 639-1, eventuelt efterfulgt af en region efter ISO 3166-1, og en region alene er ugyldig. Den reserverede værdi x-default udpeger siden til læsere, hvis sprog ikke passer til nogen af de andre, og ifølge Google er den tænkt til sider, hvor man vælger sprog.

To naboer er lette at forveksle med den. Attributten lang siger, hvilket sprog teksten foran læseren er på; hreflang siger, hvilket sprog en side, der linkes til, er på. Google oplyser, at den ikke bruger nogen af dem til at afgøre en sides sprog, så hreflang kan ikke gøre en side dansk; den fortæller en søgemaskine, at en dansk side, den allerede har genkendt, hører sammen med en engelsk. Og en kanonisk URL lægger dubletter sammen til én indekseret adresse, mens hreflang holder hver version i indekset og siger, hvilken der skal vises til hvem.

Hvorfor det betyder noget

Det, hreflang afgør, er, om sprogversionerne af en side udgør én klynge eller bedømmes som hver sin side. Står de alene, konkurrerer hver version for sig, og en søgemaskine kan vise den engelske side til en dansk læser eller liste begge versioner i de samme resultater. Erklæres de som en klynge, forstås de som ét stykke indhold, og søgemaskinen kan tilbyde den version, der passer til læserens sprogindstillinger.

Klyngen giver kun mening, når versionerne virkelig er det samme indhold. Et site på ét sprog har slet ikke brug for hreflang, og to sprogafdelinger, der adskiller sig i substansen, er heller ikke en klynge. Regionale varianter med små forskelle, for eksempel en-GB- og en-US-sider med hver sine priser, hører også sammen i én.

Omkostningen er bogføring, og den vokser med kvadratet på antallet af sprog. Hver version af hver side bærer hele listen, så når en oversættelse tilføjes, flyttes eller trækkes tilbage, ændres head på alle søskendesiderne, og en liste, der er rigtig på de fleste sider og forkert på nogle få, fejler i stilhed: de par, der peger begge veje, bliver brugt, og resten bliver smidt væk uden nogen synlig fejl. Derfor egner hreflang sig dårligt til håndredigering og godt til en generator, der udleder hver sides sæt af én liste. Det, hreflang ændrer, er, hvilken af flere versioner en søgende får at se.

Sådan ser det ud i praksis

Dette site udgiver hver side på tre sprog fra ét indholdstræ, så hver side har et fast sæt søskende at angive.

Én skabelon afgør, hvilke oversættelser der annonceres, og fem steder læser den: hreflang-sættet i head, og:locale:alternate-taggene til linkforhåndsvisninger, alternativerne i sitemappet, inLanguage i sitets strukturerede data og, efter endnu en fratrækning, den sprogstribe, læseren ser. Listen rummer siden selv og giver dermed den selvreference, reglerne kræver. Koderne nævner kun sprog, en, da og uk, så hver version tilbydes alle læsere af det sprog, uanset hvor de bor, og den engelske post skrives en gang til som x-default. Head og sitemap bærer begge sættet, og begge gengives fra den samme liste, så de kan ikke glide fra hinanden.

Skellet mellem maskiner og læsere er bevidst. Den ukrainske version er indekseret og nævnt i sitemaps, mens striben i topbjælken udelader den, og i sprogkonfigurationen er det ét enkelt flag: en crawler får stadig besked om ukrainsk i begge retninger, og kun læserens menu ændrer sig. Et andet flag, til et sprog, der er bygget, men ikke klar, fjerner det fra begge lister og mærker dets sider noindex. En side på sådan et sprog angiver heller ingen søskende, for et hreflang fra en side, der ikke er annonceret, til en, der er, er et par, som en søgemaskine kun ser den ene ende af.

Kopier følger samme logik. En side på et af de fokuserede subdomæner, hvis kanoniske URL peger tilbage på hovedsitet, udskriver slet intet hreflang: sættet læses på den side, en søgemaskine har godtaget som kanonisk, og en kopi, der nævnte sin egen værts oversættelser, ville modsige sin egen kanoniske URL. Sprogvælgeren virker stadig, for en læser, der vil have dansk, skal stadig have dansk.

Et tjek af de byggede sider kræver, at hver side med alternativer har x-default og sit eget sprog med, og at hvert alternativ er en bygget side på et annonceret sprog, som peger tilbage. Reglen om selvreference gør nytte. Generatoren har to lister med næsten samme navn, .Translations, der udelader den aktuelle side, og .AllTranslations, der tager den med, og forveksler man dem, forsvinder hver sides eget sprog fra head og fra sprogstriben på én gang, så de to stadig er enige. Mod et bevidst ødelagt build var den ene påstand den eneste i tjekket, der fangede 528 af de 792 sider.

Hvor det går galt

Søgende får versionen på det forkerte sprog. En dansk læser bliver sendt til den engelske side, eller begge versioner står side om side. Parrene peger kun én vej: den danske side nævner den engelske, men den engelske lister stadig kun de sprog, den havde før, og søgemaskiner ignorerer et par uden returlink. Byg hver sides sæt af én liste, der rummer siden selv, og afprøv gensidigheden på det byggede output.

Et helt sprogs annoteringer gør ingenting. Markuppen er der og er gyldig HTML, men versionerne bliver behandlet, som om de intet har med hinanden at gøre. Koderne betyder noget andet end tilsigtet: ua eller dk, hvor sprogene hedder uk og da, be ment som Belgien, selv om det er koden for hviderussisk, eller en-UK, hvor en-GB var ment, fordi UK er en reserveret regionskode, som Google ser bort fra. Brug et sprog fra ISO 639-1, tilføj kun en region fra ISO 3166-1, hvor indholdet faktisk er forskelligt fra land til land, og husk, at et gyldigt BCP 47-mærke stadig kan være et, Google ikke understøtter.

Oversættelserne falder ud af indekset. Kun originalsproget dukker op i søgningen, og oversættelserne behandles som dubletter af det. Hver oversættelse udpeger originalen som sin kanoniske URL, og det beder om, at oversættelsen bliver lagt sammen med originalen, mens dens hreflang beder om, at den bliver vist. Lad hver sprogversion være sin egen kanoniske URL; Googles råd er, at den kanoniske side skal være på samme sprog.

En side, der bad om at blive holdt ude af søgning, bliver annonceret alligevel. Et kladdesprog mærket noindex står blandt alternativerne på udgivne sider eller lister dem i sit eget head. Annonceringen og direktivet er sat to forskellige steder, så sitet giver en crawler to svar om den samme adresse. Beslut det pr. sprog, annonceret i begge retninger eller i ingen af dem, læg beslutningen i én indstilling, som alle lister læser, og tjek de byggede sider mod den.

Læs mere

Ordliste