TL;DR Every language version needs its own stable URL, not a cookie or a browser setting. Hreflang is only a hint, and it has to work both ways, with each page pointing to itself too. The most damaging mistake is a canonical tag that points to a different language. Google figures out the language from the visible content, not from hreflang or the
langattribute. Nobody has publicly confirmed how AI models pick a language version, so you have to measure it instead of guessing. Semly shows you whether a given language version is actually being cited by AI models.
Multilingual WordPress SEO: what you are actually trying to fix
Let's clear one thing up first. Multilingual WordPress SEO is not about translating text. It is about making sure Google and AI tools know which URL belongs to which language.
Google wants a separate URL for every language version. It does not care about cookies, and it does not read your visitors' browser settings. That is why a site that "remembers" a language in a cookie often looks like a single-language site to a crawler.
Here is the part that surprises people. Googlebot usually crawls from the USA and sends requests without an Accept-Language header. So if your site decides which language to show based on that header, the crawler may never see your other versions at all.
And please, do not auto-redirect people based on their assumed language. It can stop both users and search engines from ever reaching the other versions.
What breaks when this is missing:
- The wrong language shows up in search results.
- Google treats your versions as duplicate content.
- Crawl budget gets wasted on URLs that should not compete with each other.
Quick answers to common questions:
- Is translating enough? No. Translation without a clear URL structure leaves Google guessing.
- Will Google detect the language on its own? It detects language from visible content, but it still needs a URL per version.
- Can I use URL parameters? Google does not recommend it. Parameters are not a stable, crawlable signal.
Watch out: Google ignores locational meta tags like geo.position and distribution. Do not rely on them.
Step 1: Pick a URL structure you can live with
Decide on the architecture before you touch anything else. Changing it later means redirects, lost signals, and a lot of cleanup.
Here is how the main options compare.
| URL pattern | Pros | Cons | When to choose it |
|---|---|---|---|
ccTLD (example.de) |
Clear country targeting, easy to separate sites | Expensive, more infrastructure, one country only | When you target one country hard and have the budget |
Subdomain (de.example.com) |
Easy to set up, can live on different servers | Users may not read the de as a country signal |
When you want clean separation between markets |
Subdirectory (example.com/de/) |
Easy to set up, low maintenance, one host | Single server location, harder to separate sites | The lowest-friction choice for most WordPress sites |
URL parameters (site.com?loc=de) |
None worth mentioning | Google does not recommend it | Not really. Avoid it |
For most WordPress and WooCommerce owners, the subdirectory is the easiest place to start. You keep one install, one sitemap, and one place to manage everything.
Common questions:
- Small budget? Subdirectory. It costs nothing extra.
- Can I change later? Yes, but plan redirects carefully and expect a transition period.
- Does a subdomain split authority? It shares the root domain, but each subdomain builds its own signals over time.
Watch out: Google treats .ai, .io, .co, .me and .tv as generic top-level domains, not country domains. Do not assume they send a country signal.
Step 2: Set up hreflang so it actually counts
Hreflang tells Google that these URLs are versions of the same page in different languages. There are three ways to add it: HTML link tags, HTTP headers, or your XML sitemap. They are equivalent to Google, and mixing them gives you no extra benefit. Pick one and stick with it.
Two rules matter more than anything else:
- Self-reference. Every version must list itself.
- Return links. If page A points to page B, page B must point back to A. One-way tags get ignored.
A correct entry looks like this:
<link rel="alternate" hreflang="de" href="https://example.com/de/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Hreflang checklist:
- Every version lists itself and all the others.
- All links work both ways.
- URLs are fully qualified, with
https://. - Codes use ISO 639-1 for language, plus optional ISO 3166-1 for region.
- Region-only codes are invalid. So are
es-419,EU,UNandUK. x-defaultis set on your language selector or auto-redirecting home page.
Common questions:
- Do I have to list every language? Ideally yes. If that is not practical, at least link new languages back to your main language.
- What if I skip one? Google still processes the pairs that point to each other.
- Is
x-defaultrequired? Not strictly, but it is recommended for selector pages.
Watch out: Google treats hreflang as a hint, not a command. It can ignore it if the signals do not line up.
Step 3: Keep canonicals inside the same language
This is the mistake that hurts the most. The rule is simple: every language version canonicalizes to itself.
If your German page has a canonical pointing to the English version, you are telling Google "this German page is not the real one." Google may drop it from the index. And when that happens, every hreflang tag pointing at it becomes useless.
Google also prefers URLs that belong to an hreflang cluster when it picks a canonical. So keeping your cluster clean helps here too.
One more thing: do not add hreflang, lang, media or type attributes to rel="canonical". They are ignored.
Canonical checklist:
- Each locale page points to itself.
- No canonical crosses into another language.
- Hreflang targets are live, indexable, and not redirected.
- The URL form matches exactly: protocol, host, trailing slash.
Wrong to right, in one line: /de/ canonical pointing to /en/ becomes /de/ canonical pointing to /de/.
Common questions:
- Is a translation a duplicate? Not if the main content is actually translated.
- Can canonical point to English? Only if no same-language version exists.
- Two countries, same language? Use a self-canonical plus hreflang to separate the regions.
Step 4: Make sure your plugin does not quietly break it
Your translation plugin handles hreflang for you, until it stops. The big difference between plugins is where the translations actually live.
| Plugin | Where translations live | What to check |
|---|---|---|
| WPML | In your WordPress database | Hreflang codes in sitemaps after updates |
| Polylang | In your WordPress database | x-default beyond the homepage |
| TranslatePress | In your WordPress database | That the SEO Pack add-on is active |
| Weglot | On the vendor's servers (SaaS proxy) | That you use subdomain or subdirectory, not JavaScript |
| MultilingualPress | Separate WordPress installs (Multisite) | That translation relationships are defined |
That last column matters more than it looks. If translations live in a database, your server-side output can be translated too. If they live behind a proxy, things like WooCommerce emails and admin strings often stay in the original language.
Also worth knowing: hreflang is generated automatically, but it can break after an update. There have been real cases where a plugin emitted region-only codes in sitemaps, or leaked hreflang tags for hidden languages. Both were fixed, but only after someone noticed.
Checklist after every update:
- Do the hreflang codes still look right in your sitemap?
- Are your slugs translated the way you expect?
- Are your emails and admin strings translated?
- Does every version still self-reference?
Common questions:
- Does my plugin output correct codes? Check the sitemap source, not just the settings screen.
- Are slugs translated? Depends on the plugin. Some keep the original slug and add a prefix.
- Are emails translated? Only if the translation happens server-side.
Step 5: Verify in Search Console and fix what you find
Now confirm that Google sees what you think it sees.
Open URL Inspection for each locale and compare the "user-declared canonical" with the "Google-selected canonical." If they differ, you have a problem to fix.
Then filter your Performance report by country. If your German pages get no impressions in Germany, something is off.
Verification checklist:
- User-declared and Google-selected canonicals match for every locale.
- Hreflang points to URLs that return 200, are indexable, and are not redirected.
- URL form is consistent: protocol, host, trailing slash.
- Performance by country shows the right locale earning impressions.
Typical symptoms:
- Wrong language in results: usually a canonical or hreflang problem.
- No impressions in a country: often a missing or broken return link.
- One version missing entirely: check whether it is indexed at all.
Common questions:
- How do I know Google picked the right URL? URL Inspection shows it directly.
- Where do I see traffic per country? The Performance report, filtered by country.
- What if the canonical does not match? Fix the tag, then request re-indexing.
Step 6: Check whether AI actually cites each language version
Here is the honest part. No AI provider documents how models choose a language version. Hreflang is not a confirmed input. The most likely mechanism is simpler: the model matches the language of your prompt and pulls from an index that may or may not cover that language.
That means guessing is pointless. You have to measure.
A simple test protocol:
- Write the same questions in each target language.
- Run them across several models.
- Record which URL gets cited, and in which language.
- Repeat over time to see if it changes.
This is where Semly fits in. It is a measurement layer, not a translation tool. During onboarding you choose your markets and languages, and Semly tracks prompts per language, attributes the sources behind AI answers, and shows whether your brand shows up at all. You can start with a free AI visibility report and see where you stand before spending anything.
Common questions:
- Does AI use hreflang? No one has confirmed it does.
- How do I check if my German version is cited? Run German prompts and log the cited URLs.
- Where do I start without a budget? Start with the free report and a handful of test prompts.
Watch out: These results are correlational, not guaranteed. And different models behave differently, so a win in one does not mean a win in another.
Common mistakes and how to fix them
- Symptom: Your hreflang tags seem ignored. Cause: Missing return links. Fix: Make every pair point both ways.
- Symptom: Tags are ignored even with return links. Cause: Wrong language or region codes. Fix: Use ISO 639-1 plus ISO 3166-1, and drop region-only codes.
- Symptom: One language version vanished. Cause: A canonical pointing to another language. Fix: Make it self-canonical.
- Symptom: Hreflang points to a redirect. Cause: The target URL changed. Fix: Point to the final, live URL.
- Symptom: No
x-defaulton your selector page. Cause: It was never added. Fix: Add it to the language selector. - Symptom: Everything worked, then broke. Cause: A plugin update. Fix: Re-check your sitemap after every update.
What to do next
Adding more languages is easier when you do it in order. Link each new language back to your main language first, both ways, then expand the cluster.
You can also make your targeting machine-readable with JSON-LD. Properties like inLanguage, areaServed and availableLanguage help describe who a page is for and in what language.
Then keep it in check. Review your hreflang and canonicals after every plugin update, and re-run your AI prompt tests on a schedule.
When to stay on a subdirectory, and when to move to a ccTLD:
- Stay on a subdirectory if you are testing markets, working with a small team, or want one place to manage everything.
- Move to a ccTLD if you target one country hard, want the strongest country signal, and can handle the extra cost and maintenance.
Either way, the goal stays the same: one stable URL per language, clean signals for Google, and a way to check whether AI is actually citing each version. Semly gives you that last part, so you are not flying blind.