en-US translations to keep the default download small. Any other locale is published as a separate side-loadable file under dist/locales/<code>.{js,umd.cjs}. Load only the languages you need; they fetch in parallel with the main bundle, so you pay download cost roughly equal to max(main, locale) instead of main + all locales.
Both Libra.init({ locale }) and Libra.setLocale(locale) throw synchronously when called with an unregistered locale, so the failure surfaces at the call site instead of silently rendering English. Browser-detected fallback (when locale is unset at init) still resolves to en-US if no registered locale matches.
Supported locales
en-US · de-DE · de-CH · pl-PL · nl-NL · nl-BE · fr-BE · fr-CH · it-IT · it-CH · ro-RO · hu-HU · cs-CZ · sk-SK

The same session after Libra.setLocale('de-DE'): the interface is German, the conversation is untouched
npm consumers
Import the locale defaults and pass them toLibra.init({ locales }):
CDN consumers: classic script tag
Each locale’s UMD bundle self-registers intowindow.__libraLocales__, which Libra.init() drains automatically; no locales field needed:
libra.umd.js does not matter as long as all of them load before Libra.init() is called.
CDN consumers: ES module
Load the SDK and the locales you need in parallel, then pass the defaults toinit():
Promise.all ensures the locale bundles fetch in parallel with the SDK; overall wall-clock load time is roughly max(libra.js, largest locale) instead of the sum.
Switching at runtime
Libra.setLocale(locale) updates the widget’s UI language at runtime. Translated strings re-render in place, the chat session is preserved, and the locale is persisted in the iframe’s localStorage. The target locale must have been registered at init time.

