Zod Schema Validation
If you prefer to use zod for schema validation instead of yup, you can do so with the @vee-validate/zod
package.
With @vee-validate/zod
you can use Zod
typed schemas as drop-in replacements for yup
schemas.
Install
To use this plugin, make sure to install these packages vee-validate
, zod
, and @vee-validate/zod
.
shyarn add vee-validate zod @vee-validate/zod
# or with NPM
npm install vee-validate zod @vee-validate/zod
# or with Pnpm
pnpm add vee-validate zod @vee-validate/zod
Validating with Zod
You can create validation schemas for either field-level validation or form-level validation, the @vee-validate/zod
exposes a toTypedSchema
function that transform Zod’s schemas into something that can be understood by vee-validate
main core and use them to perform validation. It also allows vee-validate to figure out the types for both the input values and the submitted values.
Field-level Validation
The toTypedSchema
function accepts a Zod schema. You can use the converted schema by passing it to the rules
prop present on the <Field />
component:
vue<template>
<Form>
<Field name="email" type="email" :rules="fieldSchema" />
<ErrorMessage name="email" />
</Form>
</template>
<script setup>
import { Field, Form, ErrorMessage } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import * as zod from 'zod';
const fieldSchema = toTypedSchema(zod.string().nonempty('Field is required').email('Must be a valid email'));
</script>
If you prefer to use the Composition API, then you can pass the converted schema to the useField
function:
vue<template>
<input name="email" v-model="value" type="email" />
<span>{{ errorMessage }}</span>
</template>
<script setup>
import { useField } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import * as zod from 'zod';
const fieldSchema = toTypedSchema(
zod.string().min(1, { message: 'Field is required' }).email({ message: 'Must be a valid email' })
);
const { value, errorMessage } = useField('email', fieldSchema);
</script>
Form-Level Validation
You can also use Zod’s zod.object
to create validation schemas for your forms instead of individually passing it for each field, this is covered in general in the form-level validation section.
To be able to use zod.object
to define form schemas, you will be using the same toTypedSchema
function.
You can pass the converted schema to the validation-schema
prop present on the <Form />
component:
vue<template>
<Form :validation-schema="validationSchema" @submit="onSubmit">
<Field name="email" type="email" />
<ErrorMessage name="email" />
<Field name="password" type="password" />
<ErrorMessage name="password" />
<button>Submit</button>
</Form>
</template>
<script setup>
import { Form, Field, ErrorMessage } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import * as zod from 'zod';
const validationSchema = toTypedSchema(
zod.object({
email: zod.string().min(1, { message: 'This is required' }).email({ message: 'Must be a valid email' }),
password: zod.string().min(1, { message: 'This is required' }).min(8, { message: 'Too short' }),
})
);
function onSubmit(values) {
alert(JSON.stringify(values, null, 2));
}
</script>
Alternatively, if you prefer to use the composition API, you can pass the converted schema as the validationSchema
option accepted by the useForm
function:
vue<template>
<form @submit="onSubmit">
<input name="email" v-model="email" type="email" />
<span>{{ errors.email }}</span>
<input name="password" v-model="password" type="password" />
<span>{{ errors.password }}</span>
<button>Submit</button>
</form>
</template>
<script setup>
import { useField, useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import * as zod from 'zod';
const validationSchema = toTypedSchema(
zod.object({
email: zod.string().min(1, { message: 'This is required' }).email({ message: 'Must be a valid email' }),
password: zod.string().min(1, { message: 'This is required' }).min(8, { message: 'Too short' }),
})
);
const { handleSubmit, errors } = useForm({
validationSchema,
});
const { value: email } = useField('email');
const { value: password } = useField('password');
const onSubmit = handleSubmit(values => {
alert(JSON.stringify(values, null, 2));
});
</script>
TypeScript Form Values Inference
You can find more information on how typed schemas work in vee-validate here
refine/superRefine
There is a known issue with Zod’s refine
and superRefine
not executing whenever some object keys are missing which is common with forms. This is not an issue with vee-validate as it is a design choice in Zod at the moment. Refer to this issue for explanations and further reading.