Shipping a second or third language on a web app usually looks straightforward in development: add a [locale] route segment, translate the JSON dictionaries, and deploy.

Then Search Console data starts coming in, and entire language folders sit in "Crawled - currently not indexed" or "Duplicate without user-selected canonical" for weeks.

After debugging several multi-locale setups, here are the five silent failure modes that actually cause non-default locales to stall—and how to catch each one with a single terminal check.

1. Self-Referencing Canonical vs. x-default Mismatches

A common bug in localized layouts is generating the root canonical URL in the shared <head> and forgetting to scope it per route.

If /hu/guide outputs a canonical pointing back to /en/guide, search engines treat the localized page as a duplicate of English and drop it from the index completely. Every localized route must emit a self-referencing canonical, alongside reciprocal hreflang links:

<link rel="canonical" href="https://yoursite.example/hu/guide" /> <link rel="alternate" hreflang="en" href="https://yoursite.example/en/guide" /> <link rel="alternate" hreflang="hu" href="https://yoursite.example/hu/guide" /> <link rel="alternate" hreflang="x-default" href="https://yoursite.example/en/guide" /> 

Also remember: hreflang must be bidirectional. If /en/guide points to /hu/guide, /hu/guide must point back to /en/guide.

2. Soft 404s From Middleware Locale Fallbacks

A lot of i18n middleware automatically rewrites unknown paths back to /en/... or renders the default locale content while keeping the URL at /hu/old-slug with HTTP 200 OK.

To crawlers, returning English content with HTTP 200 on a localized URL looks like a soft 404 or thin duplicate page.

Rule of thumb:

  • If a slug was intentionally translated, never silently serve the English fallback under /hu/*—redirect (301) or return a genuine 404.
  • Audit your localized sitemap URLs in a script before every deploy and verify every listed URL returns HTTP 200 without an unexpected cross-locale redirect.

3. Hardcoded English Metadata (<title>, <meta description>, <html lang>)

Even when the visible React or Vue body renders in the target language, crawlers heavily weight three top-of-document signals:

  1. <html lang="hu"> (if this stays "en", language classification gets confused)
  2. Localized <title> and <meta name="description">
  3. Localized Open Graph tags (og:title, og:description, og:locale)

If your translation loader runs only on the client inside useEffect, bots inspecting the initial SSR HTML see either blank containers or English fallbacks.

4. Missing Sitemap Cross-Linking or Stale Sub-Sitemaps

Splitting sitemaps per locale (/sitemap-en.xml, /sitemap-hu.xml) is clean—if your root /sitemap.xml actually references them via <sitemapindex>, and every URL inside returns HTTP 200 with matching canonicals.

A surprisingly frequent mistake is adding a localized route, forgetting to include it in the sitemap generator, and leaving zero internal links pointing to it from the default-locale navigation. Orphaned localized pages rarely get crawled beyond initial discovery.

5. Trailing Slashes and Accept-Language Auto-Redirects Blocking Bots

Automatic Accept-Language redirects on the root path (/) can trap search bots whose Accept-Language header is empty or en-US:

  • Crawlers from regional instances should be able to reach /en, /tr, or /hu directly via stable URLs without being forced into a redirect loop based on cookies or headers.
  • Pick one trailing-slash convention (/hu/guide vs /hu/guide/) across routes, <link rel="canonical">, hreflang, and sitemap.xml, and enforce 301 normalization at the edge.

Quick Terminal Verification Checklist

Before trusting Search Console, run curl against both your localized pages and your sitemap as a stateless client (no cookies, no browser JS):

# 1. Inspect initial HTML lang, canonical, and hreflang tags curl -sL https://yoursite.example/hu/guide | grep -iE "<html|canonical|hreflang|<title" # 2. Verify status codes across all sitemap entries curl -s https://yoursite.example/sitemap.xml | grep -oP '(?<=<loc>)[^<]+' | xargs -I{} curl -o /dev/null -s -w "%{http_code} %{url_effective}\n" {} 

If initial HTML looks right with JavaScript disabled and every sitemap <loc> returns a clean 200 with self-referencing canonicals, half of multi-locale indexing problems disappear before they ever hit Search Console.