Back to blog
Engineering·April 12, 2026·5 min read

Four languages, one CMS: how we make i18n not annoying

F
FrosthavenStudio

Dutch clients who want to reach Spanish prospects, German B2B companies that want to open up the Benelux: we see the same question in different shapes. The answer is usually "three or four languages". The answer is rarely "how do we keep that from being tedious for the content editor".

Three principles keep four-language sites livable. First: one set of keys, not one set of files per language that drifts out of sync. next-intl's JSON files per locale with an identical key structure give a diffable validation target. We automatically validate in CI that all keys exist in all languages.

Second: content in the CMS, not in code. For Frosthaven.co itself we use JSON files because it's a small site with stable copy. For client sites with ~100 pages, Storyblok becomes the single source of truth. Not because of the functionality (Sanity/Payload can do that too) but because of the multilingual-by-design UI that editors understand right away.

Third: validation on translation completeness. A Spanish paragraph that isn't there breaks half a page. We use a pre-deploy check that fails if a language is incomplete, and the production URL falls back to the default locale with a warning.

SEO: hreflang tags per locale pair, canonicals per locale and sitemap.xml with xhtml:link alternates. Google only honors this after a few weeks of crawling, so plan it before the launch, not after.

The hardest part stays one thing: tone of voice per language. A literally translated website feels algorithmic. For Frosthaven we write the English copy the most direct, the Spanish a bit warmer, the German more formal and the Dutch sharper. You can hear it in the rhythms.

/ Deel dit /

X / TwitterLinkedInE-mail