← Back to blog
Tips & Tricks· September 28, 2026 ·8 min read

Multilingual SEO: hreflang, subfolders and not shooting yourself in the foot

Done right, going multilingual multiplies your search traffic. Done wrong, hreflang gets silently ignored and nobody tells you. Here are the rules and the five ways people break them.

Mads Edelskjold
Mads Edelskjold
Founder, NordicCDN · ex-datacenter CTO
Multilingual SEO: hreflang, subfolders and not shooting yourself in the foot
The short version

Give each language its own crawlable URL — subfolders such as /fr/ are safest — and connect the versions with hreflang annotations. hreflang must be reciprocal, must include a self-reference, must use valid language and region codes, and must point at indexable canonical URLs. Break any of those and Google ignores the annotation entirely, without reporting an error.

The thing that makes multilingual SEO frustrating is that it fails quietly. A broken redirect throws an error. A broken hreflang annotation does nothing at all — Google reads it, cannot verify it, discards it, and your language versions go on competing with each other while every tag looks correct in your source.

So this is a reference for getting the structure right, followed by the specific ways it gets broken.

Structure first: give each language a real URL

Search engines rank pages they can reach and distinguish. Each language therefore needs its own distinct, crawlable address, and you have three realistic options.

StructureExampleAuthorityVerdict
Subfoldersexample.com/fr/Shared across languagesRecommended
Subdomainsfr.example.comSplit per subdomainWorkable
Country domainsexample.frEntirely separateOnly for genuine country targeting
Parametersexample.com?lang=frIndexed inconsistentlyAvoid

Subfolders win for most sites because every language contributes to and benefits from one domain's authority. Country-code domains are a real option, but only when you are genuinely targeting countries rather than languages, and each one is a separate site to build authority for from scratch — a commitment people underestimate.

Language or country?

A distinction worth getting right early, because it determines your URL structure and you will not want to change it later. Are you serving French, or are you serving France?

If the content is identical for every French speaker, you want a language-only structure: /fr/, annotated hreflang="fr". If prices, shipping, legal terms or product availability differ between France, Belgium and Canada, you want language-region: /fr-fr/, /fr-be/, /fr-ca/. Do not create regional variants you do not actually need — each one is another page to maintain and another set of annotations to keep reciprocal.

hreflang, and the rules that are actually enforced

hreflang tells search engines that several URLs are the same content in different languages, so the right version reaches the right searcher and the versions are not treated as duplicates competing with one another.

/en/ /fr/ /de/ hreflang links them as the same page, in different languages
hreflang turns three apparent duplicates into one page with three language versions.

A correct set on the English page looks like this, and the same block — identical, unchanged — appears on the French and German pages too:

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

Three properties of that block matter more than anything else:

It is reciprocal. Every page in the set lists every other page in the set. Google treats a one-directional annotation as unconfirmed and discards it.

It includes a self-reference. The English page lists the English URL. This is required, is easy to omit, and its absence invalidates the set.

It is identical on every page. Which is the practical reason it works: generate the block once and output the same one everywhere, rather than trying to compute "the others" per page.

The x-default entry names the version for searchers who match nothing in the set. It is optional but worth setting deliberately, or you leave that choice to a guess.

The five ways this breaks

1. Non-reciprocal annotations

The most common failure by a wide margin. The English page lists French, the French page lists nothing, and the whole set is discarded. Usually caused by generating annotations from a per-page list that is incomplete for translated pages.

2. Invalid language or region codes

The format is an ISO 639-1 language code, optionally followed by a hyphen and an ISO 3166-1 alpha-2 country code. en-GB is valid. en-UK is not, because the country code is GB. fr-FR is valid; fr-FRA is not. And there is no such thing as hreflang="eu" for Europe — the region half must be a country. Invalid codes are silently ignored.

3. hreflang pointing at non-canonical URLs

hreflang and canonical tags have to agree. If your French page's canonical points at the English version — which happens when a template hardcodes it — you have told Google the French page is a duplicate of the English one, and the hreflang set is meaningless. Each language version must be canonical to itself.

4. Pointing at URLs that redirect or are blocked

