Schema related / parseWithZod


A helper that returns an overview of the submission by parsing the form data with the provided zod schema.

1const submission = parseWithZod(payload, options);



It could be either the FormData or URLSearchParams object depending on how the form is submitted.



Either a zod schema or a function that returns a zod schema.


Set it to true if you want to parse the form data with safeParseAsync method from the zod schema instead of safeParse.


A zod error map to be used when parsing the form data.


A function that let you customize the error structure and include additional metadata as needed.


1import { parseWithZod } from '@conform-to/zod';
2import { useForm } from '@conform-to/react';
3import { z } from 'zod';
5const schema = z.object({
6  email: z.string().email(),
7  password: z.string(),
10function Example() {
11  const [form, fields] = useForm({
12    onValidate({ formData }) {
13      return parseWithZod(formData, { schema });
14    },
15  });
17  // ...


Automatic type coercion

Conform will strip empty value and coerce the form data to the expected type by introspecting the schema and inject an extra preprocessing step. The following rules will be applied:

  1. If the value is an empty string / file, pass undefined to the schema
  2. If the schema is z.string(), pass the value as is
  3. If the schema is z.number(), trim the value and cast it with the Number constructor
  4. If the schema is z.boolean(), treat the value as true if it equals to on
  5. If the schema is, cast the value with the Date constructor
  6. If the schema is z.bigint(), cast the value with the BigInt constructor

You can override this behavior by setting up your own z.preprocess step in the schema.

Note: There are several bug reports on Zod's repository regarding the behaviour of z.preprocess since v3.22, like and If you are experiencing any issues, please downgrade to v3.21.4.

1const schema = z.object({
2  amount: z.preprocess((value) => {
3    // If no value is provided, return `undefined`
4    if (!value) {
5      return undefined;
6    }
8    // Clear the formatting and cast the value to number
9    return Number(value.trim().replace(/,/g, ''));
10  }, z.number()),

Default values

Conform already preprocesses empty values to undefined. Add .default() to your schema to define a default value that will be returned instead.

Zod will return the default value if the input is undefined after preprocessing. This also has the effect of changing the schema return type.

1const schema = z.object({
2  foo: z.string(), // string | undefined
3  bar: z.string().default('bar'), // string
4  baz: z.string().nullable().default(null), // string | null