Локализация уведомлений и алертов в FormatJS опирается на идею того, что любые пользовательские сообщения в интерфейсе представляют собой форматируемые строки с параметрами, зависящие от языка, контекста и грамматических правил конкретной локали. Уведомления (notifications), всплывающие алерты (alerts), toast-сообщения и системные сообщения становятся частью единого механизма интернационализации, где текст не «вшивается» в логику приложения, а описывается через структурированные сообщения ICU MessageFormat.
Ключевая особенность подхода заключается в разделении логики и
представления текста. Сообщение описывается через
defineMessages, MessageDescriptor или
аналогичные структуры, а затем динамически форматируется через
formatMessage. Это позволяет унифицировать уведомления вне
зависимости от источника события: ошибки, успех операции, предупреждения
или информационные сообщения.
Уведомление в контексте FormatJS представляет собой объект с метаданными:
id)defaultMessage)description)values)Пример базового описания:
import { defineMessages } from 'react-intl';
const messages = defineMessages({
saveSuccess: {
id: 'notifications.save.success',
defaultMessage: 'Данные успешно сохранены',
description: 'Уведомление об успешном сохранении'
}
});
Такой подход позволяет централизованно управлять всеми текстами уведомлений, что особенно важно в больших интерфейсах с множеством событийных сообщений.
Формирование текста уведомления выполняется через
formatMessage, который принимает описание сообщения и
значения для подстановки:
import { useIntl } from 'react-intl';
function SaveButton() {
const intl = useIntl();
const handleSave = async () => {
await saveData();
const text = intl.formatMessage(messages.saveSuccess);
showToast(text);
};
return <button onCl ick={handleSave}>Сохранить</button>;
}
Функция formatMessage гарантирует корректную подстановку
текста в зависимости от текущей локали, включая правила склонения, чисел
и дат, если они используются.
Уведомления редко бывают статичными. Чаще они содержат переменные значения: количество элементов, имена пользователей, суммы, статусы.
ICU MessageFormat позволяет встроить параметры прямо в шаблон:
const messages = defineMessages({
itemsDeleted: {
id: 'notifications.items.deleted',
defaultMessage: 'Удалено {count} элементов'
}
});
Использование:
intl.formatMessage(messages.itemsDeleted, { count: 5 });
Одна из наиболее сложных задач локализации — корректное отображение множественных форм. FormatJS использует ICU plural rules, адаптированные под каждую локаль.
const messages = defineMessages({
inbox: {
id: 'notifications.inbox',
defaultMessage: 'У вас {count, plural, one {# новое сообщение} few {# новых сообщения} many {# новых сообщений} other {# сообщения}}'
}
});
Форматирование:
intl.formatMessage(messages.inbox, { count: 3 });
Система автоматически выбирает правильную форму в зависимости от
языка, например для русского учитываются категории one,
few, many, other.
ICU MessageFormat поддерживает не только числа, но и условия
(select), что особенно полезно для алертов с разными типами
статусов.
const messages = defineMessages({
taskStatus: {
id: 'notifications.task.status',
defaultMessage: 'Задача: {status, select, success {успешно завершена} error {завершена с ошибкой} pending {в процессе} other {неизвестный статус}}'
}
});
Использование:
intl.formatMessage(messages.taskStatus, { status: 'success' });
В реальных приложениях FormatJS редко используется изолированно — чаще он является слоем генерации текста для UI-компонентов уведомлений.
Пример интеграции с toast-менеджером:
function notifySuccess(intl) {
toast.success(
intl.formatMessage({
id: 'notifications.save.success',
defaultMessage: 'Сохранение завершено успешно'
})
);
}
Такой подход позволяет полностью отделить визуальный компонент уведомления от его языкового представления.
Ошибки часто требуют передачи контекста: кода ошибки, имени поля, причины.
const messages = defineMessages({
fieldError: {
id: 'notifications.error.field',
defaultMessage: 'Ошибка в поле {field}: {reason}'
}
});
Использование:
intl.formatMessage(messages.fieldError, {
field: 'Email',
reason: 'неверный формат'
});
Это позволяет создавать единый шаблон ошибок без дублирования строк.
Уведомления часто содержат временные метки. FormatJS предоставляет
FormattedDate, FormattedTime и
intl.formatDate.
intl.formatMessage(
{
id: 'notifications.reminder',
defaultMessage: 'Напоминание: событие состоится {date}'
},
{
date: intl.formatDate(new Date(), {
year: 'numeric',
month: 'long',
day: '2-digit'
})
}
);
Локализация даты выполняется автоматически согласно выбранной локали пользователя.
Уведомления и алерты должны корректно восприниматься скринридерами. При использовании FormatJS текст уведомления уже локализован, но важна его интеграция в ARIA-модель:
aria-live="polite" для информационных сообщенийaria-live="assertive" для ошибокПример:
<div aria-live="polite">
{intl.formatMessage(messages.saveSuccess)}
</div>
FormatJS обеспечивает только текстовый слой, а доступность реализуется на уровне UI-компонентов.
В крупных системах уведомления выносятся в отдельный слой:
/i18n
/messages
notifications.js
errors.js
warnings.js
Каждое сообщение становится независимой единицей, что позволяет:
Частые проблемы при неправильном использовании FormatJS в алертах:
Корректная архитектура требует, чтобы уведомление всегда представляло собой описание, а не готовую строку.
В событийных системах уведомления часто генерируются автоматически:
function handleEvent(event, intl) {
switch (event.type) {
case 'UPLOAD_COMPLETE':
return intl.formatMessage(messages.uploadComplete);
case 'UPLOAD_FAILED':
return intl.formatMessage(messages.uploadFailed, {
file: event.payload.fileName
});
default:
return intl.formatMessage(messages.unknownEvent);
}
}
Такой подход позволяет масштабировать систему уведомлений без усложнения UI-слоя.
FormatJS реагирует на смену локали через IntlProvider.
При смене языка:
formatMessageЭто важно для приложений, где пользователь может менять язык «на лету» без перезагрузки интерфейса.
Сложные алерты могут содержать вложенные значения:
const messages = defineMessages({
backupStatus: {
id: 'notifications.backup.status',
defaultMessage: 'Резервное копирование {status} ({progress}%)'
}
});
intl.formatMessage(messages.backupStatus, {
status: 'в процессе',
progress: 78
});
Такие конструкции позволяют описывать сложные состояния без потери локализационной корректности.
Если перевод для текущей локали отсутствует, FormatJS использует
defaultMessage. Это делает систему устойчивой:
FormatJS поддерживает rich-text форматирование, позволяя вставлять элементы в сообщения:
const messages = defineMessages({
terms: {
id: 'notifications.terms',
defaultMessage: 'Принятие <b>условий использования</b> обязательно'
}
});
Рендер:
intl.formatMessage(messages.terms, {
b: (chunks) => <strong>{chunks}</strong>
});
Это позволяет создавать уведомления с частичным форматированием без нарушения локализационной структуры.
При росте приложения уведомления становятся отдельной подсистемой, где FormatJS выполняет роль слоя генерации текста. В таких архитектурах:
Разделение этих уровней обеспечивает предсказуемость поведения уведомлений и упрощает поддержку мультиязычных интерфейсов.