DEV Community

Cover image for Using Zod with FormKit
Andrew Boyd
Andrew Boyd

Posted on

Using Zod with FormKit

Starting with Beta 17 — FormKit ships with a new Zod plugin that you can use to validate your forms.

By leveraging Zod 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.

# npm, yarn, pnpm — whatever you prefer
npm install @fomkit/zod zod
Enter fullscreen mode Exit fullscreen mode

(Don't have FormKit set up in your project yet? Read the getting started docs here.)

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:

<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>
Enter fullscreen mode Exit fullscreen mode

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.

<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>
Enter fullscreen mode Exit fullscreen mode

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.

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.

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.

Now kneel before Zod!

Zod from the Superman II movie

Top comments (0)