---
name: "international_seo"
description: "International SEO that avoids self-inflicted wounds: hreflang setup and common errors, region versus language targeting, URL structure choice, localized content that is more than a translation, and measuring performance per region. Use when a site serves more than one language or country, when the wrong country version ranks or converts, when adding a new locale, or when auditing hreflang tags in HTML, HTTP headers, or a sitemap. Standalone and tool neutral."
---

# International SEO

## Purpose

Get the right version of a page in front of the right searcher, and keep it that way. Most international SEO damage is self-inflicted: a cluster where one page forgets to link back, a country code that does not exist, every locale canonicalized to the home market, or twenty translated pages for countries the business cannot ship to. This skill works in a fixed order: decide whether a separate version should exist at all, pick the targeting level and URL structure, build one complete hreflang cluster, validate it with the bundled checker, then measure each locale on its own. It follows Google Search Central guidance on localized versions and multi-regional sites, and it says plainly where that guidance ends and judgment begins.

## Workflow

1. **Decide the targeting level before touching tags.** For each planned version, answer the three questions in `references/codes-and-targeting.md`: does the offer differ by country, by one specific country, or only by writing system? Language only (`es`) is the default. Add a region (`es-MX`) only when price, currency, shipping, legal terms, availability, or terms of sale actually differ for that country. Use a script (`zh-Hans`, `zh-Hant`) when pages differ by writing system. If nothing differs, do not build the version. A single version site needs no hreflang at all.

2. **Pick the URL structure once, knowing it is hard to undo.** Country specific domains (example.de) give the clearest geotargeting and easy site separation, at higher cost, more infrastructure, and a separate authority build per domain, and each one targets a single country. Subdomains with a generic TLD (de.example.com) are easy to set up, allow different server locations, and separate sites cleanly. Subdirectories with a generic TLD (example.com/de/) are easy to set up and low maintenance on one host, with site separation harder. URL parameters (example.com?loc=de) are not recommended, because URL based segmentation is difficult. Default to subdirectories unless the business already runs separate country operations that justify domains of their own. Use a separate URL for every language version. Never switch language on one URL with cookies or browser settings.

3. **Write the full cluster as one identical set.** Every page in a cluster lists every version, including itself, plus one `x-default`. Values follow one pattern: ISO 639-1 language first in lowercase, optional ISO 15924 script in title case, optional ISO 3166-1 Alpha 2 region in uppercase. The United Kingdom is `en-GB`, never `en-UK`, because UK is a reserved code with no effect in Google Search. EU and UN are reserved the same way. A region alone is invalid, and numeric regions such as `es-419` are not supported by Google. For Latin American Spanish, ship one `es` page or one page per country where the offer differs. Full code rules and worked traps are in `references/codes-and-targeting.md`.

4. **Choose one delivery method and stay with it.** Google accepts hreflang in HTML link tags in the head, in HTTP response headers, and as `xhtml:link` entries in an XML sitemap, and it treats the three as equivalent. There is no benefit in using more than one at once, and split methods drift apart. Use HTML tags for small sites where templates are easy to control, sitemaps for large sites or many locales where head tags get heavy and templates are owned by another team, and HTTP headers mainly for non HTML files such as PDFs. Generate both forms with `python3 bin/hreflang_check.py generate variants.json` and compare against what the site actually ships.

5. **Align the canonicals before blaming the tags.** Each locale page canonicalizes to itself, in its own language. A page whose canonical points to another locale has its hreflang ignored, and cross locale canonicals collapse the whole set into one market. Check three matches per page: canonical equals the page URL, the page URL appears in its own alternate set, and every alternate href is an absolute, live, indexable URL returning a success response, not a redirect, an error page, or a noindex page. Keep canonical and hreflang as separate single purpose link tags, never combined on one tag.

