Live chat is one of the few products where i18n really matters at the edge. A French visitor on a Spanish e-commerce site will not type in English. A Japanese visitor will close the tab if the placeholder text is in English. We chose 12 languages for muro — covering ~80% of the public internet by visitor count — and built the widget i18n in a way that adds about 2 KB to the bundle.
The 12 supported languages
EN · FR · ES · DE · IT · PT · NL · JA · KO · ZH · AR (RTL) · RU. Eleven UI strings each — welcome, online status, reply ETA, typing indicator, type-message placeholder, send, attach, new message, conversation closed, reopen, powered-by line.
Resolution order
- 01Explicit
muro('init', { lang: 'fr' })from the install snippet - 02Per-website default in the muro dashboard (
config.language) - 03
navigator.language(browser preference) - 04
<html lang="…">of the host page - 05English fallback
In practice, most websites set the per-site default to match the site's primary language and let navigator.language override for visitors browsing in another tongue. That covers the long tail.
RTL: Arabic
Arabic flips everything — text direction, the side the launcher sits on, the bubble corners. We detect RTL via a simple isRtl(lang) check and add dir="rtl" on the widget root. Tailwind's logical properties (ms-3 instead of ml-3) handle the rest:
tsx<div dir={isRtl(lang) ? 'rtl' : 'ltr'} className="muro-widget">
<header className="ps-3 pe-2">…</header>
</div>Where the strings live
Plain TypeScript module — src/lib/i18n.ts — keyed by language code. No fancy ICU MessageFormat, no plural rules library; the strings we need are 11 short labels with at most one variable. JSON would have worked too; TS gives us autocomplete on the keys for free.
Agent side: the inbox stays English
The dashboard UI is in English regardless of the visitor's language — agents work in one tongue, see incoming messages in whatever language the visitor wrote. We deliberately don't translate the message body even when we detect a mismatch; agents prefer raw text + their own translation tool (DeepL, Apple's built-in) over an automatic translation that might subtly change meaning.
Adding a 13th language
It's a single file edit + a one-line type union update. Languages have come up: Polish, Turkish, Greek, Hebrew (RTL). We'll add them when we see real demand — typically when one customer's biggest market is in that language.
Multilingual chat is a quiet detail that earns trust the moment a visitor sees their language reflected back. It's also a feature we get asked about more than we'd expect, so this article exists mainly so the next person who asks gets a link instead of a paragraph.