An annotation pointing at a URL that 301s somewhere else, returns a 404, or is disallowed in robots.txt cannot be verified. Use the final, absolute, indexable URL — including the protocol and, if relevant, the trailing slash your site actually serves.

5. Automatic redirects based on browser language

The subtle one, and the most damaging. Detecting Accept-Language and force-redirecting is a bad idea for two separate reasons.

For humans: a French speaker in London may deliberately want your English page, a developer may need the original, and a visitor sent somewhere they did not choose with no obvious way back is a visitor who leaves. Language preference is not a language capability.

For crawlers: Googlebot crawls predominantly from US IP addresses with no language preference expressed. If you redirect it, you may find only your English pages ever get discovered, and the translated versions you paid for are never indexed at all.

Suggest, do not force. A dismissible banner offering the French version is helpful; an automatic 302 to it is not. Let hreflang steer search results and let the visitor steer their own browsing.

Checking your work

  • View source on a translated page and confirm the hreflang block is present, includes a self-reference, and is identical to the one on the original.
  • Follow every URL in the block. Each should return 200, not a redirect, and be canonical to itself.
  • Check the canonical tag on each version points at that version, not at the original language.
  • Use Search Console's international targeting data where available, and a dedicated hreflang validator to catch reciprocity errors across a whole site at once.
  • Confirm every language is in your sitemap with its own entry, so crawlers can discover translated pages without depending on link discovery.

Frequently asked questions

What is hreflang and do I need it?

hreflang is an HTML annotation telling search engines that several URLs are the same content in different languages or regional variants, so the appropriate version is shown to each searcher and the versions are not judged as duplicates of one another. You need it as soon as you publish the same content in more than one language on crawlable URLs.

Should I use subfolders or subdomains for different languages?

Subfolders, such as example.com/fr/, for most sites. All languages then share one domain's accumulated authority, and setup at the CDN or server is simpler. Subdomains work but split authority across hostnames. Country-code domains such as example.fr are appropriate only when genuinely targeting countries rather than languages, since each is effectively a separate site to build authority for.

Why is my hreflang not working?

Most often because the annotations are not reciprocal — every page in the set must list every other page, including itself, and Google discards sets it cannot confirm from both directions. Other common causes are invalid codes such as en-UK instead of en-GB, hreflang URLs that redirect or are blocked in robots.txt, and canonical tags on translated pages that point back at the original language.

Does hreflang need to be on every page?

Yes. Annotations are per-URL, not per-site, so each page needs a block naming its own equivalents in the other languages. The block should be identical across all versions of that page and must include a self-reference. hreflang can alternatively be supplied in HTTP headers or in an XML sitemap, which is often easier to maintain at scale.

Should I redirect visitors based on their browser language?

No. Automatic redirects override deliberate choices — a French speaker may want the English version — and they interfere with crawling, since Googlebot crawls largely from US addresses without a language preference and may therefore never discover your translated pages. Offer a dismissible suggestion banner and a visible language switcher instead, and let hreflang handle search results.

Is translated content considered duplicate content?

No. Content translated into another language is not duplicate content, and correctly implemented hreflang makes the relationship explicit so versions do not compete with one another. Problems arise from near-identical pages within the same language — for example separate pages for the UK and Australia with identical English text — where hreflang with region codes and correct self-referencing canonicals is what keeps them distinct.

Get the structure decided before you translate anything, generate one identical hreflang block per page set, never force a redirect, and multilingual SEO becomes maintenance rather than archaeology. The alternative is discovering in six months that none of it was ever counted.

#seo #multilingual #hreflang #i18n
Put it into practice

See how NordicCDN does this for your site:

Mads Edelskjold
Written by
Mads Edelskjold — Founder, NordicCDN · ex-datacenter CTO

Mads has worked in IT — mostly hosting — since he was 16. He took an early stake in a SaaS company and helped grow it through to its acquisition by Visma, has built and run data-center networks, and served as CTO of a Danish data center. He started NordicCDN to make fast, secure infrastructure simple to use.

Make your site load instantly

Start free in two minutes — no card required.

Start free