Skip to main content

Confirm

Are you sure?

SEO · Checked on every page

Hreflang tags (internationalization)What it checks and how to fix it

What it checks

Reads the page's <link rel="alternate" hreflang> tags; a page without any passes (a single-language site does not need them). When present, it checks that every language code is a valid ISO code (en-GB, not en-UK), that every URL parses, that the page lists itself, and that an x-default is declared. Passes when all of that holds and warns otherwise.

Why it matters

Hreflang tells search engines which language or regional version of a page to show to each searcher. Invalid codes are ignored, a set without the page itself is incomplete, and without x-default visitors whose language you do not serve get whichever version Google picks. The result is the wrong language in search results and visitors bouncing.

How to fix it

List every language version on every version, including the page itself, plus an x-default for everyone else. Use
ISO 639-1 language codes, optionally with an ISO 3166-1 region (en-GB, pt-BR).

<link rel="alternate" hreflang="en" href="https://example.com/pricing">
<link rel="alternate" hreflang="es" href="https://example.com/es/precios">
<link rel="alternate" hreflang="pt-BR" href="https://example.com/pt-br/precos">
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing">

In Rails, generate them from the available locales so none is forgotten:

<% I18n.available_locales.each do |locale| %>
  <link rel="alternate" hreflang="<%= locale %>" href="<%= url_for(locale: locale, only_path: false) %>">
<% end %>
<link rel="alternate" hreflang="x-default" href="<%= url_for(locale: I18n.default_locale, only_path: false) %>">

Monitor this automatically

Full Stack Audit runs this check and 126 others on your site on a schedule, and emails you when one that passed starts failing.

More SEO checks