Schema related / parseWithZod

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);

#Parameters

payload

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

options

schema

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

async

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

errorMap

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

formatError

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

#Example

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

#Tips

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 z.date(), 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 https://github.com/colinhacks/zod/issues/2671 and https://github.com/colinhacks/zod/issues/2677. 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    }
7
8    // Clear the formatting and cast the value to number
9    return Number(value.trim().replace(/,/g, ''));
10  }, z.number()),
11});

Default values

Conform will always strip empty values to undefined. If you need a default value, please use .transform() to define a fallback value that will be returned instead.

1const schema = z.object({
2  foo: z.string().optional(), // string | undefined
3  bar: z
4    .string()
5    .optional()
6    .transform((value) => value ?? ''), // string
7  baz: z
8    .string()
9    .optional()
10    .transform((value) => value ?? null), // string | null
11});