Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Формы и действия: 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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.