Using Zod with FormKit
Tags: zod, typescript, webdev, tutorial
Published: 2023-05-18 19:11:00

---
title: Using Zod with FormKit
published: true
description: With the new @formkit/zod plugin it's easy to validate your FormKit forms using Zod.
tags: zod, typescript, webdev, tutorial
cover_image: https://s3.amazonaws.com/cdn.formk.it/web-assets/articles/zod-with-formkit.png
# Use a ratio of 100:42 for best results.
published_at: 2023-05-18 19:11 +0000
---

Starting with Beta 17 — [FormKit](https://formkit.com) ships with a new [Zod plugin](https://formkit.com/plugins/zod) that you can use to validate your forms.

By leveraging [Zod](https://zod.dev) for your form validation you are able to use the same type-definitions to validate your application’s data on the front-end and the back-end — saving you time and reducing the opportunities for malformed data to find its way into your database.

The FormKit Zod plugin not only validates your data before it is submitted — it provides **real-time validation feedback on a per-input level**! No more giant block of Zod errors at the top or bottom of your form on submit. 🚀

It's easy to set up and use, so let's get started!

## Installation

To start, we will need to install both the `@formkit/zod` and `zod` packages into our FormKit project.

```sh
# npm, yarn, pnpm — whatever you prefer
npm install @fomkit/zod zod
```

(Don't have FormKit set up in your project yet? [Read the getting started docs here](https://formkit.com/getting-started/installation).)

## Setup 

Now in our project we will be able to import `createZodPlugin` from `@formkit/zod` and provide it with a schema we can define using the `z` import from `zod`.

`createZodPlugin` accepts two arguments:
- `zodSchema`: The Zod schema that we define in our app (or more likely import from a shared location).
- `submitCallback`: A function that receives valid `formData` and allows us to do something with it.

`createZodPlugin` returns a tuple with two values:
- `zodPlugin`: The plugin that should be added to your target FormKit form.
- `submitHandler`: The submit handler function to be attached to your target form. It is responsible for validating your form data against the provided Zod schema and calling your `submitCallback` when the data is valid.

The structure for setup in a Vue file looks like the following:

```vue
<script setup>
import { createZodPlugin } from '@formkit/zod'
import { z } from 'zod'

const zodSchema = z.object({
  // Zod schema here...
  // in a real app you probably import this 
  // from somewhere else.
})

const [zodPlugin, submitHandler] = createZodPlugin(
  zodSchema,
  async (formData) => {
    // a submit function here where we 
    // do something with our valid data.
  }
)
</script>

<template>
  <FormKit 
    type="form"
    :plugins="[zodPlugin]"
    @submit="submitHandler"
  >
     <!-- Your matching form structure here -->
  </FormKit>
</template>
```

## A real example

Here is a full example — first the code block and then a live demo of the output — using the above setup code. 

Note that there are no `validation` props on our `FormKit` components — all validation is being derived from the provided Zod schema.

```vue
<script setup>
import { createZodPlugin } from '@formkit/zod'
import { z } from 'zod'

const zodSchema = z.object({
  personalInfo: z.object({
    firstName: z.string().min(3).max(25),
    lastName: z.string().min(3).max(25),
  }),
  email: z.string().email(),
  features: z.string().array().min(2),
})

const [zodPlugin, submitHandler] = createZodPlugin(
  zodSchema,
  async (formData) => {
    // fake async submit handler, but this is where you
    // do something with your valid data.
    await new Promise((r) => setTimeout(r, 2000))
    alert('Form was submitted!')
    console.log(formData)
  }
)
</script>

<template>
  <h1>Validation from Zod schema</h1>
  <FormKit 
    type="form" 
    :plugins="[zodPlugin]" 
    @submit="submitHandler"
  >
    <FormKit type="group" name="personalInfo">
      <FormKit
        type="text"
        name="firstName"
        label="First Name"
      />
      <FormKit 
        type="text" 
        name="lastName" 
        label="Last Name" 
      />
    </FormKit>
    <FormKit 
     type="text" 
     name="email" 
     label="Your email" 
    />
    <FormKit
      type="checkbox"
      name="features"
      label="Zod features"
      :options="['Validation', 'Type-Safety', 'Reusability']"
    />
  </FormKit>
</template>
```

Here's the same example in an interactive demo with `validationVisibility` set to `live` for demonstration purposes. If your browser does not support the embed, click the `Fork on StackBlitz` button to open in a new tab.

{% embed https://stackblitz.com/edit/vue3-script-setup-with-vite-ptlbhx?ctl=1&embed=1&file=src/App.vue&view=preview %}

## Conclusion

That's a brief overview of the new Zod plugin that ships with FormKit. If you'd like to learn more you can [read the official documentation on FormKit.com](https://formkit.com/plugins/zod).

More of a visual learner? VueSchool.io has released a free 8-minute video that covers the FormKit Zod plugin. You can [watch it for free here](https://vueschool.io/lessons/formkit-and-zod).

Now kneel before Zod!

![Zod from the Superman II movie](http://www.reactiongifs.com/wp-content/uploads/2013/07/zod.gif)