Multilingual website SEO: one language per URL, and everything translated

You need one language per URL and every part translated. This page shows what to translate, how to wire hreflang, and how to structure URLs. It includes a worked example for one page in English and French.

By , founder of Porteur · Updated 14 September 2026 · Markdown

One language per URL, and translate everything

Do not mix languages on the same URL. Put each language on its own URL. Search engines and people need a clear version to land on.

Translate the whole page. That means the visible copy and the parts around it. Titles, meta descriptions, slugs, headings, image alt, navigation, footer, and forms.

Translate structured data too. Add the right inLanguage and local names in JSON-LD. Localise currency, dates and examples. A French page should read like it was written for France.

Choose a URL structure you can run for years

You have three good options. ccTLD, subdirectory, or subdomain. Google says all three work. Pick by operations and links, as of 2026.

OptionWhat it isProsConsUse when
ccTLDexample.frStrongest geo signal. Clear for users. Can host locally.A separate site to run. Separate link profile to build.You commit to a market long term and can support a separate site.
Subdirectoryexample.com/fr/One host. One link profile. Easier to manage and track.Weaker geo signal than ccTLD. Needs clean routing and internal links.You want one domain to grow, with simpler ops.
Subdomainfr.example.comClear split. Flexible hosting. Often treated as part of the site.Can be seen as separate. Dilutes links if mishandled.You need team or tech isolation by language.

Avoid parameters for language. They are fragile. They fragment signals. They reduce click trust. They are hard for users to share and for you to test.

A migration is costly. If you plan to add more languages, start with subdirectories. example.com/fr/, example.com/de/, example.com/es/. Keep slugs translated inside each. example.com/fr/tarifs/ not example.com/fr/pricing/.

When to add a language

Add a language when the product is sold in that country and you can support it. A second language is a second site's worth of maintenance.

Check demand first. In Search Console, look for impressions from that country on your one-language site. If it shows queries in that language, you have a start.

Check delivery. Payments, taxes, support hours, shipping, and legal pages must work for that market. If you cannot serve it, do not translate it yet.

Plan resourcing. Who writes, reviews and updates the translations. Who updates screenshots and examples. Who tracks changes after releases. Make it someone's job, not a side task.

What to translate and localise on every page

  • Title tag: up to about 60 characters. Match the search in that language.
  • Meta description: one clear sentence within about 155 characters.
  • Slug: short, in that language, with hyphens. Use accents only if your stack supports them well.
  • Headings and body: written for local search intent, not word for word.
  • Image alt text: describe the image in that language. Keep it concise.
  • Structured data: translate names and descriptions. Set inLanguage. Use local currency codes.
  • Navigation and internal links: point to the same language. A French page links to French pages.
  • Forms, CTA labels, error messages, and footers: all in that language.
  • Dates, numbers, and currencies: use local formats, for example comma decimals in France and point decimals in the US.
  • Examples and screenshots: match the market where possible.

Do keyword research per language. People do not search word for word. "logiciel de paie" is not "salaire app". Your titles and slugs must match how locals search.

Hreflang that selects the right version

Hreflang declares the language and region versions of a page. It helps Google show the right version. It does not merge ranking signals across languages.

  • Place hreflang in the head, or in your XML sitemap, or via HTTP headers.
  • Use ISO codes. fr, en, en-GB, en-US, fr-CA, etc. Use x-default for a generic or selector page.
  • Map exact equivalents only. /pricing to /fr/tarifs, not to a category.
  • Make entries reciprocal. Each version lists all the others, including itself.
<link rel="alternate" href="https://yourproduct.com/pricing/" hreflang="en" />
<link rel="alternate" href="https://yourproduct.com/fr/tarifs/" hreflang="fr" />
<link rel="alternate" href="https://yourproduct.com/pricing/" hreflang="x-default" />

Search Console's International Targeting report is gone since 2022. You cannot set geo targeting for gTLDs there anymore. Get hreflang right and track with logs and the Inspect URL tool for samples, not a dashboard number.

Do not auto redirect by IP or browser language

Never send people to a different URL based on IP or Accept-Language headers. Googlebot crawls from the US and would never see your other versions. Use a banner, not a redirect.

