Skip to content
Playground

Zod

You may want to use Zod validator because:

  • You can use Zod schema as a source of truth for the form value type (z.infer).
  • This is an easy way to add custom error messages

Installation

Terminal window
npm i @sjsf/zod-validator zod zod-to-json-schema json-schema-to-zod

References:

Example

<script lang="ts">
import { SimpleForm, ON_INPUT, type Schema } from "@sjsf/form";
import { createValidator } from "@sjsf/zod-validator";
import { zodToJsonSchema } from "zod-to-json-schema";
import { z } from "zod";
import { useCustomForm } from "@/components/custom-form";
import { initialValue, uiSchema } from './_shared';
const schema = z.object({
id: z
.string()
.regex(new RegExp("\\d+"), "Must be a number")
.min(8)
.optional(),
active: z.boolean().optional(),
skills: z.array(z.string().min(5)).min(4).optional(),
multipleChoicesList: z
.array(z.enum(["foo", "bar", "fuzz"]))
.max(2)
.optional(),
});
type Value = z.infer<typeof schema>;
const validator = createValidator({ schema });
const form = useCustomForm({
schema: zodToJsonSchema(schema, { errorMessages: true }) as Schema,
uiSchema,
validator,
fieldsValidationMode: ON_INPUT,
initialValue: initialValue as Value,
});
</script>
<SimpleForm
{form}
novalidate
style="display: flex; flex-direction: column; gap: 1rem;"
/>
<pre>{JSON.stringify(form.value, null, 2)}</pre>

Caveats

  • If you using this library only for full form validation (without fields validation mode) and your form does not have and oneOf, anyOf, dependencies if keywords or recursive references, you can use this library pretty safely.

  • If you are using fields validation mode then starting from this point internally we start to use json-schema-to-zod. So first of all, please read this warning about using this library at runtime. However, I believe you are still safe as only small leafy bits of the circuit are transformed with this approach.

  • If you use any conditional keyword or recursive references it means with a high probability something can go wrong. If you have problems with this approach, try using zod with a different validator using the augment submodule. So in this case zod validator will be used only for full form validation.

import { createValidator } from "@sjsf/other-validator";
import { withZod } from "@sjsf/zod-integration/augment";
const validator = withZod(createValidator(), { schema });

Async validation

This validator supports async validation but only for the full form validation.

import { createValidator } from "@sjsf/zod-validator";
const validator = createValidator({
async: true,
schema,
});