Ustawianie hreflang i x-default na wielojęzycznej stronie (z Hugo) - Część 2
W 2023 roku przyjrzałem się, jak dodać odpowiednie tagi hreflang do mojej osobistej strony internetowej, które uwzględniały dodanie odniesienia do bieżącego języka, odniesienia do przetłumaczonej strony (jeśli jest dostępna), oraz jako domyślnie wskazywanie na stronę zaprojektowaną jako przełącznik językowy.
Od tamtej pory sądziłem, że to podejście jest poprawne, ale odkryłem, że to rozwiązanie na mojej stronie, gdzie nie cała zawartość jest w 100% przetłumaczona, nie jest dobre dla stron w pełni przetłumaczonych domyślnie.
Oto, czego się z tego nauczyłem i jak zoptymalizowałem hreflang i x-default na stronach zbudowanych z użyciem Hugo.
Niedawno stworzyłem “jeszcze jedną stronę Hugo”. Moja przyjaciółka, która jest wysoko wykwalifikowanym audytorem w wielu standardach, potrzebuje strony internetowej, aby reklamować to, co może zaoferować potencjalnym nowym klientom.
Jest z Polski, mieszka w Szwecji, pracuje dla brytyjskiej firmy i oferuje swoje usługi na całym świecie.
Strona musi być domyślnie w języku angielskim, aby mieć globalny zasięg; jednakże musi być dostępna w jej ojczystym języku (polskim) oraz w miejscu jej głównego zamieszkania (szwedzkim).
Z takim podejściem strona emiliawardach.com nabiera życia.
Jak zawsze, po ukończeniu strony praca nie jest zakończona. Zawsze są jakieś drobne poprawki i ulepszenia. Kiedy zacząłem ją sprawdzać za pomocą różnych walidatorów i narzędzi jak ahrefs.com, ku mojemu zaskoczeniu, spotkałem się z wieloma problemami zgłoszonymi jako Brak wzajemnego hreflang (brak tagu powrotnego) (Missing reciprocal hreflang (no return-tag)).
Przyjrzałem się również stronie internetowej mojej znajomej, yummyrecipes.uk, która została w pełni przetłumaczona jakiś czas temu i znalazłem podobne problemy.
Myślałem, że zaimplementowałem wszystko poprawnie, zgodnie z moim poprzednim postem Ustawianie hreflang i x-default na wielojęzycznej stronie (z Hugo).
Gdy zacząłem ponownie czytać to, co napisałem, znalazłem kilka błędów, które doprowadziły do tego podejścia.
Po pierwsze, początek strony w Hugo zawierał następujące elementy:
<!DOCTYPE html>
<html lang="{{ .Language.LanguageCode }}" xml:lang="{{ .Language.LanguageCode }}">
To generuje następujący kod dla części angielskiej.
<!DOCTYPE html>
<html lang="en-GB" xml:lang="en-GB">
Jak zauważysz, nie celuję tylko w anglojęzycznych odwiedzających, ale idę bardziej szczegółowo, odzwierciedlając, że strona jest w brytyjskim angielskim, co jest bardziej niż poprawne.
Problemem była początkowa implementacja.
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}">
{{ range .Translations }}
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}">
{{ end }}
Na razie wykluczę
x-default
, ponieważ wrócę do tego później.Dodatkowo, zrezygnowałem z używania względnego linku
{{ .RelPermalink }}
i pozostałem przy pełnym linku do strony za pomocą{{ .Permalink }}
.
Powyższy kod wygeneruje coś takiego:
<link rel="alternate" hreflang="en" href="https://emiliawardach.com/">
<link rel="alternate" hreflang="pl" href="https://emiliawardach.com/pl/">
<link rel="alternate" hreflang="sv" href="https://emiliawardach.com/sv/">
Pierwsza niezgodność była tutaj.
Ponieważ określam język za pomocą {{ .Language.LanguageCode }}
w tagu <html>
, strona angielska zwróci en-GB
, polska będzie miała pl-PL
, a szwedzka sv-SE
.
Ponieważ bardziej szczegółowo określam języki dokumentów w tagu <html>
, wskazując, że angielski to nie tylko angielski, ale brytyjski angielski, powinienem to śledzić we wszystkich odniesieniach hreflang
, których używam na stronie.
{{ .Lang }}
zwróci tylko dwa znaki języka; dla angielskiego będzie to tylko en
, co jest niezgodne z tym, co ustawiłem na samym początku.
Dla wyjaśnienia, languageCode
, który określiłem w hugo.conf
, jest następujący dla części angielskiej:
[languages.en]
languageCode = 'en-GB'
Oczywiście, mogę zmienić languageCode
, aby był bardziej uniwersalny (po prostu en
), ale wolę trzymać się poprawnej metody, aby dokładnie odzwierciedlić brytyjski angielski, a nie ogólny angielski.
W takim przypadku muszę dostosować mój kod, używając .Language.LanguageCode
zamiast samego .Lang
, w następujący sposób:
<link rel="alternate" hreflang="{{ .Language.LanguageCode }}" href="{{ .Permalink }}">
{{ range .Translations }}
<link rel="alternate" hreflang="{{ .Language.LanguageCode }}" href="{{ .Permalink }}">
{{ end }}
Zauważ, że raportuję pierwszy link rel="alternate"
jako odniesienie do samej siebie dla strony, na której aktualnie jestem w wybranym języku.
Drugi, wewnątrz {{ range .Translations }}
, zwróci wszystkie inne dostępne języki dla wybranej strony (/about/
), jak pokazano poniżej:
<link rel="alternate" hreflang="en-GB" href="https://emiliawardach.com/about/">
<link rel="alternate" hreflang="pl-PL" href="https://emiliawardach.com/pl/o-mnie/">
<link rel="alternate" hreflang="sv-SE" href="https://emiliawardach.com/sv/om/">
hreflang
będzie odpowiadał językowi określonemu na poziomie dokumentu w tagu <html>
. Odniesie się do aktualnie odwiedzanej strony /about
w brytyjskim angielskim i wymieni inne dostępne linki do przetłumaczonych stron.
Pierwszy problem rozwiązany.
Teraz musimy przemyśleć użycie x-default
.
W moim poprzednim poście, wspomniałem o specjalnie zaprojektowanej stronie, na której użytkownicy mogą zdecydować o wyborze języka:
<link rel="alternate" href="{{ .Site.Params.langSelector | absURL }}" hreflang="x-default">
Na mojej stronie będzie to wyglądać następująco:
<link rel="alternate" href="https://dariusz.wieckiewicz.org/en/language-selector/" hreflang="x-default">
To nie jest idealne rozwiązanie, ale na mojej stronie, gdzie nie wszystko jest (ani nie musi być) przetłumaczone, to pewnego rodzaju kompromis.
x-default
powinno zawsze działać jako opcja zapasowa.
Pamiętaj, że określiłem języki jako szczegółowe. Angielski to nie tylko angielski, to brytyjski angielski.
Jeśli osoba, której język ustawiony na urządzeniu to angielski, ale pochodzi z Liberii, zostanie zgłoszony jako en-LR
.
To oczywiście nie będzie pasować do pl-PL
i sv-SE
, ale również nie będzie pasować do en-GB
.
W takim przypadku musimy zapewnić domyślną opcję zapasową.
Ponieważ angielski jest dużo bardziej uniwersalny niż polski czy szwedzki, jeśli osoba trafi, poprzez wyszukiwarkę lub bezpośredni link, na /pl/o-mnie/
, co nie pasuje do ich głównego języka, x-default
powinno zasugerować, że powinni zobaczyć inną wersję językową jako swoją domyślną stronę.
W takim przypadku domyślnym językiem będzie angielski w formie brytyjskiego angielskiego.
Będąc na /pl/o-mnie
, x-default
powinno zgłaszać się w następujący sposób:
<link rel="alternate" href="https://emiliawardach.com/about/" hreflang="x-default">
W Hugo możemy to osiągnąć na różne sposoby, jak donosi Joe Mooring na forum wsparcia Hugo, w odpowiedzi na pytanie How to get a specific translation?.
Spodobała mi się opcja z funkcją index
, i do moich celów dodałem następujące elementy do mojego kodu:
{{ $p := index (where .AllTranslations "Language.Lang" "en") 0 }}
<link rel="alternate" href="{{ $p.Permalink }}" hreflang="x-default">
Ten kod wylistuje wszystkie tłumaczenia (.AllTranslations
), ale ograniczy wynik do pojedynczego wybranego języka, którym w tym przypadku jest angielski en
.
Pełny kod będzie wyglądać następująco:
<link rel="alternate" hreflang="{{ .Language.LanguageCode }}" href="{{ .Permalink }}">
{{ range .Translations -}}
<link rel="alternate" hreflang="{{ .Language.LanguageCode }}" href="{{ .Permalink }}">
{{ end -}}
{{ $p := index (where .AllTranslations "Language.Lang" "en") 0 }}
<link rel="alternate" href="{{ $p.Permalink }}" hreflang="x-default">
To podejście wykorzysta x-default
do jego zamierzonego celu. Zapewni spójność w całej treści (stronach) i będzie zgodne z tym, co jest znane jako powszechna praktyka.
“Powszechną praktyką jest, aby podstawowa lub najbardziej ogólna wersja językowa (często angielska) służyła jako x-default.”
Dla mojej polskiej strony /pl/o-mnie/
, wynik będzie wyglądał następująco:
<link rel="alternate" hreflang="en-GB" href="https://emiliawardach.com/about/">
<link rel="alternate" hreflang="pl-PL" href="https://emiliawardach.com/pl/o-mnie/">
<link rel="alternate" hreflang="sv-SE" href="https://emiliawardach.com/sv/om/">
<link rel="alternate" href="https://emiliawardach.com/about/" hreflang="x-default">
To rozwiązuje problem z Brakującym wzajemnym hreflangiem (brak tagu zwrotnego) (Missing reciprocal hreflang (no return-tag)) raz na zawsze.
Pozdrawiam.
Komentarze i Reakcje