i18n Support
This repository supports multiple languages via JSON translation files in app/locales/.
Supported Languages
- 🇬🇧 English (en)
- 🇪🇸 Spanish (es)
- 🇫🇷 French (fr)
- 🇮🇹 Italian (it)
- 🇩🇪 German (de)
- 🇧🇷 Portuguese (pt)
- 🇷🇺 Russian (ru)
- 🇸🇦 Arabic (ar)
- 🇮🇳 Hindi (hi)
- 🇨🇳 Chinese (zh)
- 🇯🇵 Japanese (ja)
- ðŸ‡ðŸ‡· Croatian (hr)
- 🇷🇸 Serbian (sr)
Features
- ✅ Automatic language detection from browser
- ✅ Language persistence in localStorage
- ✅ Real-time language switching
- ✅ JSON-based translations
- ✅ RESTful translations API
- ✅ Dynamic locale discovery (no hardcoded locale list)
How It Works
Translation source of truth
- Translations live in
app/locales/<locale>.json. - The server does not translate strings; it only serves these JSON files to the browser.
- Locales are discovered dynamically by scanning
app/locales/*.json(no config change required).
API
GET /localesreturns available locale codes derived fromapp/locales/*.json.GET /translations/:localereturns the full JSON translations for that locale.
Client behavior
- Chooses a locale in this order:
localStorage.locale(if supported) → browser language → defaulten. - Uses dot-notation keys (example:
signIn.button). - Supports placeholder replacement using
__name__tokens.
Usage
For Users
- Open the application
- Click the sidebar button (users icon)
- Go to "Settings" tab
- Select your preferred language from the dropdown (with flag emojis)
For Developers
Add translation to HTML:
HTML
<button data-i18n="signIn.button">Sign In</button>
<input data-i18n-placeholder="signIn.username" placeholder="Enter username" />
Use in JavaScript:
JavaScript
const text = t('signIn.button'); // Returns: "Sign In"
const message = t('room.userJoined', { username: 'John' }); // Returns: "John joined the call"
Placeholder format:
In your JSON:
In JS:
API Endpoint:
Files Structure
Text Only
app/locales/
├── en.json # English translations
├── es.json # Spanish translations
├── fr.json # French translations
├── it.json # Italian translations
└── ... # Other locales (pt, ru, ar, hi, zh, ja, sr, hz)
public/
└── i18n.js # Client-side i18n library
Quick Test
Bash
# List supported locales (derived from app/locales/*.json)
curl http://localhost:8000/locales
# Test English translations
curl http://localhost:8000/translations/en
# Test Spanish translations
curl http://localhost:8000/translations/es
Adding a New Language
- Create
app/locales/<locale>.json(example:app/locales/nl.json). - Copy the structure of
app/locales/en.jsonand translate only the values. - No restart is required: the client will see the new locale via
GET /locales.
Optional:
- If you want a friendly label (flag + name) in the Settings dropdown, add your locale to the
getLocaleLabel()mapping inpublic/i18n.js. Otherwise the dropdown shows the raw locale code.
Notes
- This project uses client-side i18n (see
public/i18n.js). The server remains language-agnostic. - Any server-generated messages (API errors, WebSocket
errorpayloads) are currently plain strings and are not translated.
Adding / Changing Translation Keys
- Keep keys consistent across all locale files.
- Keys are nested objects; the client uses dot-notation to access them.
- If a key is missing, the client logs a warning and shows the key string.