Формат повідомлень та i18n
Найнеочевидніша частина протоколу. Якщо ваш клієнт впаде на обробці помилки — майже напевно причина тут.
Сервер не знає мови клієнта
Звичайний підхід — клієнт надсилає Accept-Language, сервер відповідає однією мовою. Тут зроблено інакше: сервер віддає всі 17 локалей одразу, а мову обирає клієнт уже в себе.
t('queue.songAdded', { title }){
"uk": "Пісню додано",
"en": "Song added",
"pl": "Utwór dodano",
"…": "…"
}Причина в природі радіо: одна подія в сокеті йде всім слухачам одночасно, а вони сидять з різними мовами. Якби сервер локалізував повідомлення сам, він мав би або надсилати персональну копію кожному, або тримати мову в стані з'єднання. Об'єкт з усіма локалями знімає обидві проблеми: широкомовна подія лишається однією, і кожен клієнт показує своє.
Ціна — трафік: кожне повідомлення несе 17 варіантів. Для коротких системних рядків це прийнятно, для довільного тексту було б ні.
Що це означає для клієнта
Поле error не є рядком:
// ✗ покаже "[object Object]"
alert(data.error);
// ✓
alert(pickLocalized(data.error, 'uk'));Мінімальна реалізація вибору:
const DEFAULT_LOCALE = 'uk';
function pickLocalized(source, lang = DEFAULT_LOCALE) {
if (source == null) return '';
if (typeof source === 'string') return source; // деякі помилки — рядки
const src = source.localized ?? source; // буває вкладеним
return src[lang] ?? src[DEFAULT_LOCALE] ?? Object.values(src)[0] ?? '';
}Три випадки, які треба витримати:
- Звичайний об'єкт локалей —
{ uk: "…", en: "…" }. - Вкладений під
localized—{ code: "…", localized: { uk: "…" } }. - Просто рядок — частина старих ендпоінтів і технічні помилки.
Коди помилок
Машинно-читабельні помилки несуть ще й code поруч із локалями:
{ "code": "TRACK_NOT_FOUND", "uk": "Трек не знайдено", "en": "Track not found" }Гілкуйте логіку по code, а локалі показуйте користувачеві. Порівнювати текст повідомлення не можна — він змінюється з перекладами.
Підстановки
У рядках трапляються {token}-плейсхолдери, які сервер підставляє до надсилання. Іноді значення підстановки саме є об'єктом локалей — тоді воно розкривається в тій самій мові, що й основний рядок.
Пошук серед мов
Список локалей не зашитий у код: сервер бере його з назв тек у server/src/i18n/. Не покладайтеся на фіксований перелік — беріть ключі самого об'єкта.
Мова інтерфейсу і напрямок письма
Локалі ar та he пишуться справа наліво. Референсний клієнт перемикає document.documentElement.dir на rtl і використовує логічні CSS-властивості (text-start, margin-inline-start) замість лівих і правих. Якщо ви плануєте підтримувати ці мови, закладіть це від початку — переробляти важко.