Библиотека superforms

Библиотека Superforms для SvelteKit предназначена для упрощения работы с HTML-формами, обеспечивая строгую типизацию, валидацию, синхронизацию состояния и интеграцию с серверной логикой. Она устраняет типичные проблемы ручной обработки форм: дублирование логики валидации, рассинхронизацию клиентского и серверного состояний, сложность обработки ошибок и повторного заполнения данных.

Ключевая идея — единый источник правды для формы, основанный на схеме (чаще всего с использованием Zod), которая используется и на сервере, и на клиенте.


Установка и базовая настройка

npm install sveltekit-superforms zod

Библиотека работает в связке с:

  • SvelteKit (сервер + клиент)
  • Zod (или альтернативные валидаторы)
  • form actions (стандартный механизм SvelteKit)

Схема валидации как ядро формы

Superforms строится вокруг схемы:

import { z } from 'zod';

export const userSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
  age: z.number().min(18)
});

Особенности:

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

Серверная инициализация формы

В файле +page.server.ts:

import { superValidate } from 'sveltekit-superforms';
import { userSchema } from '$lib/schemas';

export const load = async () => {
  const form = await superValidate(userSchema);
  return { form };
};

Здесь происходит:

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

Обработка отправки формы (actions)

export const actions = {
  default: async ({ request }) => {
    const form = await superValidate(request, userSchema);

    if (!form.valid) {
      return { form };
    }

    // обработка данных
    console.log(form.data);

    return { form };
  }
};

Особенности:

  • superValidate(request, schema) автоматически извлекает и валидирует данные

  • результат содержит:

    • form.valid
    • form.data
    • form.errors

Использование формы на клиенте

В +page.svelte:

<script lang="ts">
  import { superForm } from 'sveltekit-superforms/client';
  export let data;

  const { form, errors } = superForm(data.form);
</script>

<form method="POST">
  <input name="email" bind:value={$form.email} />
  {#if $errors.email}
    <span>{$errors.email}</span>
  {/if}

  <input type="password" name="password" bind:value={$form.password} />
  {#if $errors.password}
    <span>{$errors.password}</span>
  {/if}

  <button type="submit">Submit</button>
</form>

Реактивность и сторы

Superforms использует Svelte store:

  • $form — текущее состояние данных
  • $errors — ошибки
  • $message — сообщения (например, успешная отправка)

Пример:

$form.email = 'test@example.com';

Изменения автоматически отражаются в UI.


Клиентская валидация

Superforms поддерживает валидацию без отправки формы:

const { form, errors, enhance } = superForm(data.form);
<form method="POST" use:enhance>

Преимущества:

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

Работа с ошибками

Ошибки автоматически связываются с полями:

form.errors = {
  email: ['Invalid email']
};

В UI:

{#if $errors.email}
  <span>{$errors.email}</span>
{/if}

Поддерживаются:

  • множественные ошибки
  • вложенные структуры
  • кастомные сообщения

Начальные значения (default values)

const form = await superValidate(userSchema, {
  defaults: {
    email: 'example@mail.com',
    age: 25
  }
});

Работа с вложенными структурами

const schema = z.object({
  user: z.object({
    name: z.string(),
    address: z.object({
      city: z.string()
    })
  })
});

В форме:

<input bind:value={$form.user.name} />
<input bind:value={$form.user.address.city} />

Массивы и динамические поля

const schema = z.object({
  tags: z.array(z.string())
});
{#each $form.tags as tag, i}
  <input bind:value={$form.tags[i]} />
{/each}

Добавление элементов:

$form.tags = [...$form.tags, 'new'];

Кастомная валидация

const schema = z.object({
  password: z.string(),
  confirm: z.string()
}).refine(data => data.password === data.confirm, {
  message: "Passwords must match",
  path: ["confirm"]
});

Сообщения и статусы

return message(form, 'Success!');

На клиенте:

{#if $message}
  <p>{$message}</p>
{/if}

Прогрессивное улучшение (enhance)

const { enhance } = superForm(data.form);
<form use:enhance>

Возможности:

  • AJAX отправка
  • сохранение состояния
  • кастомные обработчики

Кастомизация поведения

const { form } = superForm(data.form, {
  validate: 'input', // или 'submit'
  debounceMs: 300
});

Параметры:

  • validate: когда запускать валидацию
  • debounce: задержка проверки
  • tainted: отслеживание изменений

Работа с файлами

const schema = z.object({
  avatar: z.instanceof(File)
});
<input type="file" name="avatar" />

Интеграция с TypeScript

Типы автоматически выводятся:

type FormData = typeof userSchema._type;

Или:

import type { Infer } from 'zod';
type FormData = Infer<typeof userSchema>;

Переиспользование схем

Схемы можно делить:

const baseUser = z.object({
  email: z.string().email()
});

const extendedUser = baseUser.extend({
  password: z.string().min(8)
});

Middleware и хуки

const form = await superValidate(request, schema, {
  strict: true
});

Дополнительно:

  • перехват ошибок
  • логирование
  • кастомные трансформации

Частые проблемы и решения

1. Несоответствие типов

Решение: использовать одну схему на сервере и клиенте

2. Потеря состояния

Решение: использовать enhance

3. Ошибки не отображаются

Проверка:

  • правильный name у input
  • соответствие схеме

Производительность

Superforms оптимизирован за счёт:

  • минимизации перерисовок
  • работы через store
  • ленивой валидации

Расширение функциональности

Можно подключать:

  • кастомные валидаторы
  • i18n для сообщений
  • интеграцию с UI-библиотеками (Skeleton, Flowbite)

Практический паттерн: разделение логики

schemas.ts

export const schema = z.object({...});

+page.server.ts

superValidate(...)

+page.svelte

superForm(...)

Чёткое разделение:

  • схема
  • сервер
  • UI

Безопасность

  • валидация всегда на сервере
  • клиентская валидация — вспомогательная
  • защита от подмены данных

Итоговая модель работы

  1. Определяется схема
  2. Сервер создаёт форму через superValidate
  3. Клиент подключает superForm
  4. Пользователь взаимодействует с формой
  5. Данные валидируются
  6. Ошибки и состояние синхронизируются автоматически