Формы и form actions
Form actions в +page.server.js обрабатывают отправку форм на сервере и работают даже без JavaScript.
«Если load читает данные с сервера, то actions их записывают.» Формы в SvelteKit устойчивы: они работают и без JS, и лучше с ним.
Загрузчик load читает данные, а как их записывать — создавать пост, логиниться, оставлять комментарий? Для этого в SvelteKit есть form actions. В файле +page.server.js вы экспортируете объект actions с функциями-обработчиками отправки формы. Браузер шлёт обычный POST-запрос формы, сервер его обрабатывает.
Ключевая идея — прогрессивное улучшение. Форма работает на чистом HTML без единой строчки JavaScript: браузер отправляет данные, сервер отвечает. А если JavaScript есть, директива use:enhance перехватывает отправку и делает её без перезагрузки страницы, плавно. То есть базовая функциональность доступна всем, а улучшения — поверх. Это делает приложение надёжнее.
// src/routes/contact/+page.server.js
import { fail } from '@sveltejs/kit';
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const email = data.get('email');
if (!email) return fail(400, { error: 'Email обязателен' });
await saveContact(email);
return { success: true };
}
};<!-- src/routes/contact/+page.svelte -->
<script>
import { enhance } from '$app/forms';
let { form } = $props(); // результат action
</script>
<form method="POST" use:enhance>
<input name="email" type="email" />
<button>Отправить</button>
</form>
{#if form?.error}<p>{form.error}</p>{/if}
{#if form?.success}<p>Спасибо!</p>{/if}Внутри action используют служебные функции: fail(status, data) возвращает ошибку валидации с данными для повторного показа формы, redirect(status, location) уводит на другую страницу, error(status, message) бросает ошибку. Можно объявить несколько именованных действий (например, login и register) и выбирать их атрибутом action у формы.
Как это работает под капотом
Форма с method="POST" отправляет данные на тот же URL, SvelteKit находит нужный action, выполняет его и либо возвращает результат в проп form, либо делает редирект. Смоделируем обработку отправки с валидацией.
// Обработка form action: валидация -> успех или fail
function fail(status, data) { return { status, ...data, ok: false }; }
async function action(formData) {
const email = formData.email;
if (!email) return fail(400, { error: 'Email обязателен' });
if (!email.includes('@')) return fail(400, { error: 'Неверный email' });
return { status: 200, success: true, ok: true };
}
action({}).then(r => console.log(r)); // {error: 'Email обязателен'}
action({ email: 'нет' }).then(r => console.log(r)); // {error: 'Неверный email'}
action({ email: '[email protected]' }).then(r => console.log(r)); // {success: true}Попробуй сам ▶ — вставь код в консоль браузера (F12 → Console) и нажми Enter, чтобы увидеть вывод.
<form method=POST use:enhance>
|
v
actions в +page.server.js
|
+-- ошибка -> fail() -> проп form (показать сообщение)
+-- успех -> данные или redirect()
(без JS — то же, но с перезагрузкой страницы)Частые ошибки
- Возвращать ошибку валидации через
throwвместоfail.failсохраняет данные формы для повторного показа. - Забыть
method="POST"у формы. Без него action не вызовется. - Полагаться только на JS-валидацию. Проверяйте данные на сервере — это безопаснее.
Best practices
- Добавляйте
use:enhanceдля плавного UX, но не ломайте работу без JS. - Валидируйте на сервере и возвращайте
failс понятными сообщениями. - Для многошаговых сценариев используйте именованные actions.
Почему прогрессивное улучшение важно
Идея, что форма должна работать без JavaScript, в эпоху одностраничных приложений может показаться старомодной — но за ней стоит серьёзная инженерная мудрость. JavaScript на странице может не загрузиться: оборвалась сеть, скрипт упал с ошибкой, пользователь сидит за корпоративным прокси, который что-то вырезал. Если ваша форма построена как нативная HTML-форма с серверным action, она продолжит работать даже в этих условиях — браузер просто отправит данные обычным запросом. А когда JavaScript есть, директива use:enhance бесшовно перехватывает отправку и делает её плавной, без перезагрузки. Так вы получаете лучшее из двух миров: надёжную базу, доступную всем, и приятный UX поверх неё для большинства. Этот подход также дисциплинирует: раз форма обязана работать через сервер, вы неизбежно пишете серверную валидацию, а не полагаетесь только на клиентскую, которую легко обойти. В итоге приложение получается и доступнее, и безопаснее.
Итог: form actions обрабатывают отправку форм на сервере, работают без JavaScript и улучшаются через use:enhance. Используйте fail, redirect и error для управления результатом.