Skip to content

SEO & Growth3 min read

hreflang for a three-language site: how onlyapps.org is set up

One URL per language, hreflang with return links, self-referencing canonicals, sr-Latn for Serbian and 404 instead of a silent English fallback — the rules behind our English, Serbian and Russian pages.

Our site speaks English, Serbian and Russian. For people that is a language switcher in the header; for search engines it is a set of rules that decides which version shows up for whom. Get them wrong and the Russian page competes with the English one, or a Serbian searcher lands on a page they cannot read. Here is how we set it up.

One language, one address

Every language lives at its own URL: English at the root, Serbian under /sr/, Russian under /ru/. The content of a page never depends on cookies or on the browser language, so a crawler that follows a link always sees the same version a visitor would.

hreflang tells engines which page is for whom

Each page lists all of its language versions — including itself — plus an x-default for everyone else. This is the head of the Russian version of this article:

html
<link rel="canonical" href="https://onlyapps.org/ru/blog/hreflang-three-languages" />
<link rel="alternate" hreflang="en" href="https://onlyapps.org/blog/hreflang-three-languages" />
<link rel="alternate" hreflang="sr-Latn" href="https://onlyapps.org/sr/blog/hreflang-three-languages" />
<link rel="alternate" hreflang="ru" href="https://onlyapps.org/ru/blog/hreflang-three-languages" />
<link rel="alternate" hreflang="x-default" href="https://onlyapps.org/blog/hreflang-three-languages" />

A few details matter:

  • Return links. Every version must point to every other version. If the Russian page lists the English one but not the other way round, engines may ignore the pair.
  • Self-referencing canonical. Each language version is canonical to itself. Pointing all canonicals to English would tell search engines that the translations are duplicates.
  • Language tags. Values follow BCP 47. Serbian is written in two scripts, so we mark our version as sr-Latn — Serbian in Latin script.
  • x-default. English is the fallback for languages we do not support.

Untranslated means 404, not a fallback

When a post exists only in English, /ru/blog/... returns 404 instead of quietly showing the English text under a Russian address. That keeps every indexed URL honest: the language in the address is the language on the page. The hreflang set only lists translations that actually exist, and the language switcher sends you to the matching translation — or to the home page in that language when there is none.

Sitemaps repeat the same story

Our sitemaps list every published page in every language and attach the same alternates to each URL. Search engines can then learn the relationships without loading every page, and the dates in lastmod change only when the content changes.

CheckWhat correct looks like
URL structureOne URL per language, no cookie-based switching
hreflangAll versions listed on every version, plus x-default
CanonicalEach version canonical to itself
Missing translation404 in that language, not a copy of English
SitemapSame alternates as in the page head

Mistakes we see most often

  • Translating the interface but leaving the main text in English under a localized URL.
  • Redirecting visitors by IP, which hides the other versions from crawlers.
  • Mixing region and language: ru-RU limits a page to Russia, while ru targets Russian speakers everywhere.
  • Forgetting to update alternates when a translation is removed.

Tip

After any change, open the page source in each language and check that the canonical and the hreflang set are identical across versions — except for the canonical, which always points to the page itself.

Want to see it live? Switch the language at the top of this page — you will land on this article's translation.

ShareXLinkedIn

ONLYAPPS team

Novi Sad, Serbia · onlyapps.org

Contact

We use analytics cookies only with your consent. Essential cookies keep the site working. Privacy policy