Technical SEO

hreflang that breaks language versions: five ways to turn a bilingual site into a monolingual one

The site has two language versions, the switcher works, hreflang is declared — and yet the search engine sees only one language. We break down five real configurations where the language markup is formally there but works against the site.

A bilingual site is not two versions of the text but an agreement with the search engine: this page is in Ukrainian, here is its counterpart in another language, show each person the one that suits them. The agreement is formalized with the hreflang attribute.

The problem is that a broken hreflang looks exactly like a working one: the site opens, the switcher works, the markup is there in the code. The error only becomes visible when you look for it deliberately.

Below are five real configurations we have come across while measuring Ukrainian sites.

1. hreflang set up twice, with the two sets contradicting each other

The most complex case we have seen. On a lingerie store, language markup had been added by two different mechanisms at once — probably by the theme and a separate extension that did not know about each other.

The first set declared ru-ru, uk-ua and pl, pointing to root URLs. The second declared ru, x-default and uk, pointing to URLs with the /ua/ prefix. On top of that, the link declared as uk-ua served Russian content, and the same was true of the Polish one.

For a search engine this is not “two opinions” but a contradiction it resolves at its own discretion — which most often means ignoring both sets.

2. The language code is wrong

On a military gear store, the language versions really did exist — the root one and /ua/. In the markup they were declared as uk-UA and uk-RU.

The second code does not mean “Russian for Ukraine”: the first part is the language, the second is the region. uk-RU reads as “Ukrainian language, Russia region”. The correct code for a Russian-language version of a Ukrainian site is ru-UA.

An extra touch on the same site: <html lang="ru"> on the root version, meaning the page’s language attribute contradicted what hreflang declared.

A separate variant of this error turned up in a sample of construction companies: the same language code declared twice — one site out of eight checked on 8 August 2026.

3. The sitemap contains only one language version

The site is bilingual, hreflang is declared correctly — but the sitemap has URLs in only one language. The second version exists for a person using the switcher and does not exist for a crawler that starts from the sitemap.

From real measurements:

  • a spice store: all 590 unique URLs in the sitemap point to the Russian version, even though the code has <html lang="uk"> and hreflang for Ukrainian is declared;
  • a tool store: 100% of the URLs in the sitemap are Russian-language, while the site serves Ukrainian by default;
  • a garden equipment store: the sitemap has only the Ukrainian-language branch; the Russian version is declared in hreflang but did not make it into the sitemap;
  • a wholesale cosmetics store: not a single Russian-language URL in the sitemap, despite full bilingual support with a switcher.

There is no pattern in which language “disappears” — and that is the best proof that the cause is technical, not content-related: that is simply how the sitemap generator ended up configured, and nobody checked the result.

4. Interface translated, meta tags not

A subtler case. The language version exists, the interface is translated, <html lang="uk"> is set correctly — but the <title> and meta description stayed in the original language.

We saw this on the lingerie store: the Ukrainian-language /ua version had a translated interface and the correct language attribute, but its meta tags remained Russian. To a search engine such a page looks like a duplicate — meta tags are the primary way it tells pages apart.

This is the classic partial localization mistake: what is visible in the layout gets translated, and what is visible only in search results does not.

5. hreflang is there, but the second version is not

The reverse case: the markup declares language versions that physically do not exist — a leftover from plans or from a template. The search engine follows the link, gets a 404 or a redirect to the same page, and stops trusting the entire group.

A separate variant is hreflang with only one entry pointing to the page itself, plus x-default. Formally not an error, in practice markup that does nothing: a group of one page does not connect it to anything.

How to check your site

  1. Open the Ukrainian homepage and view the source: find all lines containing hreflang. There should be as many as you have language versions, plus x-default if needed.
  2. Check the language codes: uk-UA for Ukrainian, ru-UA for the Russian-language version of a Ukrainian site. Each code should appear exactly once.
  3. Open each hreflang link and make sure it opens exactly the language that is declared, and that the page returns 200, not a redirect.
  4. Check reciprocity: the page that hreflang points to must link back to the first one. Search engines ignore one-sided declarations.
  5. Compare <html lang> with what hreflang declares — they should match.
  6. Check the sitemap: does it contain URLs for both language versions?
  7. Check the <title> and meta description on the second language version — they should be translated, not inherited.

How much work is involved

The markup itself takes hours: it is a block of links in <head> generated from the list of a page’s language versions. What can be harder is untangling a situation where the theme and an extension both add markup at the same time: first you need to find both sources and disable one.

The most expensive item is usually the fourth — translating meta tags on every page of the second language version. This is no longer technical work but content work, and on a catalog of thousands of items it requires either a translator or automation followed by spot checks.

The limits of this data

The figures are measurements taken on specific dates (August 2026); we deliberately do not name the sites. The market sample of construction companies that the duplicated language code example comes from consisted of eight sites — so the “1 of 8” share describes those particular sites, not the market.

Tags

SEO

Did you like the article?

Your opinion helps us create better content

Share with friends

Found something useful?

Help others learn about it - share the article on social networks

Thank you for helping us grow

Founder of LIONEX

Vladyslav Chystiakov

Writes about what he builds himself: online stores on OpenCart, applications on Next.js, integrations and site speed. The articles carry measurements and checks a reader can repeat on their own project, not general advice. Commercial development since 2015.

Questions

Frequently asked questions

Answers to common questions on the topic

What is the correct hreflang code for a Russian-language version of a Ukrainian site?

ru-UA: the first part is the language, the second the region. The code uk-RU, which we found on one measured site, reads as "Ukrainian language, Russia region" — not what was intended.

Can hreflang be declared twice?

Technically yes, and it is a real defect: a theme and a separate extension add markup independently of each other. We saw a site where two sets contradicted each other, and the URL declared as the Ukrainian version served Russian content.

Why does a second language version stay out of the index if hreflang is correct?

The most common reason is that the sitemap contains URLs for only one language. Crawling starts from the sitemap, and the second version remains reachable only through internal links.

Is translating the interface enough for a language version to work?

No. If the title and meta description remain in the original language, the page looks like a duplicate to a search engine — meta tags are the primary way it tells pages apart. This is the classic partial-localisation mistake.

What is hreflang reciprocity and why does it matter?

If page A declares page B as its language version, page B must declare A in return. One-sided declarations are ignored — the group is treated as incomplete.

Get the best articles by email

Subscribe to our newsletter and receive useful tips, insights and news about web development, marketing and business.

We respect your privacy. You can unsubscribe at any time.