Email, url и другие встроенные форматы

В экосистеме валидации форм JavaScript одним из наиболее распространённых инструментов является связка Yup + YupResolver, используемая вместе с React Hook Form. Основная ценность Yup заключается в декларативном описании схем данных, где каждый тип имеет набор встроенных методов валидации.

Для строковых значений ключевую роль играют специализированные валидаторы форматов, среди которых особенно часто применяются email() и url().


Базовая структура Yup-схемы

Любая схема начинается с определения структуры объекта:

import * as Yup from "yup";

const schema = Yup.object({
  email: Yup.string(),
  website: Yup.string(),
});

На этом уровне поля существуют, но не имеют ограничений. Вся сила Yup раскрывается при добавлении встроенных методов.


Валидатор email()

Метод email() проверяет соответствие строки стандартному формату электронной почты. Проверка выполняется на основе регулярного выражения, встроенного в библиотеку.

Простейший пример

const schema = Yup.object({
  email: Yup.string()
    .email("Некорректный формат email")
    .required("Email обязателен"),
});

Поведение валидатора

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

Важные особенности

email() не гарантирует существование адреса, он проверяет только синтаксис. Следовательно, адрес test@domain.fake будет считаться валидным.


Комбинация email() с дополнительными ограничениями

На практике email редко используется отдельно. Обычно он комбинируется с дополнительными строковыми правилами:

const schema = Yup.object({
  email: Yup.string()
    .trim()
    .lowercase()
    .email("Некорректный email")
    .max(255, "Слишком длинный email")
    .required("Обязательное поле"),
});

Разбор цепочки

  • trim() — удаляет пробелы по краям
  • lowercase() — нормализует регистр
  • email() — проверяет формат
  • max() — ограничивает длину

Такой подход обеспечивает не только проверку, но и нормализацию данных.


Валидатор url()

Метод url() используется для проверки корректности веб-адресов.

Базовый пример

const schema = Yup.object({
  website: Yup.string()
    .url("Некорректный URL")
    .required("Укажите сайт"),
});

Что считается валидным URL

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

Недопустимые:

  • example.com (без протокола)
  • http//missing-colon.com
  • ftp://example.com (в зависимости от реализации Yup может не проходить)

Особенности работы url() в Yup

1. Требование протокола

В большинстве случаев Yup ожидает наличие протокола http:// или https://.

2. Строгая структура

URL проверяется на:

  • наличие домена
  • корректные символы
  • допустимые пути
  • правильный формат query string

Комбинирование url() с трансформациями

const schema = Yup.object({
  website: Yup.string()
    .trim()
    .url("Неверный формат ссылки")
    .lowercase()
    .required(),
});

Порядок имеет значение: трансформации выполняются до финальной проверки.


Другие встроенные строковые форматы в Yup

Помимо email и url, библиотека предоставляет дополнительные методы для работы со строками.


matches(): кастомные форматы через регулярные выражения

Метод matches() позволяет описывать любые форматы вручную.

Пример: телефонный номер

const schema = Yup.object({
  phone: Yup.string()
    .matches(
      /^\+?[0-9]{10,15}$/,
      "Некорректный номер телефона"
    )
});

Особенности

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

uuid() и идентификаторы

В Yup нет отдельного uuid() во всех версиях, но часто используется через matches():

const schema = Yup.object({
  id: Yup.string().matches(
    /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
    "Некорректный UUID"
  ),
});

lowercase() и uppercase()

Методы нормализации регистра:

const schema = Yup.object({
  code: Yup.string()
    .uppercase()
    .required(),
});

или

const schema = Yup.object({
  username: Yup.string()
    .lowercase()
    .required(),
});

trim(): очистка строк

Удаляет пробелы по краям:

Yup.string().trim()

Особенно важно для email и url, где лишние пробелы приводят к неочевидным ошибкам.


min() и max() для строк

Ограничение длины:

const schema = Yup.object({
  title: Yup.string()
    .min(5, "Слишком коротко")
    .max(100, "Слишком длинно"),
});

required() и nullable()

required()

Yup.string().required("Поле обязательно")

Отклоняет:

  • undefined
  • null
  • пустую строку (в зависимости от конфигурации)

nullable()

Yup.string().nullable()

Позволяет явно хранить null.


Встроенные форматы в связке с YupResolver

При использовании React Hook Form Yup интегрируется через resolver:

import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

const schema = Yup.object({
  email: Yup.string().email().required(),
  website: Yup.string().url(),
});

const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm({
  resolver: yupResolver(schema),
});

Как работает YupResolver

  • получает схему Yup
  • валидирует данные формы целиком
  • возвращает структурированные ошибки
  • синхронизирует результат с React Hook Form

Поведение ошибок в встроенных форматах

Каждый валидатор (email, url, matches) возвращает стандартный объект ошибки:

{
  path: "email",
  message: "Некорректный формат email",
  value: "test@"
}

Это позволяет унифицировать обработку UI-ошибок.


Частые ошибки при использовании email и url

1. Отсутствие trim()

Yup.string().email()

Пробел в конце делает адрес невалидным.


2. Неправильный порядок методов

Yup.string()
  .email()
  .trim()

Ошибка: trim должен идти до email.


3. Ожидание проверки существования адреса

email() не выполняет DNS-проверку и не проверяет почтовый сервер.


Сочетание встроенных форматов с кастомной логикой

const schema = Yup.object({
  email: Yup.string()
    .trim()
    .lowercase()
    .email("Ошибка email")
    .test("no-disposable", "Временные email запрещены", (value) => {
      if (!value) return true;
      return !value.includes("tempmail");
    }),
});

Стратегия построения устойчивых схем

Встроенные форматы Yup эффективны при соблюдении нескольких принципов:

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

Поведение при пустых значениях

Методы email() и url() не заменяют required(). Без него поле может считаться валидным даже при пустом значении:

Yup.string().email() // пустая строка может пройти

Корректный вариант:

Yup.string().email().required()