Skip to content
Writing
Dec 2025 1 min read

Shipping to three languages without losing your mind

Notes on URL-based locales, compile-time messages, and why the document lang attribute is not optional.

i18nSvelteKit

The biggest i18n mistake is treating language as runtime state. Put it in the URL. Every locale gets a real, crawlable, shareable address, and hreflang stops being a guess.

Compile-time message catalogs turn missing translations into build errors instead of production blanks. A typed message function looks like this:

import * as m from '$lib/paraglide/messages';

// resolved at build time — a missing key fails the build, not the page
const title = m.site_title();
const read = m.min_read({ minutes: 6 });

And yes — set the html lang attribute per page. Screen readers pick a voice from it; search engines trust it. A Japanese page that declares English is a bug, even if every visible word is correct.

Comments

Loading comments…