Sobes.tech
Middle

How to organize a schema for a multi-step form in Zod? How to handle conditional validation?

sobes.tech AI

Answer from AI

In Zod, for a multi-step form, it is common to create separate schemas for each step and then combine them as needed. For conditional validation, you can use the .refine() or .superRefine() methods, as well as conditional logic within the schema.

Example of organizing a schema for a two-step form with conditional validation:

import { z } from 'zod';

const step1Schema = z.object({
  name: z.string().min(1, "Name is required"),
  age: z.number().int().positive(),
});

const step2Schema = z.object({
  hasPet: z.boolean(),
  petName: z.string().optional(),
}).superRefine((data, ctx) => {
  if (data.hasPet && (!data.petName || data.petName.trim() === '')) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: "Pet name is required if you have a pet",
      path: ["petName"],
    });
  }
});

// Combined schema for the entire form
const fullSchema = step1Schema.merge(step2Schema);

This approach allows validating each step separately and applying conditional checks, for example, if the hasPet field is true, then petName is required. The superRefine method provides access to the entire data structure and allows adding custom errors.

For dynamic validation, you can also use .refine() with a function that checks the values of other fields.

How to organize a schema for a multi-step form in… - sobes.tech