Формы и действия: actions
Действие (action) — серверная функция, которая принимает отправленную HTML-форму. Её объявляют в +page.server.js рядом со страницей формы. Форма работает даже без JavaScript в браузере, а с ним — без перезагрузки страницы.
Страница с формой
Создайте src/routes/blog/new/+page.svelte:
<!-- src/routes/blog/new/+page.svelte -->
<h1>Новая статья</h1>
<form method="POST">
<input name="title" placeholder="Заголовок" />
<textarea name="body" placeholder="Текст"></textarea>
<button>Опубликовать</button>
</form>Атрибут method="POST" обязателен: действия отвечают только на POST-запросы. На http://localhost:5173/blog/new появится форма, но отправлять её пока некуда.
Действие
Создайте src/routes/blog/new/+page.server.js:
// src/routes/blog/new/+page.server.js
import { redirect } from '@sveltejs/kit';
import { addPost } from '$lib/server/posts.js';
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const title = data.get('title');
const body = data.get('body');
const slug = title.toLowerCase().replaceAll(' ', '-');
addPost({ slug, title, body });
redirect(303, `/blog/${slug}`);
}
};Действие default получает данные формы из request.formData(), сохраняет статью и перенаправляет на её страницу. Заполните форму и нажмите «Опубликовать» — откроется новая статья, а на /blog она появится в списке. Код 303 говорит браузеру открыть новый адрес обычным GET-запросом.
Проверка данных
Если заголовок пуст, вернём форму с ошибкой функцией fail:
// src/routes/blog/new/+page.server.js (начало действия)
import { fail, redirect } from '@sveltejs/kit';
// внутри default, сразу после чтения полей:
if (!title) {
return fail(400, { body, missing: true });
}Объект из fail придёт на страницу в свойстве form:
<!-- src/routes/blog/new/+page.svelte -->
<script>
let { form } = $props();
</script>
<form method="POST">
{#if form?.missing}<p class="error">Введите заголовок</p>{/if}
<input name="title" placeholder="Заголовок" />
<textarea name="body" placeholder="Текст">{form?.body ?? ''}</textarea>
<button>Опубликовать</button>
</form>Отправьте форму без заголовка — над полем появится «Введите заголовок», а введённый текст сохранится.
use:enhance
Без JavaScript браузер при отправке перезагружает страницу. Директива use:enhance из $app/forms отправляет форму в фоне и обновляет form и данные страницы на месте:
<!-- src/routes/blog/new/+page.svelte -->
<script>
import { enhance } from '$app/forms';
let { form } = $props();
</script>
<form method="POST" use:enhance>
<input name="title" placeholder="Заголовок" />
<button>Опубликовать</button>
</form>Поведение то же, но без мигания страницы. Если JavaScript отключён, форма продолжит работать обычным способом.
Частая ошибка
Объявить действие в +page.js вместо +page.server.js. Действия выполняются только на сервере, и SvelteKit их там не найдёт: отправка формы закончится ошибкой 405 «Method Not Allowed». Объект actions экспортируйте из +page.server.js.