6. **Validate the cluster with the bundled checker, then by hand.** Export each page URL, its canonical, and its alternate list into the JSON format in `examples/pricing-cluster.json`, then run `python3 bin/hreflang_check.py check cluster.json`. The checker flags invalid and reserved codes, missing self references, alternate sets that differ between pages, missing return tags among the supplied pages, duplicate values, relative URLs, canonical conflicts, mixed protocols, and a missing `x-default` as a warning. Run `python3 bin/hreflang_check.py demo` first to see a clean three region cluster pass and a broken cluster fail on six errors. Then spot check the live pages: view the raw server HTML, not only the rendered page, because tags injected late by scripts may not be in the first response a crawler reads. Targets outside the export file get a warning, not a pass, so export the whole cluster.

7. **Ship localization, not bare translation.** Score each new locale against the six checks in `references/localization-and-measurement.md`: full language coverage including forms and emails, keyword research done in the locale, local currency and formats, an offer that is true for that country, local trust signals, and a fluent regional review of the final page. Keep one language for content and navigation on each page, since Google judges language from visible content. Do not auto redirect visitors based on a guessed language or location. It can block both users and crawlers from reaching every version. Put a visible language and region switcher on every locale page instead.

8. **Cover the other engines without inventing rules.** Google and Yandex read hreflang. Secondary guides report that Bing leans more on page language signals such as the `html lang` attribute and the `content-language` meta tag, so set `html lang` correctly on every locale page as a matter of course. That costs nothing and helps accessibility tools at the same time. Do not promise a ranking effect on any engine from these tags. Hreflang is a hint about which version to serve, not a directive and not a ranking boost.

9. **Measure each locale separately.** There is no current Search Console country targeting setting and no hreflang error report. Google removed the International Targeting report in September 2022. Use the Performance report filtered by country and by page for the last 28 days against the previous 28 days, keep a tracked set per locale, and run the wrong version check and canonical check in `references/localization-and-measurement.md`. Re-run the validator after any template, CMS, domain, or protocol change and after every new locale launch, because clusters break at change points.

## Output Contract

A finished international SEO job delivers all of these:

1. **A targeting table.** One row per version: market, hreflang value, URL, and the concrete difference that justifies a separate version, or a note that the version was cut and why.
2. **The URL structure decision.** Which of the four structures was chosen, what it costs, and what would trigger a revisit. Stated once, before build work starts.
3. **One complete cluster per page type.** The identical alternate set for every member, in the single chosen delivery method, generated or checked with `bin/hreflang_check.py`, with the checker output kept.
4. **A canonical alignment note.** Confirmation per page type that canonical, self reference, and alternate hrefs match, and that every target is live and indexable.
5. **A localization score per locale.** Pass or fail on each of the six checks, with the failing items named. No locale is reported ready on translation alone.
6. **A per region measurement sheet.** One block per locale in the format at the end of `references/localization-and-measurement.md`, with clicks, impressions, position, wrong version findings, and one named next action per locale.

## Operating Rules

1. **Never invent a code.** Every hreflang value must resolve to ISO 639-1 for language, ISO 15924 for script, and ISO 3166-1 Alpha 2 for region, or be `x-default`. If a market cannot be expressed in those sets, say so and use the language only form or per country pages.
2. **No cluster ships half built.** A missing return tag or a missing self reference can void the relationship between pages. If only some locales are ready, ship the complete cluster for the ready subset and add new members to every page when they launch.
3. **Fix canonicals before tags.** When a wrong version ranks, check the Google selected canonical and the declared canonical first, then return tags, then indexing, then content similarity. Tag edits on a page with a cross locale canonical change nothing.
4. **No locale without a servable offer.** Do not launch a country version the business cannot sell to, ship to, or support. Wrong promises in the right language still lose the customer and the ranking.
5. **One delivery method per site.** HTML, headers, or sitemap. If a migration forces a change of method, remove the old one in the same release and revalidate the full cluster.
6. **Report engine differences honestly.** State which claims come from Google documentation and which come from secondary guides about other engines. Do not present a secondary summary as an engine guarantee.
7. **Revalidate after change, not on a calendar alone.** Template edits, CMS upgrades, domain and protocol migrations, and new locale launches are the moments clusters break. Each one triggers a fresh checker run and a live spot check.
