hreflang across the globe

Post on 21-Apr-2017

1.855 views 0 download

Transcript of hreflang across the globe

hreflang across the globe

ISS Munich - #iss #hreflang - @jdevalk

ISS Munich - #iss #hreflang - @jdevalk

Today!• What is hreflang?

• Design choices

• Common issues

• Useful tools

ISS Munich - #iss #hreflang - @jdevalk

What is hreflang?

ISS Munich - #iss #hreflang - @jdevalk

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

What is hreflang?In short: serve the right language version to the user, based on their locale and location.

ISS Munich - #iss #hreflang - @jdevalk

What is it meant for?

ISS Munich - #iss #hreflang - @jdevalk

What is it meant for?• Fully translated sites

ISS Munich - #iss #hreflang - @jdevalk

What is it meant for?• Fully translated sites

• Sites with regional variation

ISS Munich - #iss #hreflang - @jdevalk

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

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/”

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

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"

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

But beware!

ISS Munich - #iss #hreflang - @jdevalk

But beware!• In the previous example, which page would German

speaking / seeking people in Belgium get?

ISS Munich - #iss #hreflang - @jdevalk

But beware!• In the previous example, which page would German

speaking / seeking people in Belgium get?

• A better solution:

ISS Munich - #iss #hreflang - @jdevalk

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"

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

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

x-default

ISS Munich - #iss #hreflang - @jdevalk

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

What would happen?

ISS Munich - #iss #hreflang - @jdevalk

What would happen?• Someone searching in Dutch would get the Dutch site.

ISS Munich - #iss #hreflang - @jdevalk

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

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

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

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"

hreflang design choices

ISS Munich - #iss #hreflang - @jdevalk

hreflang implementation options• HTML meta tags

• HTTP headers

• XML sitemap

ISS Munich - #iss #hreflang - @jdevalk

HTML meta tagsEasiest 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

HTTP headersVery 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

XML Sitemap<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"><url> <loc>http://www.example.com/english/</loc> <xhtml:link rel=“alternate" hreflang="de" href="http://www.example.com/deutsch/"/> <xhtml:link rel=“alternate" hreflang="de-ch" href="http://www.example.com/schweiz-deutsch/"/> <xhtml:link rel=“alternate" hreflang="en" href="http://www.example.com/english/"/></url>

ISS Munich - #iss #hreflang - @jdevalk

XML Sitemap[…]

<url> <loc>http://www.example.com/deutsch/</loc> <xhtml:link rel=“alternate" hreflang="en" href="http://www.example.com/english/"/> <xhtml:link rel=“alternate" hreflang="de-ch" href="http://www.example.com/schweiz-deutsch/"/> <xhtml:link rel=“alternate” hreflang="de" href="http://www.example.com/deutsch/"/></url>

ISS Munich - #iss #hreflang - @jdevalk

XML Sitemap

ISS Munich - #iss #hreflang - @jdevalk

XML Sitemap• horribly ugly

ISS Munich - #iss #hreflang - @jdevalk

XML Sitemap• horribly ugly

• but easiest to maintain

ISS Munich - #iss #hreflang - @jdevalk

XML Sitemap• horribly ugly

• but easiest to maintain

• doesn’t add kilobytes to each page load

ISS Munich - #iss #hreflang - @jdevalk

hreflang breaks - often

ISS Munich - #iss #hreflang - @jdevalk

Common issuesYes. 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 upGot it right

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

If your hreflang href links to:

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

If your hreflang href links to:

• broken URLs

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

If your hreflang href links to:

• broken URLs

• URLs that are redirected

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

If your hreflang href links to:

• broken URLs

• URLs that are redirected

• relative URLs

1. Broken links / relative URLs

ISS Munich - #iss #hreflang - @jdevalk

If your hreflang href links to:

• broken URLs

• URLs that are redirected

• relative URLs

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.

2. Missing return link

ISS Munich - #iss #hreflang - @jdevalk

2. Missing return link

ISS Munich - #iss #hreflang - @jdevalk

If page A says A is English and B is German.

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.

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.

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

Language and Country / Region codes follow strict ISO specs.

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.

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.

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.

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

3. Wrong country / region code

ISS Munich - #iss #hreflang - @jdevalk

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!

4. Canonical interference

ISS Munich - #iss #hreflang - @jdevalk

4. Canonical interference

ISS Munich - #iss #hreflang - @jdevalk

4. Canonical interference

ISS Munich - #iss #hreflang - @jdevalk

Each language should have a canonical that points to itself.

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.

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:

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:

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/”>

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/”>

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!

Useful tools

hreflang tag generator

http://yoa.st/hreflanggenerator

ISS Munich - #iss #hreflang - @jdevalk

hreflang XML sitemap generatorhttp://www.themediaflow.com/tool_hreflang

ISS Munich - #iss #hreflang - @jdevalk

hreflang XML sitemap generatorhttp://www.themediaflow.com/tool_hreflang

ISS Munich - #iss #hreflang - @jdevalk

hreflang tag validator

http://flang.dejanseo.com.au/

ISS Munich - #iss #hreflang - @jdevalk

ISS Munich - #iss #hreflang - @jdevalk

http://yoa.st/hreflangchrome

hreflang tag recognition

ISS Munich - #iss #hreflang - @jdevalk

hreflang tag recognition

Keep auditing

It works now!

ISS Munich - #iss #hreflang - @jdevalk

It works now!No. It works now.

ISS Munich - #iss #hreflang - @jdevalk

It works now!No. It works now.

It will break.

ISS Munich - #iss #hreflang - @jdevalk

Common reasons for breakage

ISS Munich - #iss #hreflang - @jdevalk

Common reasons for breakagePages that are redirected, but the hreflang wasn’t updated.

ISS Munich - #iss #hreflang - @jdevalk

Common reasons for breakagePages 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

Common reasons for breakagePages 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

Regular audits

ISS Munich - #iss #hreflang - @jdevalk

Regular auditsTo prevent breakage, you need to audit regularly.

ISS Munich - #iss #hreflang - @jdevalk

Regular auditsTo prevent breakage, you need to audit regularly.

If you have continuous integration, add hreflang tests.

ISS Munich - #iss #hreflang - @jdevalk

Setup (regular) testsManually with Screaming Frog, or automated.

ISS Munich - #iss #hreflang - @jdevalk

Audit source code

ISS Munich - #iss #hreflang - @jdevalk

Audit source codeMake sure the code that generates hreflang:

ISS Munich - #iss #hreflang - @jdevalk

Audit source codeMake sure the code that generates hreflang:

• has documentation that explains why;

ISS Munich - #iss #hreflang - @jdevalk

Audit source codeMake sure the code that generates hreflang:

• has documentation that explains why;

• points to documentation on the how;

ISS Munich - #iss #hreflang - @jdevalk

Audit source codeMake 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

Audit source codeMake 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

Regular audits

ISS Munich - #iss #hreflang - @jdevalk

Regular audits and smart code

documentation will keep your

hreflang happy!

Questions?Follow along:

• https://yoast.com/

• @jdevalk & @yoast on Twitter

• facebook.com/yoast

ISS Munich - #iss #hreflang - @jdevalk