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) %>">