Command Palette

Search for a command to run...

Hreflang vs Canonical: How They Work Together

Hreflang vs Canonical: How They Work Together

T
Toolz Team
|Aug 23, 2026|11 min read

Part of the SEO Tools collection

The worst hreflang bug I have shipped was a one-line template change that took four language versions out of Google's index. The head partial rendered a canonical tag, and someone refactored it so the canonical was built from the default locale rather than the current one. Every translated page started declaring the English page as its canonical. The hreflang annotations were untouched and still perfect. They were also completely irrelevant, because you cannot serve a URL that has been canonicalized out of the index.

Nothing broke. The pages still loaded. Traffic from the non-English markets fell off over about three weeks, which is roughly how long it took Google to recrawl everything, and by the time it was obvious the cause was five commits back.

Canonical and hreflang are the two annotations most likely to be confused with each other and the two most likely to cancel each other out. This guide covers what each one claims, the rule that keeps them compatible, and the specific combinations that go wrong. It sits under the complete hreflang guide, next to 12 common hreflang errors.

TL;DR: A canonical tag says "of these near-duplicate URLs, index this one." An hreflang annotation says "these URLs are localized alternates, serve the right one per user." They answer different questions and must not contradict each other. The rule is that every page canonicalizes to itself, and hreflang describes the relationships between those self-canonical pages. Canonicalizing one language version to another removes it from the index and makes the hreflang set pointless, because canonical is the stronger signal.

What does a canonical tag claim?

A canonical tag nominates the preferred URL among a group of URLs that serve substantially the same content:

<link rel="canonical" href="https://example.com/pricing" />

It exists because the same content is reachable at many URLs: with and without tracking parameters, with and without a trailing slash, through a print view, through a category path and a direct path. Left alone, Google picks one and consolidates the ranking signals onto it. The canonical tag is how you make that pick yourself.

Two properties matter for this discussion. First, it is a hint, not a directive, though a strong one that Google follows most of the time. Second, and this is the part that bites, the non-canonical URLs stop being indexed in their own right. Their signals are folded into the canonical. That is the whole point of the tag, and it is exactly the wrong thing to do to a translation.

What does hreflang claim?

Hreflang makes a different claim entirely:

<link rel="alternate" hreflang="de-DE" href="https://example.com/de/preise" />

It says: another version of this page exists, it is aimed at German speakers in Germany, and here is where it lives. It says nothing about which URL should be indexed. All of the alternates are expected to be indexed, independently, each ranking in its own market. Hreflang is a routing hint applied at serve time, not an indexing instruction.

Put the two side by side and the difference is clear:

Canonical Hreflang
Question it answers Which of these URLs should be indexed? Which version should this user see?
Effect on the other URLs They stop being indexed separately They stay indexed, each in its market
Applies to Duplicate or near-duplicate content Translated or regionalized content
Direction Points to one winner Describes a symmetric set
Strength Strong; usually followed A hint used at ranking and serve time

Translated pages are not duplicates. They are different content for different audiences that happens to be structurally parallel. Treating them as duplicates with a cross-language canonical is the category error at the root of every failure below.

What is the rule?

Every page canonicalizes to itself. Hreflang describes the relationships between those self-canonical pages.

Concretely, the English pricing page carries:

<link rel="canonical" href="https://example.com/pricing" />
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="de" href="https://example.com/de/preise" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />

And the German pricing page carries the identical hreflang block with a different canonical:

<link rel="canonical" href="https://example.com/de/preise" />
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="de" href="https://example.com/de/preise" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />

Same hreflang set on both, self-referential canonical on each. That is the whole pattern. Google documents the same requirement in its localized versions guidance: the annotations must be reciprocal, and the URLs they name must be the ones you want indexed.

What happens when the canonical points across languages?

The language version disappears.

Walk through it. The French page says "index the English page instead of me." Google obliges and drops the French URL from the index. The English page's hreflang says "the French version is at this URL." Google looks at that URL, finds it is canonicalized to the page it is already on, and has nothing to serve French searchers. The set collapses to one page.

The symptom is a language version that is crawled, returns 200, contains good translated content, and never ranks. In Search Console the URL Inspection tool reports it as an alternate of another page rather than as indexed. That report is the fastest way to confirm the diagnosis, and if you are chasing a language version that will not rank, check it before anything else.

The reason canonical wins is that the two signals operate at different stages. Canonicalization happens during indexing; hreflang is consulted during ranking and serving. A URL that never enters the index is not available at the later stage.

What about parameters and near-duplicates within one language?

This is where both signals are legitimately in play at once, and the combination is fine as long as you keep the layers straight.

