Form actions handle POST requests in SvelteKit. They're the preferred way to mutate data.
Basic Form Action
javascript// src/routes/contact/+page.server.js export const actions = { default: async ({ request }) => { const formData = await request.formData(); const email = formData.get('email'); const message = formData.get('message'); await saveContactMessage({ email, message }); return { success: true }; } };
svelte<!-- src/routes/contact/+page.svelte --> <script> let { form } = $props(); </script> {#if form?.success} <p class="success">Message sent!</p> {/if} <form method="POST"> <input name="email" type="email" required /> <textarea name="message" required></textarea> <button type="submit">Send</button> </form>
Named Actions
Have multiple actions on one page:
javascript// +page.server.js export const actions = { login: async ({ request, cookies }) => { const data = await request.formData(); const user = await authenticate(data.get('email'), data.get('password')); cookies.set('session', user.sessionId, { path: '/' }); return { success: true }; }, register: async ({ request }) => { const data = await request.formData(); await createUser(data.get('email'), data.get('password')); return { success: true }; }, logout: async ({ cookies }) => { cookies.delete('session', { path: '/' }); } };
svelte<!-- Call specific action with ?/actionName --> <form method="POST" action="?/login"> <input name="email" type="email" /> <input name="password" type="password" /> <button>Login</button> </form> <form method="POST" action="?/register"> <input name="email" type="email" /> <input name="password" type="password" /> <button>Register</button> </form> <form method="POST" action="?/logout"> <button>Logout</button> </form>
Returning Errors
javascriptimport { fail } from '@sveltejs/kit'; export const actions = { default: async ({ request }) => { const data = await request.formData(); const email = data.get('email'); if (!email.includes('@')) { return fail(400, { email, error: 'Invalid email address' }); } // Success return { success: true }; } };
svelte<script> let { form } = $props(); </script> {#if form?.error} <p class="error">{form.error}</p> {/if} <form method="POST"> <input name="email" value={form?.email ?? ''} /> <button>Submit</button> </form>