3.54 min read

Hreflang and canonical: the correct setup (and the #1 mistake that breaks indexing)

Key takeaways

  • Hreflang tells Google which language/region version to show
  • Canonical tells Google which URL is the primary for indexing
  • If you mix them wrong (especially cross-language canonicals), Google ignores hreflang and collapses your cluster

Most “hreflang issues” are canonical issues in disguise.

You think you are telling Google “show EN to EN users, RU to RU users”, but your canonicals tell Google “actually, only EN is the real page”.

This guide is the missing glue between:

TL;DR (the rule you can remember)

  • hreflang = routing (which version to show)
  • canonical = indexing preference (which URL is the primary)

For multi-language sites, the default correct pattern is:

  • each language page is canonical to itself
  • each language page lists all alternates via hreflang (reciprocal)
  • optional x-default points to your neutral fallback

The #1 mistake:

Your RU page canonicalizes to the EN page (or vice versa).

That collapses the cluster. Google will often ignore your hreflang annotations because you told it the alternates are not primary pages.

Minimal correct setup (HTML example)

Let’s say you have the same intent in two languages:

  • EN: https://casinokrisa.com/start
  • RU: https://casinokrisa.ru/start

On the EN page:

<link rel="canonical" href="https://casinokrisa.com/start" />

<link rel="alternate" hreflang="en" href="https://casinokrisa.com/start" />
<link rel="alternate" hreflang="ru" href="https://casinokrisa.ru/start" />
<link rel="alternate" hreflang="x-default" href="https://casinokrisa.com/start" />

On the RU page:

<link rel="canonical" href="https://casinokrisa.ru/start" />

<link rel="alternate" hreflang="en" href="https://casinokrisa.com/start" />
<link rel="alternate" hreflang="ru" href="https://casinokrisa.ru/start" />
<link rel="alternate" hreflang="x-default" href="https://casinokrisa.com/start" />

Notes:

  • Canonical is self-referential for each language page.
  • hreflang is reciprocal (each points to the other).
  • x-default is optional and is usually your global/fallback URL.

What canonical is not doing here

Canonical is not “pick the best language”.

Canonical is about duplicates: parameter URLs, multiple paths, print views, tracking, etc.

If your EN and RU pages are different language versions of the same intent, treat them as a cluster (hreflang), not as duplicates to collapse (canonical).

Related GSC statuses you might see when the setup is wrong:

When cross-language canonicals can be correct (rare)

Only do this if you truly want one language to be the only indexable version.

Examples:

  • a translated page is a placeholder and you want it out of index permanently
  • you do not maintain the translation and want everything consolidated

In that case:

  • canonicalize the non-primary language to the primary one
  • do not keep hreflang between them (it’s contradictory)

If you still want both indexed and served, do self-canonicals + hreflang.

Common failure modes (quick checklist)

1) Hreflang points to URLs that redirect

Hreflang targets should be clean, crawlable 200s (no chains).

If you have redirect noise, fix that first:

2) Canonical URL does not match the page URL (without a reason)

If your RU page has:

  • hreflang says “RU exists”
  • canonical says “RU is not primary”

Google will pick one truth. Often: canonical wins.

3) Missing reciprocity

EN points to RU, but RU does not point back.

Google commonly ignores the cluster when reciprocity is broken.

4) Wrong language/region codes

Use valid BCP 47-ish patterns (en, en-US, ru, ru-RU) and be consistent.

5) Different canonicalization rules across hosts

If you run .com and .ru, make sure:

  • both are crawlable and indexable (not blocked, not “noindex”)
  • both are consistently HTTPS / trailing slash decisions
  • both versions exist for the same intent (or you do not declare them as alternates)

How to validate in Google Search Console (practical)

For each language URL:

  1. Open URL Inspection
  2. Check:
    • User-declared canonical: should be the same URL (self-canonical) in the normal pattern
    • Google-selected canonical: may differ at first, but should converge as the cluster stabilizes
  3. Watch the “Page indexing” status over time:
    • “Duplicate…” and “Alternate…” signals often correlate with canonical/hreflang inconsistencies

If you want the bigger map of what each status means:

Next.js note (if you generate tags in code)

If you use Next.js metadata, the same logic applies:

  • set alternates.canonical to the current language URL
  • set alternates.languages to the other language URLs (plus optional x-default)

The tech changes, the rule does not: don’t declare alternates, then canonicalize them away.

Next in SEO & Search

View topic hub

Up next:

Entity-first SEO for personal brands (2026): a practical checklist that gets you indexed, trusted, and surfaced

Entity-first SEO is how Google connects pages into “who this is” and “why it’s credible”. This checklist shows how to build a personal brand entity (Person/Organization, sameAs, rel=me, author signals, hubs, and internal linking) so your site becomes easier to interpret and worth indexing.