A presentation on Google's hreflang, given by Joost de Valk of Yoast at the International Search Summit in Munich. It covers what hreflang is, how to implement it, which pitfalls to avoid and how to keep it working.
5. What is hreflang?
“Google uses the rel="alternate"
hreflang="x" attributes to serve the correct
language or regional URL in Search results.”
ISS Munich - #iss #hreflang - @jdevalk
6. What is hreflang?
In short: serve the right language version to the
user, based on their locale and location.
ISS Munich - #iss #hreflang - @jdevalk
7. What is it meant for?
ISS Munich - #iss #hreflang - @jdevalk
8. What is it meant for?
• Fully translated sites
ISS Munich - #iss #hreflang - @jdevalk
9. What is it meant for?
• Fully translated sites
• Sites with regional variation
ISS Munich - #iss #hreflang - @jdevalk
10. What is it meant for?
• Fully translated sites
• Sites with regional variation
• Only the template gets translated, main
content is the same (but don’t do this!!)
ISS Munich - #iss #hreflang - @jdevalk
11. ISS Munich - #iss #hreflang - @jdevalk
English site Dutch siteGerman site
hreflang=“de” href=“http://example.com/de/”
hreflang=“en” href=“http://example.com/en/”
hreflang=“nl” href=“http://example.com/nl/”
12. What would happen?
• Someone searching in Dutch would get the Dutch site.
• Someone searching in German would get the German site.
• Someone searching in English would get the English site.
ISS Munich - #iss #hreflang - @jdevalk
13. ISS Munich - #iss #hreflang - @jdevalk
German site
for Germany
German site
for Switzerland
German site
for Austria
href="http://www.example.com/de-de/" hreflang="de-de"
href="http://www.example.com/de-at/" hreflang="de-at"
href="http://www.example.com/de-ch/" hreflang="de-ch"
14. What would happen?
• Someone searching in German in Germany would get
the /de-de/ site.
• Someone searching in German in Austria would get
the /de-at/ site.
• Someone searching in German in Switzerland would
get the /de-ch/ site.
ISS Munich - #iss #hreflang - @jdevalk
16. But beware!
• In the previous example, which page would German
speaking / seeking people in Belgium get?
ISS Munich - #iss #hreflang - @jdevalk
17. But beware!
• In the previous example, which page would German
speaking / seeking people in Belgium get?
• A better solution:
ISS Munich - #iss #hreflang - @jdevalk
18. ISS Munich - #iss #hreflang - @jdevalk
German site
for Germany
& rest of world
German site
for Switzerland
German site
for Austria
href="http://www.example.com/de-de/" hreflang="de"
href="http://www.example.com/de-at/" hreflang="de-at"
href="http://www.example.com/de-ch/" hreflang="de-ch"
19. x-default
“The new x-default hreflang attribute value
signals to our algorithms that this page doesn’t
target any specific language or locale and is the
default page when no other page is better
suited.”
https://webmasters.googleblog.com/2013/04/x-default-hreflang-for-international-pages.html
ISS Munich - #iss #hreflang - @jdevalk
20. x-default
“The x-default hreflang value signals
to our algorithms that such a page
doesn’t target a specific language or
locale.”
https://webmasters.googleblog.com/2013/04/x-default-hreflang-for-international-pages.html
ISS Munich - #iss #hreflang - @jdevalk
22. ISS Munich - #iss #hreflang - @jdevalk
English site Dutch siteGerman site
hreflang=“de” href=“http://example.com/de/”
hreflang=“en” href=“http://example.com/en/”
hreflang=“nl” href=“http://example.com/nl/”
hreflang=“x-default” href=“http://example.com/”
Country
selector page
24. What would happen?
• Someone searching in Dutch would get the Dutch site.
ISS Munich - #iss #hreflang - @jdevalk
25. What would happen?
• Someone searching in Dutch would get the Dutch site.
• Someone searching in German would get the German
site.
ISS Munich - #iss #hreflang - @jdevalk
26. What would happen?
• Someone searching in Dutch would get the Dutch site.
• Someone searching in German would get the German
site.
• Someone searching in English would get the English
site.
ISS Munich - #iss #hreflang - @jdevalk
27. What would happen?
• Someone searching in Dutch would get the Dutch site.
• Someone searching in German would get the German
site.
• Someone searching in English would get the English
site.
• Someone searching in Spanish would get the country /
language selector.
ISS Munich - #iss #hreflang - @jdevalk
28. ISS Munich - #iss #hreflang - @jdevalk
German site
for Germany
& rest of world
German site
for Switzerland
German site
for Austria
href="http://www.example.com/de-de/" hreflang="de"
href="http://www.example.com/de-at/" hreflang="de-at"
href="http://www.example.com/de-ch/" hreflang=“de-ch"
href="http://www.example.com/de-de/" hreflang=“x-default"
31. HTML meta tags
Easiest when you’re not in full control of everything:
<link rel="alternate" href="http://example.com/en-gb" hreflang="en-gb" />
<link rel="alternate" href="http://example.com/en-us" hreflang="en-us" />
<link rel="alternate" href="http://example.com/en-au" hreflang="en-au" />
ISS Munich - #iss #hreflang - @jdevalk
32. HTTP headers
Very useful for non HTML content:
Link: <http://es.example.com/document.pdf>; rel="alternate"; hreflang="es",
<http://en.example.com/document.pdf>; rel="alternate"; hreflang="en",
<http://de.example.com/document.pdf>; rel="alternate"; hreflang=“de"
Not always as easy to maintain for other stuff.
ISS Munich - #iss #hreflang - @jdevalk
40. Common issues
Yes. Common.
This very scientifically
correct pie chart from
David Sottimano is sadly
close to the truth:
ISS Munich - #iss #hreflang - @jdevalk
Hreflang implementation
5%
95%
Screwed up
Got it right
42. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
43. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
• broken URLs
44. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
• broken URLs
• URLs that are redirected
45. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
• broken URLs
• URLs that are redirected
• relative URLs
46. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
• broken URLs
• URLs that are redirected
• relative URLs
47. 1. Broken links / relative URLs
ISS Munich - #iss #hreflang - @jdevalk
If your hreflang href links to:
• broken URLs
• URLs that are redirected
• relative URLs
It won’t work.
49. 2. Missing return link
ISS Munich - #iss #hreflang - @jdevalk
If page A says A is English and B is German.
50. 2. Missing return link
ISS Munich - #iss #hreflang - @jdevalk
If page A says A is English and B is German.
Page B needs to say B is German and A is English.
51. 2. Missing return link
ISS Munich - #iss #hreflang - @jdevalk
If page A says A is English and B is German.
Page B needs to say B is German and A is English.
It can not lack the return link.
52. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
53. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
Language and Country / Region codes follow strict ISO
specs.
54. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
Language and Country / Region codes follow strict ISO
specs.
The first bit is the language, two letters, in ISO 639-1
format.
55. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
Language and Country / Region codes follow strict ISO
specs.
The first bit is the language, two letters, in ISO 639-1
format.
The second (optional) bit is the region. In ISO 3166-1
Alpha 2 format.
56. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
So Ferrari got it slightly wrong:
<link rel="alternate" hreflang="en-en" href="http://www.ferrari.com/en_en/" />
<link rel="alternate" hreflang="fr-fr" href="http://www.ferrari.com/fr_fr/" />
<link rel="alternate" hreflang="de-de" href="http://www.ferrari.com/de_de/" />
<link rel="alternate" hreflang="es-es" href="http://www.ferrari.com/es_es/" />
<link rel="alternate" hreflang="it-it" href="http://www.ferrari.com/it_it/" />
<link rel="alternate" hreflang="en-us" href="http://www.ferrari.com/en_us/" />
<link rel="alternate" hreflang="ja-jp" href="http://www.ferrari.com/ja_jp/" />
<link rel="alternate" hreflang="zh-cn" href="http://www.ferrari.com/zh_cn/" />
<link rel="alternate" hreflang="nl" href="http://www.ferrari.com/nl_nl/" />
This was on their nl page.
57. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
58. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
59. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
60. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
61. 3. Wrong country / region code
ISS Munich - #iss #hreflang - @jdevalk
This is btw quite a common issue:
<link href="http://www.independent.co.uk/"
rel="alternate" hreflang="en-uk" />
This should be en-gb of course!
64. 4. Canonical interference
ISS Munich - #iss #hreflang - @jdevalk
Each language should have a canonical that
points to itself.
65. 4. Canonical interference
ISS Munich - #iss #hreflang - @jdevalk
Each language should have a canonical that
points to itself.
If it doesn’t follow that simple rule, it’ll
prevent hreflang from working.
66. 4. Canonical interference
ISS Munich - #iss #hreflang - @jdevalk
Each language should have a canonical that
points to itself.
If it doesn’t follow that simple rule, it’ll
prevent hreflang from working.
So, in our earlier example:
67. ISS Munich - #iss #hreflang - @jdevalk
English site Dutch siteGerman site
<link rel=“alternate” hreflang=“de” href=“http://example.com/de/”>
<link rel=“alternate” hreflang=“en” href=“http://example.com/en/”>
<link rel=“alternate” hreflang=“nl” href=“http://example.com/nl/”>
<link rel=“canonical” href=“http://example.com/en/”>
Correct implementation:
68. ISS Munich - #iss #hreflang - @jdevalk
English site Dutch siteGerman site
Correct implementation:
<link rel=“alternate” hreflang=“de” href=“http://example.com/de/”>
<link rel=“alternate” hreflang=“en” href=“http://example.com/en/”>
<link rel=“alternate” hreflang=“nl” href=“http://example.com/nl/”>
<link rel=“canonical” href=“http://example.com/de/”>
69. ISS Munich - #iss #hreflang - @jdevalk
English site Dutch siteGerman site
Correct implementation:
<link rel=“alternate” hreflang=“de” href=“http://example.com/de/”>
<link rel=“alternate” hreflang=“en” href=“http://example.com/en/”>
<link rel=“alternate” hreflang=“nl” href=“http://example.com/nl/”>
<link rel=“canonical” href=“http://example.com/nl/”>
70. 5. It looks fine but it says it’s broken!
ISS Munich - #iss #hreflang - @jdevalk
Maybe you have two implementations? If so…
Get rid of one!
83. Common reasons for breakage
Pages that are redirected, but the hreflang wasn’t
updated.
ISS Munich - #iss #hreflang - @jdevalk
84. Common reasons for breakage
Pages that are redirected, but the hreflang wasn’t
updated.
Pages that have been deleted in one language but
not in the other(s).
ISS Munich - #iss #hreflang - @jdevalk
85. Common reasons for breakage
Pages that are redirected, but the hreflang wasn’t
updated.
Pages that have been deleted in one language but
not in the other(s).
A developer thought “this can be done so much
simpler”, and breaks it all.
ISS Munich - #iss #hreflang - @jdevalk
87. Regular audits
To prevent breakage, you need to audit
regularly.
ISS Munich - #iss #hreflang - @jdevalk
88. Regular audits
To prevent breakage, you need to audit
regularly.
If you have continuous integration, add
hreflang tests.
ISS Munich - #iss #hreflang - @jdevalk
91. Audit source code
Make sure the code that generates hreflang:
ISS Munich - #iss #hreflang - @jdevalk
92. Audit source code
Make sure the code that generates hreflang:
• has documentation that explains why;
ISS Munich - #iss #hreflang - @jdevalk
93. Audit source code
Make sure the code that generates hreflang:
• has documentation that explains why;
• points to documentation on the how;
ISS Munich - #iss #hreflang - @jdevalk
94. Audit source code
Make sure the code that generates hreflang:
• has documentation that explains why;
• points to documentation on the how;
• explains special cases like x-default;
ISS Munich - #iss #hreflang - @jdevalk
95. Audit source code
Make sure the code that generates hreflang:
• has documentation that explains why;
• points to documentation on the how;
• explains special cases like x-default;
• explains relationship to canonical.
ISS Munich - #iss #hreflang - @jdevalk
96. Regular audits
ISS Munich - #iss #hreflang - @jdevalk
Regular audits and smart code
documentation will keep your
hreflang happy!