Try this it, it seems simple and it works for me:
const MAX_FILE_SIZE = 500000;
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
const someSchema = z.object({
image: z
.any()
.refine((file) => file?.size <= MAX_FILE_SIZE, `Max image size is 5MB.`)
.refine(
(file) => ACCEPTED_IMAGE_TYPES.includes(file?.type),
"Only .jpg, .jpeg, .png and .webp formats are supported."
)
})
And then the error should be displayed with:
formState.errors?.image?.message
One thing to note though is what kind of object are you getting from your input. Check if its a File object or a File[] array. I am using it with react-dropzone so I configured it to save a single File object. If it were an array you would have to change the schema to this:
const MAX_FILE_SIZE = 500000;
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
const someSchema = z.object({
image: z
.any()
.refine((files) => files?.[0]?.size <= MAX_FILE_SIZE, `Max image size is 5MB.`)
.refine(
(files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type),
"Only .jpg, .jpeg, .png and .webp formats are supported."
)
})