Form validation with SvelteKit and Zod

Justin's profile pic

Justin Ahinon

Last updated on

Enter your email to get this article emailed to you

If you have ever built a form with SvelteKit, you already know that the experience is quite amazing. The framework provides a lot of tools to help you build forms, make requests, and pass data between the client and the server. You can make that experience even better by using type safe validation for your forms with Zod.

But first, what is Zod?

You can think of Zod as a schema builder and validation for your JavaScript/TypeScript applications. It’s a very developer-friendly tool that provides a ton of features to help you safely consume and validate data.

Here is a quick example of what Zod can do for you:

TYPESCRIPT

You can use a  try/catch  block to catch the error to avoid your application crashing, or use Zod  safeParse  to avoid throwing an error.

Now that you have a basic understanding of what Zod is, let’s see how we can use it to validate our SvelteKit forms.

What are we building?

For the purpose of this post, we will build a simple software engineers talent directory application. Users will be able to use a form to add their profile to the directory. To keep things simple and focused on the topic, we will not handle things like authentication and authorization.

Basic structure for our SvelteKit project

Our project basically consists of a root  +page.svelte  that contains our app form and a  +page.server.ts  server route to handle the form submission and validation.

SVELTE

Notice here that I used the  use:enhance  to enable progressive enhancement for our form. All the forms fields are required, and we will use Zod to make sure this is respected.

In my page server route, I declare the schema for a talent profile.

TYPESCRIPT

It is also possible to customize the error messages that Zod returns, like this:

TYPESCRIPT

I use  .trim()  to remove any whitespace from the string before validating it. We also use  .min(1)  to make sure the string is not empty.

I can now use these in my SvelteKit form actions to handle the form submission and validation.

TYPESCRIPT

In the snippet above, we get the form data from the request, and safely parse it using our predefined schema (remember, safe parsing will not throw an error).

Here’s what the console output looks like after submitting correct data through the form:

JSON

We can simulate incorrect data submission by removing the  required  attribute from the  name  and  email  fields to see what’s outputted in the console:

JSON

We now have a bit of idea of how we will use the  safeParse  method to validate our form data.

Handling form validation errors

Since Zod returns a  success  boolean and an  errors  array, we can use these to create the necessary logic to handle form validation errors.

TYPESCRIPT

The  invalid()  function comes in very handy here to return a validation error object to the client.

In the current state, we will not see any behavioral change in the client side after we submit incorrect data through the form. That’s because, even if we return a validation error object, our client doesn’t know yet how to handle it.

Let’s fix that by adding a bit of client side logic.

SVELTE

Here, we use the  form  variable (it needs to be named  form  for the form actions to work) to log the form data to the console. We also use the  $:  syntax to log the form data to the console whenever it changes.

Here’s what  console.log()  gives us:

Form date on the frontend

Let’s generate and display some error messages based on the  form  data.

SVELTE

We now get these nice error notices after submitting incorrect data through the form:

Form error notices

Going further

We can go further by extracting the form errors notices into a standalone component and use JavaScript to append each error message next to the corresponding input field.

Wrapping up

Out of the box, SvelteKit already provides a ton of useful features to handle forms submission and validation. Adding Zod to that mix makes it even more powerful. The possibilities are endless.