Say the German pricing page is reachable at /de/preise and /de/preise?utm_source=newsletter. The parameterized URL canonicalizes to /de/preise, which is correct: they are genuine duplicates within one language. The hreflang set operates one level up, between /pricing, /de/preise, and /fr/tarifs, and it names only the canonical form of each.

Two rules keep this clean:

  1. Hreflang always names canonical URLs. Never point an annotation at a parameterized or otherwise non-canonical URL. The return tag on that URL will not match, because the canonical version is the one carrying the block.
  2. Canonicalize within a language, never across. Parameters, print views, session URLs, all fine. Another language, never.

The same logic covers pagination, faceted URLs, and any other duplication mechanism. Resolve it inside the language, then let hreflang describe the resolved set.

Does hreflang help with duplicate content across regions?

Partly, and the distinction is worth being precise about because it is often overstated.

Hreflang does not deduplicate. It does not tell Google to ignore the similarity between your US and UK English pages. What it does is tell Google those pages are deliberate regional variants, which changes how Google handles the similarity: instead of picking one and filtering the other, it keeps both and selects per query and per user.

That is the practical benefit for same-language, multi-region sites, and it is the reason those sites need hreflang more urgently than multi-language sites do. Two pages in different languages are obviously different documents. Two pages in English with different prices and spellings are not obviously different to a crawler, and without the annotation one of them loses.

If the regional pages are genuinely identical, word for word, the honest answer is that you may not need separate pages at all. Hreflang is not a way to justify near-duplicate content; it is a way to describe content that is legitimately differentiated by market.

How do you audit the two together?

A crawl that extracts both annotations answers this in one pass. For each URL, you want two facts: does its canonical equal its own URL, and does its hreflang set match its siblings'. Sort by canonical and look for groups where several URLs share one canonical across different language paths. That grouping is the bug, and it is visible at a glance.

For a single page, curl it and read both tags together:

curl -s https://example.com/de/preise | grep -E 'rel="(canonical|alternate)"'

What you are checking is that the canonical href is the URL you just fetched, and that the hreflang block contains an entry for this page's own locale pointing at the same URL. Those two facts being consistent is most of the battle.

Then check that the hreflang targets are themselves self-canonical. A set can be perfectly reciprocal and still fail because one of the targets canonicalizes elsewhere, which is the failure at the top of this article and the one that is invisible from the page you are looking at.

What about canonical and the sitemap?

Same principle, extended. A sitemap should list canonical, indexable URLs only. If your sitemap carries hreflang annotations as xhtml:link entries, those entries name the same canonical URLs the HTML would.

The failure mode here is a sitemap generated from a route table rather than from the indexable URL set, so it lists parameterized or non-canonical variants alongside the real ones. Google treats sitemap inclusion as a weak canonicalization hint, so a sitemap that disagrees with your canonical tags is one more contradictory signal. The XML Sitemap Generator is a quick way to rebuild a clean list when you are not sure what is currently in there, and the hreflang generator tool produces the matching xhtml:link block in the sitemap format.

Frequently asked questions

What is the difference between hreflang and canonical?

A canonical tag nominates which of several near-duplicate URLs should be indexed. An hreflang annotation declares that several URLs are localized alternates and helps search engines serve the right one per user. Canonical consolidates; hreflang differentiates.

Should each language version canonicalize to itself?

Yes. Every page in a hreflang set must have a self-referential canonical. Canonicalizing a translated page to another language removes it from the index and makes the hreflang set useless.

Which signal wins if hreflang and canonical disagree?

Canonical, in effect. Canonicalization happens at indexing time, and a URL that is not indexed cannot be served to anyone, whatever the hreflang annotations say.

Can I use canonical tags on a multilingual site at all?

Yes, and you should. Use them to resolve duplication within a language, such as tracking parameters and print views. Never use them across languages.

Does hreflang fix duplicate content between my US and UK pages?

It does not deduplicate, but it tells Google the pages are deliberate regional variants rather than accidental duplicates, so both stay indexed and the right one is served per market. That is the main reason same-language multi-region sites need hreflang.

Should hreflang point at canonical URLs?

Always. Pointing an annotation at a parameterized or non-canonical URL breaks the return tag, because the block lives on the canonical version rather than the variant you named.

How do I tell if a canonical is killing a language version?

Run the URL through Search Console's URL Inspection tool. If it reports the page as an alternate of another URL rather than as indexed, a cross-language canonical is the cause.

Do sitemap URLs need to match my canonical tags?

Yes. Sitemaps should list canonical, indexable URLs only. A sitemap that lists non-canonical variants adds a contradictory signal on top of the tags you already emit.


Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!