Twenty-two languages, done correctly

hreflang, canonicals and a translation pipeline that admits what it has not translated

Twenty-two languages, with hreflang clusters, self-referential canonicals, per-section translation tracking, and sitemaps that list a page only in the languages it genuinely exists in. Most multilingual sites get this wrong in ways that actively suppress their own rankings.

Every number here names where it came from and when it was measured.
MeasureValueSourceMeasured
Languages served22messages/*.json in the marketing site repository
Threshold for counting a language as translated for a sectionat least 90% of strings present, fewer than 30% identical to Englishapp/lib/message-locales.ts
Translated strings in the marketing dictionary, per language6,517key count of the English dictionary bundle
Sitemap generationPer request, from the same sources the pages read — no maintained listapp/lib/sitemap-source.ts

What building it taught us

International SEO is mostly a set of rules about honesty. A page that exists in one language and is served under twelve prefixes is twelve near-duplicates, and search engines will pick one and file the rest as unindexable. The common failure is not malice, it is optimism: a site launches its language switcher before its translations, then wonders why the foreign-language versions never rank.

We made the machinery tell the truth. Whether a page counts as translated into a language is computed, not asserted: the language's own bundle must carry at least ninety per cent of that page's strings before merging with English, and fewer than thirty per cent of them may be byte-identical to the English original. That second test exists because a machine translation provider returning the source text unchanged produces a bundle that looks complete and is not — measured on real output, an echoing provider comes out almost entirely identical, and that is not a translation.

Everything follows from that one computation. An untranslated page points its canonical at the English original and is excluded from that language's sitemap, so nothing unindexable is ever submitted. When the translation lands, the page becomes its own canonical and appears in the sitemap automatically. Sitemaps are generated per request from the same sources the pages read, so they cannot drift — the two hand-maintained copies this replaced had already disagreed with each other, and neither listed a single blog post.

Structural fields are protected from translators by construction. Copy lives in a dictionary and is merged over the typed object, so only string leaves can be replaced and only where the shape still matches; a list whose length has drifted falls back to English rather than rendering half-translated. A translator cannot break a slug, a route or a comparison matrix, because those never leave TypeScript.

Built with

  • next-intl
  • hreflang
  • XML sitemaps
  • Next.js App Router
  • self-hosted machine translation

What this qualifies us for

International SEOMultiple languages and markets without competing against yourselfMultilingual websitesMore than a language switcher and a translation pluginTechnical SEOMaking a site legible to search engines, at the sourceContent modeling and editorial systemsStructuring content so it can be reused, translated and found

Tell us what you are trying to do

A short conversation is usually enough to tell whether we are the right people. If we are not, we will say so and point you somewhere better.

Start a conversationI already use KamoCRMHow we quote