Form actions в SvelteKit

В SvelteKit Form Actions — это современный подход к обработке форм, который интегрирован с маршрутизацией и серверной логикой. В отличие от классических клиентских обработчиков событий on:submit, Form Actions позволяют работать с формами через серверные функции, обеспечивая безопасное и декларативное управление данными.

Форма, настроенная через Form Actions, может автоматически обрабатывать отправку, валидацию и возвращать ошибки или успех без необходимости использовать отдельные API-запросы.


Структура Form Actions

Форма в SvelteKit связывается с серверной функцией через атрибут action или через экспортированную функцию actions в +page.server.js (или +page.server.ts).

Пример базового использования:

// +page.server.js
export const actions = {
    default: async ({ request }) => {
        const formData = await request.formData();
        const name = formData.get('name');
        const email = formData.get('email');

        if (!name || !email) {
            return { 
                status: 400, 
                errors: { message: 'Все поля обязательны' } 
            };
        }

        // Логика обработки данных, например, сохранение в базу
        return { success: true };
    }
};
<!-- +page.svelte -->
<form method="POST" use:enhance>
    <input type="text" name="name" placeholder="Имя" />
    <input type="email" name="email" placeholder="Email" />
    <button type="submit">Отправить</button>
</form>

Здесь функция default — это Action по умолчанию, которая вызывается при отправке формы.


Подключение Form Actions к клиенту

Для улучшения UX используется хук use:enhance, который позволяет работать с формой асинхронно, не перезагружая страницу. Это обеспечивает плавное обновление состояния формы и отображение ошибок:

import { enhance } from '$app/forms';

let data;
function handleSubmit({ result }) {
    data = result;
}
<form method="POST" use:enhance={{ onSubmit: handleSubmit }}>
    <input name="username" />
    <button type="submit">Отправить</button>
</form>

{#if data?.errors}
    <p class="error">{data.errors.message}</p>
{/if}

{#if data?.success}
    <p class="success">Форма успешно отправлена</p>
{/if}

Ключевой момент: enhance превращает стандартную HTML-форму в мощный инструмент для асинхронной работы с сервером, сохраняя при этом SEO-дружественность и доступность.


Множественные Actions

SvelteKit позволяет определять несколько действий для одной страницы. В +page.server.js это делается так:

export const actions = {
    login: async ({ request }) => { /* логика логина */ },
    register: async ({ request }) => { /* логика регистрации */ }
};

В форме можно указать конкретное действие через атрибут formaction у кнопки:

<form method="POST">
    <input name="email" />
    <input name="password" type="password" />

    <button type="submit" for maction="?/login">Войти</button>
    <button type="submit" for maction="?/register">Регистрация</button>
</form>

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


Валидация и обработка ошибок

Form Actions интегрируются с механизмами валидации данных на сервере. Возвращаемые объекты могут содержать errors и status, которые автоматически передаются обратно клиенту:

if (!email.includes('@')) {
    return {
        status: 422,
        errors: { email: 'Некорректный email' }
    };
}

На клиенте ошибки можно отобразить динамически:

{#if data?.errors?.email}
    <span class="error">{data.errors.email}</span>
{/if}

Преимущества Form Actions

  • Серверная обработка: данные обрабатываются на сервере, что повышает безопасность.
  • Автоматическая интеграция с формой: нет необходимости вручную отправлять fetch запросы.
  • Управление несколькими действиями: одна страница может обрабатывать разные действия.
  • Поддержка асинхронного UX: через use:enhance форма работает без перезагрузки страницы.
  • Полная совместимость с HTML: формы остаются стандартными, SEO-дружественными и доступными.

Работа с загрузкой и состоянием формы

SvelteKit предоставляет объект form через стор form:

<script>
    import { form } from '$app/forms';
</script>

<form method="POST" use:enhance>
    <input name="name" />
    <button type="submit">Отправить</button>
</form>

{#if $form.submitting}
    <p>Отправка...</p>
{/if}

Состояние формы (submitting, data, errors) можно использовать для создания индикаторов загрузки и динамических сообщений.


Поддержка TypeScript

Form Actions полностью поддерживают TypeScript, что позволяет строго типизировать входные данные и возвращаемые результаты:

export const actions: Actions = {
    default: async ({ request }) => {
        const formData = await request.formData();
        const email = formData.get('email') as string;
        if (!email) return { status: 400, errors: { email: 'Обязательное поле' } };
        return { success: true };
    }
};

Типизация повышает безопасность кода и предотвращает ошибки на этапе компиляции.


Использование с UI-библиотеками

Form Actions легко интегрируются с компонентными библиотеками, такими как SvelteKit UI libs, позволяя создавать формы с красивым интерфейсом, динамическими сообщениями об ошибках и кнопками загрузки. Компоненты оборачиваются вокруг стандартных форм и используют use:enhance для асинхронного UX.


Эта архитектура делает Form Actions в SvelteKit мощным инструментом для построения форм любой сложности, обеспечивая безопасность, отзывчивость и простоту интеграции с серверной логикой.