Documentation

Internationalisation

Translate the widget's UI strings to any locale.

The widget ships with react-i18next wired up. The default bundle includes English; every other locale is loaded from a JSON file under src/locales/<locale>/translation.json. Browser language detection is on by default — visitors with navigator.language set to de-DE see the German bundle if it exists, English otherwise.

Out of the box

Pass language to the component to force a locale, or omit it to let the detector pick:

<AppmintChat
  orgId="..."
  configId="..."
  appId="..."
  language="de"
/>

The detector chain is configured in src/locales/i18n.ts — it tries localStorage first (i18nextLng key), then navigator.language, then falls back to en.

Adding a locale

Translations are static JSON. Add a new folder per locale:

src/locales/
├── en/
│   └── translation.json
├── de/
│   └── translation.json
└── fr/
    └── translation.json     # ← new

Copy en/translation.json to your new locale and translate the strings in place. Keys are flat:

{
  "welcome.title": "Hi there 👋",
  "welcome.subtitle": "How can we help?",
  "chat.placeholder": "Type a message",
  "chat.send": "Send",
  "register.email": "Email",
  "register.firstName": "First name",
  ...
}

Then register the locale in src/locales/i18n.ts:

import en from './en/translation.json';
import de from './de/translation.json';
import fr from './fr/translation.json';

i18n.init({
  resources: {
    en: { translation: en },
    de: { translation: de },
    fr: { translation: fr },   // ← new
  },
  fallbackLng: 'en',
  ...
});

Rebuild (yarn build:lib for the package, yarn build for the standalone) and the new locale is available.

Custom translations without forking

There is no i18n export from the bundle today — the widget loads its translations from its own bundled JSON files. For a one-off override (e.g., your brand uses "Concierge" instead of "Support"), the practical path is to fork chat-client and rebuild the bundle, or override copy via the chat-config record (welcome.title, welcome.subtitle, headerContent) which is server-driven and bypasses i18n.

If you self-host the bundle, you can also patch src/locales/<locale>/translation.json directly before running yarn build.

RTL languages

The Tailwind config includes tailwindcss-rtl, so RTL locales (Arabic, Hebrew) flip layout automatically when the document dir attribute is rtl:

<html lang="ar" dir="rtl">

Or set it programmatically before mounting:

document.documentElement.dir = ['ar', 'he', 'fa', 'ur'].includes(language) ? 'rtl' : 'ltr';

The default message bubble handles RTL correctly. Slot-based overrides aren't supported today (see Slots).

Date and time formatting

The widget renders timestamps via Intl.DateTimeFormat using the current locale. There is no slot today to swap formatting — if you need a different format than the locale's default, fork the bundle.

Test coverage

src/locales/__tests__/ contains snapshot tests for the English bundle. Add a snapshot for each new locale to catch missing keys early.

Common pitfalls

  • A key shows as welcome.title in the UI — the locale file is missing that key. Check the key list in en/translation.json and add it to your locale.
  • The detector picks the wrong languagenavigator.language returns en-US, not en. The widget normalises to the language code (first two letters), so en-US and en-GB both map to en.
  • localStorage value is sticky — if a visitor switched languages before, localStorage.i18nextLng holds the override. Clear it (or expose a language picker that calls i18n.changeLanguage(...)) to switch.