International SEO — hreflang, subfolders and canonicals done right
Why international SEO is the make-or-break detail
A multilingual site that isn’t technically wired up correctly fails in two predictable ways. First: Google ranks the English version in the German market because English has more backlinks and the hreflang link is missing — the German user lands on a language they didn’t expect and bounces. Second: the two language versions cannibalize each other in the index because canonicals point cross-locale and Google treats the German page as a duplicate of the English one. In both cases, the problem isn’t the content — it’s the missing clarity in meta signals.
This article walks through how to combine the three core building blocks — URL structure, hreflang and canonical — so each locale gets its own identity while still being recognizable as part of a family. The examples assume a typical EN/DE setup; the principles scale to any number of languages.
The core mechanic: three signals, three jobs
International SEO works through three independent technical signals. Each answers a different question — and each must be correct on its own for the system to hold together.
URL structure — where does each language live?
Google needs to recognize from the URL alone which language a page is served in. Three patterns are established:
- ccTLD (
example.de,example.fr): strongest geo signal, highest maintenance overhead (separate domains, separate authority pools, separate hosting). Sensible when markets are genuinely separate — different legal frameworks, different marketing teams. - Subdomain (
de.example.com,en.example.com): medium effort, medium signal. Google sometimes treats subdomains as separate properties — authority has to be built up per subdomain. - Subfolder (
example.com/de/,example.com/en/): the pragmatic default for most sites. One domain, one authority pool, simple hreflang maintenance. Standard for SaaS, agency sites and content platforms.
Subfolders win in practice almost every time, unless the markets are legally or organizationally fully separate. The article uses the subfolder pattern as the reference from here on.
hreflang — which language version is for whom?
hreflang is the explicit annotation: “this page also exists in German at URL X, in English at URL Y, in French at URL Z”. Three properties are non-negotiable:
- Bidirectional. If
/de/produktpoints to/en/product, then/en/productmust point back to/de/produkt. If the back-reference is missing, Google ignores the entire annotation. - Self-reference. Each page also lists itself in its hreflang tags.
/de/produktincludes an hreflang to/de/produkt. Without self-reference the set is incomplete. - BCP 47 codes. Language only (
de,en) or language plus region (de-AT,en-US). Neverde-DEas shorthand for “generic German” — it pointlessly narrows the scope to Germany.
Canonical — which URL is the official one?
The canonical tag decides which of several same-language URL variants is the primary one. For international SEO the rule is simple and non-negotiable: each locale references itself. /en/product has canonical /en/product. Never cross-locale to /de/produkt.
Cross-locale canonicals are the most common killer of multilingual sites — Google reads it as “the German page is just a variant of the English one, the English one is the main version” and drops the German page from the index.
Pitfalls — what goes wrong in practice
Missing self-reference and x-default
Many sites only list the other languages per page, not their own. But Google requires the complete set including self-reference. Equally common: missing x-default — the fallback signal for languages that aren’t explicitly covered. A user from Spain who picked neither EN nor DE should land on the x-default version.
Cross-locale canonicals from CMS defaults
Some CMS automatically set a canonical to the “master language”. That’s intended for pure translation plugins, but in an international SEO setup it’s fatal. Before launch, always sample manually: view-source on a DE page and an EN page, check both canonicals — they must point to themselves.
IP-based auto-redirect
If you redirect users automatically by IP to the “right” language, you lose visibility of the other locales for crawlers. Googlebot crawls from US IPs — auto-redirect always lands it on the EN version, the DE pages are never seen. Clean solution: language-picker banner without redirect, the user decides.
Inconsistent URLs between hreflang and canonical
A classic bug: hreflang points to /de/produkt, but the canonical on the page points to /de/produkt/. Trailing slash, http vs. https, www vs. non-www — every variant must be consistent. Google follows the canonical and ignores the hreflang if the URLs don’t match exactly.
Sitemap entries pointing to 301 redirects
If you maintain hreflang in the sitemap (instead of the HTML head), make sure none of the listed URLs hits a redirect. As soon as Google encounters a 301 on an hreflang target, it discards the whole annotation for that page.
Implementation — three places hreflang can live
Option 1: HTML head (default)
<link rel="canonical" href="https://example.com/en/product/">
<link rel="alternate" hreflang="en" href="https://example.com/en/product/">
<link rel="alternate" hreflang="de" href="https://example.com/de/produkt/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/product/">
Works for any HTML response. Maintenance grows linearly with the number of languages but is easy to handle from a templating layer.
Option 2: HTTP header
For non-HTML resources (PDFs, multilingual whitepapers) the only viable path:
Link: <https://example.com/en/whitepaper.pdf>; rel="alternate"; hreflang="en",
<https://example.com/de/whitepaper.pdf>; rel="alternate"; hreflang="de"
Option 3: XML sitemap
For very large sites (>10,000 URLs per language) the performance winner — the annotation lives centrally in the sitemap, the HTML head stays slim:
<url>
<loc>https://example.com/en/product/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/product/"/>
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/produkt/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/product/"/>
</url>
Important: don’t mix. Maintaining hreflang in the head and in the sitemap invites conflicts and drift.
Reference table: URL structure and implementation
| Criterion | ccTLD | Subdomain | Subfolder | |---|---|---|---| | Geo signal | very strong | medium | weak (offset by hreflang) | | Authority build-up | separate per domain | mostly separate | shared | | Hosting | per domain | per subdomain | shared | | hreflang maintenance | high | medium | low | | Sensible when | truly separate markets | medium separation | default for multilingual sites | | Example | example.de / example.fr | de.example.com | example.com/de/ |
| hreflang location | Pro | Con | |---|---|---| | HTML head | visible everywhere, easy to debug | bloats head with many languages | | HTTP header | the only option for non-HTML | harder to audit | | XML sitemap | scales for >10k URLs | possible conflicts with head tags |
Worked example: EN/DE site with subfolders
A SaaS has content in English and German, hosted on example.com with subfolder structure. The product page exists in both languages.
HTML head of the EN page (/en/product/):
<link rel="canonical" href="https://example.com/en/product/">
<link rel="alternate" hreflang="en" href="https://example.com/en/product/">
<link rel="alternate" hreflang="de" href="https://example.com/de/produkt/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/product/">
HTML head of the DE page (/de/produkt/):
<link rel="canonical" href="https://example.com/de/produkt/">
<link rel="alternate" hreflang="en" href="https://example.com/en/product/">
<link rel="alternate" hreflang="de" href="https://example.com/de/produkt/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/product/">
Three things that are right here:
- Self-reference on both pages (each page lists itself).
- Bidirectionality: EN points to DE, DE points back to EN.
- Canonical per locale: each page points to itself, never cross-locale.
x-default here points to the EN version because that’s the international default. On a site with a dedicated language-picker landing page, x-default would point to that picker.
Worked example: spotting broken markup
A quick audit routine for an existing site:
- Browser DevTools → View Source on an EN page. Check: canonical points to EN URL? Self-reference present? hreflang set complete?
- Same on the matching DE page. Check: does the DE hreflang point to exactly the EN URL from step 1?
- Search Console → International Targeting: any missing return links flagged?
curl -Ion a DE URL: no 301 redirects on the hreflang path? Trailing slash consistent?
A typical finding: the EN page references https://example.com/de/produkt in hreflang, but the actual DE URL is https://example.com/de/produkt/ (with slash). Both pages still rank — but the hreflang link doesn’t connect, and the locales compete in the index.
FAQ
- de is enough for "German in general". Use de-DE, de-AT, de-CH only if you really maintain country-specific versions (different prices, different terms, different phone numbers). Otherwise the set grows unnecessarily and becomes harder to keep in sync.
- Don't set any hreflang annotation. The page just ranks in its language. As soon as a translation is added, link both.
- Strictly speaking no, in practice almost always recommended. There are more languages than the ones you cover — x-default tells Google what to show users browsing in Spanish, Japanese or Portuguese. Common pattern: x-default points to the EN version or the language-picker page.
- Days to weeks. Google has to re-crawl all affected pages and verify bidirectionality. For larger sites, trigger a re-indexing through Search Console.
- Works in principle, but is more fragile. Server-side in the HTML head is the robust path. If you're running an SPA, maintain hreflang via the sitemap.
Do I need de-DE or is de enough?
What about pages that only exist in one language?
Do I need x-default if all my languages are covered?
How fast do hreflang changes take effect?
What about JavaScript-rendered hreflang tags?
Check before every launch
Sample one page per language: view-source, verify canonical and hreflang set. A single wrong canonical can knock a whole locale out of the index.
Conclusion
International SEO isn’t magic — it’s clean mechanics with three building blocks: URL structure, hreflang and canonical. Get the three right — subfolder as default, hreflang bidirectional including self-reference and x-default, canonical always pointing to its own locale — and 90% of the issues are solved before they appear.
The most common failures are structural, not editorial: cross-locale canonicals, missing self-reference, inconsistent URLs. Before each launch and after each template change, a ten-minute audit routine via view-source and Search Console is the cheapest SEO lever you have in a multilingual setup.
If you’re building a new site: start with subfolders, maintain hreflang in the HTML head, lock canonicals to their own locale. If you’re inheriting an existing site: audit the three signals first, before anyone touches content. Visibility losses caused by broken markup take weeks to recover after a fix — caution pays off many times over.
Entdecke mehr
301 Redirect
A 301 redirect is an HTTP status code permanently redirecting one URL to another — the standard for URL changes, domain moves and site migrations.
LexikonTechnical SEO — what Google actually has to crawl, render and index
How crawl budget, robots, sitemap, JS rendering, indexing, canonical and Core Web Vitals fit together — the full arc for production sites.
NewsGoogle Search Central Live Toronto 2026 — what Google officially said about the future of search
Information Gain as the new guideline, Google-Extended clarified, AI Mode with 93% zero-click. The key statements from Toronto.