Handling forms in SvelteKit using Superforms
Aleksi Koivu
Founder -- KoivuDev
December 9, 2023
Introduction
Form handling and validation is a surprisingly difficult and complex topic. Fortunately in the modern web development landscape a lot of convenient libraries and platforms have emerged to ease the work of developers. This article goes through the steps of handling form data using the Superforms library in SvelteKit, and then processing that data in a database (Supabase) and eventually sending an email using Rebase.
Superforms
This section assumes that you have already set up your SvelteKit project and have some experience with SvelteKit’s syntax and conventions. If this isn’t the case, refer to the comprehensive SvelteKit documentation and set up and learn about your project before proceeding.
Installation
Start off by installing the Superforms package alongside zod, using your preferred package manager (the example uses npm).
npm i -D sveltekit-superforms zod
Server-side configuration
The main thing required to create a Superform is a Zod validation schema. This schema represents the form data. The Zod documentation has more details for creating schemas. Add the validation schema to your src/routes/+page.server.ts
file to ensure the client has access to it:
import { z } from 'zod';
import { superValidate } from 'sveltekit-superforms/server';
const schema = z.object({
name: z.string().default('Hello world!'),
email: z.string().email()
});
export const load = async () => {
// Server API:
const form = await superValidate(schema);
// Unless you throw, always return { form } in load and form actions.
return { form };
};
Client-side configuration
Now that the Superforms validation is set up on the server side, we can move onto attaching it onto our form on the frontend.
src/routes/+page.svelte</>
<script>
import type { PageData } from './$types';
import { superForm } from 'sveltekit-superforms/client';
export let data: PageData;
// Client API:
const { form } = superForm(data.form);
</script>
<form method="POST">
<label for="name">Name</label>
<input type="text" name="name" bind:value={$form.name} />
<label for="email">E-mail</label>
<input type="email" name="email" bind:value={$form.email} />
<div><button>Submit</button></div>
</form>
This will fetch the validator along with its schema from the server side and bind the input fields’ values on to the form.
Submitting to Supabase
Next, we will look at how this form data can be submitted to and saved in Supabase.