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
(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 validformData
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 yoursubmitCallback
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>
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>
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!
Top comments (0)