squirrelscan
GitHub

hreflang: x-default and the self-referencing tag

hreflang tells search engines which language version to show. squirrel checks for x-default and a self-reference on any page that has them.

What hreflang is

<link rel="alternate" hreflang="…"> tells a search engine that a page has versions for other languages or regions, and where they are. Without it, the versions compete as near-duplicates and the wrong one is shown.

Two rules make a set work. Every page in the set lists every version including itself, so the set is confirmed from every direction. And x-default names the version to show a visitor whose language matches none of the others, usually a language selector or the primary version.

What squirrel checks

The rule runs on every crawled page over every link[rel="alternate"][hreflang]. It emits up to three checks:

  • Info when the page has no hreflang tags. Message: No hreflang tags found (not required for single-language sites). No further checks run.
  • hreflang-xdefault warns when no tag has hreflang="x-default". Message: No x-default hreflang found.
  • hreflang-self warns when no tag’s resolved href equals the page URL exactly. Message: No self-referencing hreflang found. For a URL that answers with an HTTP redirect, the page URL is the one the redirect ended on, since that is the page whose tags are read: /en/old-slug redirecting to /en/new-slug passes when /en/new-slug references itself.
  • hreflang passes, listing the language codes found. Message: 4 hreflang tag(s) found.

The final pass check is always emitted alongside any warnings, so a page can report both a missing x-default and a count of its tags. The self-reference comparison is on the fully resolved URL, so a self-tag that differs by a trailing slash or a query string does not count. Language codes are not validated, and the return links from the other versions cannot be checked from this page. Severity info, weight 3.

How to fix it

<link rel="alternate" hreflang="en-au" href="https://example.com/au/pricing" />
<link rel="alternate" hreflang="en-gb" href="https://example.com/uk/pricing" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />

Generate the full set from one source of truth so every version lists every other, including itself, with URLs matching the canonical form exactly.

Keep hreflang and the canonical tag consistent: each version should be canonical to itself, not to the primary language.

Rule IDi18n/hreflang
CategoryInternationalization
ScopePer-page
Severityinfo
Weight3/10

Enable / disable

Disable this rule

[rules]
disable = ["i18n/hreflang"]

Disable all Internationalization rules

[rules]
disable = ["i18n/*"]

Enable only this rule

[rules]
enable = ["i18n/hreflang"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

Internationalization findings ship in every audit next to the SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the Internationalization section of the report. Each page is reported with its hreflang codes and any missing x-default or self-reference. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close