Sveltekit에서 form을 통해 데이터를 POST 하는 방법


스벨트킷에서는 <form> 태그를 사용해 서버에 데이터를 POST하는 기능을 제공합니다. 이 Form Actions라는 기능을 사용하면 client-side 자바스크립트를 최소화, 또는 아예 없이 POST 메시지를 호출할 수 있습니다.

기본 동작

가장 간단한 경우, 즉 페이지에 하나의 form만 존재하는 경우에는 +page.server.ts에서 export한 actions.default 함수가 호출됩니다.

// +page.svelte
<form method="POST">
    <label>
        Email
        <input name="email" type="email" />
    </label>
    <label>
        Password
        <input name="password" type="password" />
    </label>
    <button>Log in</button>
</form>
// +page.server.ts
import type { Actions } from './$types';

export const actions = {
    default({ request }) {
        const formData = await request.formData();

        const email = formData.get('email');
        const password = formData.get('password');

        return { success: true };
    }
} satisfies Actions;

actions.default 함수는 RequestEvent 객체를 받아, request.formData()를 사용하여 데이터를 읽을 수 있습니다. 요청을 처리한 후 동작은 다음 업데이트까지 해당 페이지의 폼 속성 및 $page.form 앱 전체를 통해 사용할 수 있는 데이터로 응답할 수 있습니다.

<script lang="ts">
    import type { ActionData } from './$types';
    import form from '$page.form';

    export let form: ActionData;

    // or
    import { page } from '$app/stores';

    $: form = $page.form;
</script>

{#if form.success}
    <p>Logged in!</p>
{/if}

Named Actions

페이지에 여러 form이 있는 경우, actions 객체를 내보내고 각 form에 action 속성을 추가하여 actions 객체의 특정 동작을 호출할 수 있습니다.

// +page.svelte
<form method="POST" action="?/foo" />
<form method="POST" action="?/bar" />
// +page.server.ts

export const actions = {
    foo({ request }) {
        // ...
    },
    bar({ request }) {
        // ...
    }
} satisfies Actions;

유효성 검사

Input validation 결과 요청이 유효하지 않은 경우, fail 함수를 호출하여 클라이언트에게 오류를 알릴 수 있습니다.

import type { Actions } from './$types';
import { fail } from '@sveltejs/kit';

export const actions = {
    default({ request }) {
        const formData = await request.formData();

        const email = formData.get('email');
        const password = formData.get('password');

        if (!email || !password) {
            return fail(400, { message: 'Email and password are required' });
        }

        return { success: true };
    }
} satisfies Actions;

리다이렉션

리다이렉션은 load에서와 마찬가지로 작동합니다.

import type { Actions } from './$types';
import { redirect } from '@sveltejs/kit';

export const actions = {
    default({ request }) {
        const formData = await request.formData();

        const email = formData.get('email');
        const password = formData.get('password');

        throw redirect('/');
    }
} satisfies Actions;