Библиотека Superforms для SvelteKit предназначена для упрощения работы с HTML-формами, обеспечивая строгую типизацию, валидацию, синхронизацию состояния и интеграцию с серверной логикой. Она устраняет типичные проблемы ручной обработки форм: дублирование логики валидации, рассинхронизацию клиентского и серверного состояний, сложность обработки ошибок и повторного заполнения данных.
Ключевая идея — единый источник правды для формы, основанный на схеме (чаще всего с использованием Zod), которая используется и на сервере, и на клиенте.
npm install sveltekit-superforms zod
Библиотека работает в связке с:
Superforms строится вокруг схемы:
import { z } from 'zod';
export const userSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
age: z.number().min(18)
});
Особенности:
В файле +page.server.ts:
import { superValidate } from 'sveltekit-superforms';
import { userSchema } from '$lib/schemas';
export const load = async () => {
const form = await superValidate(userSchema);
return { form };
};
Здесь происходит:
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.validform.dataform.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}
Поддерживаются:
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}
const { enhance } = superForm(data.form);
<form use:enhance>
Возможности:
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" />
Типы автоматически выводятся:
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)
});
const form = await superValidate(request, schema, {
strict: true
});
Дополнительно:
1. Несоответствие типов
Решение: использовать одну схему на сервере и клиенте
2. Потеря состояния
Решение: использовать enhance
3. Ошибки не отображаются
Проверка:
name у inputSuperforms оптимизирован за счёт:
Можно подключать:
schemas.ts
export const schema = z.object({...});
+page.server.ts
superValidate(...)
+page.svelte
superForm(...)
Чёткое разделение:
superValidatesuperForm