<!-- Example: a non-blocking banner suggestion -->
<div role="region" aria-label="Language suggestion">
  <p>Il existe une version française de cette page.</p>
  <a href="/fr/tarifs/">Aller à la version française</a>
</div>

Translation quality and Google's spam policies

Translate for people, not for throughput. Pages must answer local queries in that language. This is how each page earns its place.

Google's spam policies list content translated automatically without human review as an example of scaled content abuse. AI assisted is fine. Publishing at scale without value is not, as of March 2024 signals folded into core ranking.

  • Have a human review every translation before publish.
  • Rewrite for local terms and search intent. Do not mirror sentence order.
  • Swap screenshots and examples to local ones when it helps.
  • Keep product data in sync across languages. Do not let features drift.

Worked example: one page in English and French

Base page: /pricing. French page: /fr/tarifs. Structure: subdirectory. Internal links on each language point to same-language pages. Switcher links the pair.

  • English title: Pricing for YourProduct. French title: Tarifs YourProduct.
  • English description: Simple plans, monthly or yearly. Start free. French description: Des forfaits simples, mensuels ou annuels. Commencez gratuitement.
  • Slug: pricing vs tarifs.
  • H1: Pricing vs Tarifs.
  • Body copy: translated and adapted. Currency shown in USD on /pricing and EUR on /fr/tarifs.
  • Alt text: "Pricing table for YourProduct" vs "Tableau des tarifs YourProduct".
  • Navigation: /features links to /fr/fonctionnalites on the French page.
  • Schema: SoftwareApplication with inLanguage set to en or fr, and offers with the right priceCurrency.
  • Hreflang: reciprocal links between the two URLs, with x-default on the English page if you have no selector page.
<!-- /pricing head -->
<title>Pricing for YourProduct</title>
<meta name="description" content="Simple plans, monthly or yearly. Start free.">
<link rel="alternate" href="https://yourproduct.com/pricing/" hreflang="en" />
<link rel="alternate" href="https://yourproduct.com/fr/tarifs/" hreflang="fr" />
<link rel="alternate" href="https://yourproduct.com/pricing/" hreflang="x-default" />
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "YourProduct",
  "inLanguage": "en",
  "applicationCategory": "BusinessApplication",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "USD"
  }
}
</script>
<!-- /fr/tarifs head -->
<title>Tarifs YourProduct</title>
<meta name="description" content="Des forfaits simples, mensuels ou annuels. Commencez gratuitement.">
<link rel="alternate" href="https://yourproduct.com/pricing/" hreflang="en" />
<link rel="alternate" href="https://yourproduct.com/fr/tarifs/" hreflang="fr" />
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "YourProduct",
  "inLanguage": "fr",
  "applicationCategory": "BusinessApplication",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "EUR"
  }
}
</script>

What a fixed pair looks like: two URLs, both indexable, both translated, both linked to internally in their language, hreflang in place, and a real switcher between them. Search Console shows queries in English on /pricing and in French on /fr/tarifs over time.

Rollout plan and QA

  1. Pick structure and routes

    Choose ccTLD, subdirectory, or subdomain. List every route to translate. Define slugs per language.

  2. Prepare content and data

    Translate titles, descriptions, copy, UI strings, alt, and schema. Localise currency and dates. Have human review.

  3. Wire navigation

    Translate menus. Ensure a French page links to French pages. Add a language switcher with real links and hreflang on each pair.

  4. Build sitemaps

    Create one sitemap per language or one with hreflang entries. Submit in Search Console.

  5. Ship and monitor

    Release a small set first. Use the URL Inspection tool on samples. Check server logs for crawler access to all language URLs.

  6. Track queries and fix

    In the Performance report, filter by page and by country. Check if queries match your titles and slugs. Adjust copy and internal links.

Do not block anything via robots.txt that the other language needs. Keep canonical tags self-referencing within each language. Do not cross-canonical between languages. They are not duplicates for people.

Questions

Sources

Check my site, free

See where to start: paste your URL and get a free check of your site’s pages and the searches around them in about thirty seconds, with three findings shown whole.

  • Free check, no card
  • Read-only, your own accounts
  • Readable by your agent

Read next