Множественные языки

Библиотека Yup предоставляет встроенный механизм локализации сообщений ошибок валидации. Это позволяет адаптировать текст ошибок под разные языки интерфейса без изменения бизнес-логики схем.

Каждое стандартное правило валидации в Yup использует текстовые сообщения по умолчанию, которые могут быть переопределены глобально или локально для конкретных схем.


Глобальная настройка языка через setLocale

Основной механизм управления языковыми сообщениями реализуется через setLocale.

import * as Yup from 'yup';

Yup.setLocale({
  mixed: {
    required: 'Обязательное поле',
    notType: 'Неверный тип данных',
  },
  string: {
    min: 'Минимальная длина ${min} символов',
    max: 'Максимальная длина ${max} символов',
  },
  number: {
    min: 'Значение должно быть не меньше ${min}',
    max: 'Значение должно быть не больше ${max}',
  }
});

Особенности механизма

  • Локализация применяется ко всем схемам, созданным после вызова setLocale
  • Поддерживаются плейсхолдеры (${min}, ${max}, ${path})
  • Возможна частичная переопределяемость (только нужные типы и правила)

Локализация на уровне схемы

Глобальные настройки могут быть переопределены внутри конкретной схемы:

const schema = Yup.object({
  username: Yup.string()
    .required('Введите имя пользователя')
    .min(3, 'Слишком короткое имя'),
});

Такой подход используется, когда требуется:

  • контекстно-зависимый текст ошибок
  • разные формулировки в разных формах
  • бизнес-специфичные сообщения

Динамическая смена языка

В приложениях с поддержкой нескольких языков часто требуется менять язык интерфейса без перезагрузки.

const locales = {
  ru: {
    mixed: { required: 'Обязательное поле' },
    string: { min: 'Минимум ${min} символа' }
  },
  en: {
    mixed: { required: 'Required field' },
    string: { min: 'Minimum ${min} characters' }
  }
};

function applyLocale(lang) {
  Yup.setLocale(locales[lang]);
}

Важный момент

После вызова setLocale новые схемы будут использовать обновлённые сообщения. Уже созданные схемы сохраняют предыдущие значения, если сообщения были зафиксированы в момент создания.


Интеграция с системами i18n

В реальных приложениях Yup часто используется совместно с библиотеками интернационализации, такими как i18next.

Подход с функциями

import i18n from 'i18next';
import * as Yup from 'yup';

Yup.setLocale({
  mixed: {
    required: () => i18n.t('validation.required')
  },
  string: {
    min: ({ min }) => i18n.t('validation.min', { min })
  }
});

Преимущества такого подхода

  • сообщения генерируются динамически
  • поддерживается мгновенное переключение языка
  • нет необходимости пересоздавать схемы

Контекстные сообщения с параметрами

Yup поддерживает передачу параметров в функции сообщений:

Yup.string()
  .min(5, ({ min, path }) =>
    `${path} должен содержать минимум ${min} символов`
  );

Доступные параметры:

  • path — имя поля
  • value — текущее значение
  • min, max — ограничения
  • originalValue — исходное значение

Поддержка множественных языков в сложных схемах

В сложных объектах с вложенной структурой локализация применяется ко всем уровням:

const schema = Yup.object({
  user: Yup.object({
    name: Yup.string().required(),
    profile: Yup.object({
      age: Yup.number().min(18)
    })
  })
});

При использовании setLocale сообщения автоматически распространяются на вложенные схемы без дополнительных настроек.


Условная локализация

Иногда требуется менять язык в зависимости от состояния приложения:

function createSchema(lang) {
  const messages = {
    ru: 'Обязательное поле',
    en: 'Required field'
  };

  return Yup.object({
    email: Yup.string().required(messages[lang])
  });
}

Такой подход применяется, когда глобальная локализация нежелательна.


Ошибки и fallback-язык

При отсутствии перевода Yup не выбрасывает ошибку, а использует:

  • стандартные сообщения библиотеки
  • либо последние установленные значения через setLocale

Это позволяет безопасно внедрять новые языки постепенно.


Типизация и языки

При использовании TypeScript локализация сообщений не влияет на типизацию схем, но важно учитывать:

  • функции сообщений должны возвращать string
  • параметры ошибок типизируются автоматически при использовании Yup типов

Производительность при мультиязычности

Использование функций в setLocale может влиять на производительность при массовой валидации:

  • статические строки быстрее
  • функции обеспечивают гибкость, но требуют вызова при каждой ошибке

Баланс достигается смешанным подходом: статические сообщения + функции только там, где необходим динамический текст.


Практика разделения языковых файлов

Часто локализация выносится в отдельные модули:

export const yupRu = {
  mixed: {
    required: 'Обязательное поле'
  }
};

export const yupEn = {
  mixed: {
    required: 'Required field'
  }
};

И затем подключается централизованно:

Yup.setLocale(yupRu);

Поведение при асинхронной смене языка

Если язык меняется во время работы формы:

  • текущие ошибки могут оставаться на старом языке
  • новые валидации используют обновлённые сообщения
  • для полной синхронизации требуется повторная валидация схемы

Кастомные языковые правила

Можно расширять стандартные сообщения под бизнес-логику:

Yup.addMethod(Yup.string, 'cyrillicOnly', function (message) {
  return this.matches(/^[а-яА-Я]+$/, message);
});

И использовать локализованные тексты:

Yup.string().cyrillicOnly('Только кириллица');

Мультиязычные формы и серверная валидация

При серверной валидации важно:

  • передавать код языка вместе с запросом
  • синхронизировать сообщения с фронтендом
  • избегать жёстко зашитых строк на сервере

Это обеспечивает единообразие ошибок между клиентом и сервером при использовании Yup-схем как общего контракта валидации.