International SEO: the technical setup
·4 min read
International SEO is the technical work of letting Google find, index and show the right language or country version of your site to each searcher. Give every version its own crawlable URL, never force visitors onto a version by IP or browser language, translate whole pages properly, and connect the versions with hreflang. The rest is ordinary SEO, repeated per market.
The usual failure is Google never seeing the German pages at all, because they sit behind a cookie, a redirect or a query string.
Which URL structure is best for international SEO?
Use a subdirectory on your main domain unless you have a business reason for something else. Google's guide to managing multi-regional and multilingual sites lists four options and marks only one as not recommended.
| Structure | Example | What Google lists for it | When to pick it |
|---|---|---|---|
| Country domain (ccTLD) | example.de |
Clear geotargeting, server location irrelevant. Costly, more infrastructure, one country only | Separate local businesses, or a market where a local domain builds trust |
| Subdomain | de.example.com |
Easy setup, servers can differ by location. Users can't tell if "de" means language or country | Versions run by different teams or stacks |
| Subdirectory | example.com/de/ |
Easy setup, low maintenance. One server location, harder to separate sites | Most sites. Every version shares the domain's links and history |
| URL parameter | example.com?loc=de |
Not recommended. Segmentation is hard, targeting unclear | Never for new builds |
A ccTLD also locks the version to one country. example.de says Germany, so it is the wrong home for German speakers in Austria and Switzerland. A subdirectory like /de/ can serve all three, with /de-at/ added later if prices or shipping differ.
Do not count on Search Console to fix a vague structure. Google retired the International Targeting report and its country setting in 2022, so the URL and hreflang carry the signal now.
Why you should not auto-redirect by IP or Accept-Language
Automatic redirects hide your other versions from Google. Googlebot usually crawls from the USA and sends requests without an Accept-Language header, per the same Google guide. If your server sends every US IP to /en-us/, the crawler may never reach /fr/ or /ja/, and those pages never get indexed.
Google's advice is blunt. Avoid automatically redirecting users between language versions, and don't use IP analysis to adapt content. A French speaker on a work trip in Tokyo gets Japanese pages too.
What to do instead:
- Serve the URL that was requested, every time, to every visitor.
- Show a dismissible banner when the visitor's locale doesn't match: "This page is also available in French."
- Put a language switcher in the header or footer with plain links to each version. Links, not a JavaScript dropdown that writes a cookie.
- Remember a manual choice in a cookie only to pick the banner text, never to redirect.
If you already redirect, the redirect chain checker traces every hop a plain request follows.
Translated content vs machine translation
Translate the whole page, and have a person review anything you machine-translate. Google's multi-regional guide asks for one language per page for content and navigation, and warns against side-by-side translations. It also says translating only the boilerplate while the body stays in one language makes a bad experience. A Spanish menu around an English article is not a Spanish page.
Machine translation itself is allowed. Unreviewed scale is the risk. Google's spam policies list "automated transformations like synonymizing, translating" among the ways sites produce scaled content abuse. Pushing 5,000 product pages through a translation API overnight and publishing them unread is the pattern that policy describes.
A workable middle path:
- Machine-translate a first draft, then have a fluent reviewer fix terminology, units, currency and legal text.
- Translate titles, meta descriptions, image alt text and structured data, not only the body.
- Translate the pages that earn traffic first. Leave the long tail in the original language rather than publish unread output.
- Localize what matters to the buyer. Prices in euros, local phone numbers and real shipping terms do more than perfect grammar.
The lang attribute and the signals Google ignores
Set lang on every page anyway, even though Google says it doesn't use it. The guide states that Google determines language from visible content, not from code-level information such as lang attributes or the URL.
<html lang="de-AT">Screen readers use it to pick a voice, and browsers use it to decide whether to offer translation. Keep it consistent with the page's own hreflang value, because a page that says lang="en" and lists itself as hreflang="de" signals a template bug somewhere.
The signal Google does read is hreflang. It tells Google which URLs are versions of the same page and which audience each one serves. The syntax, the return-link rule and the common code mistakes are in our hreflang guide. The fallback for unmatched visitors has its own post on hreflang x-default, and how to check hreflang walks through testing a live set. Each translated page should also be canonical to itself, never to the English original, or the canonical cancels the hreflang.
Check your hreflang setup
Our hreflang checker reads the hreflang links in a page's head and its HTTP Link header. It validates each language and region code and suggests the right one for common mistakes like uk or en-uk. It also flags duplicate codes, relative URLs, a missing self-reference, a missing x-default and a page canonicalized elsewhere, and compares your lang attribute with the page's own hreflang.
It then fetches up to 20 of the listed language versions and reports whether each one loads, redirects, carries noindex, points its canonical somewhere else or fails to link back. Each run costs 10 credits. It does not read hreflang in XML sitemaps, crawl the rest of the site or run JavaScript, so annotations injected client-side won't show up. Run it on one page per template.