Field Types
All supported field types and how to configure them
Form Wire maps Zod types to form controls automatically. Here's every supported type.
Text Input
z.string().min(1, "Required")Renders as <input type="text">. Override with the component option:
fields: {
bio: { label: "Bio", component: "textarea" },
}z.email("Enter a valid email")Renders as <input type="email">.
Number
z.coerce.number().min(18, "Must be 18+")Renders as <input type="number">. Uses z.coerce so string form values are coerced to numbers.
Date
z.coerce.date()Renders as <input type="date">.
Boolean / Checkbox
z.boolean()Renders as <input type="checkbox">.
For "must accept" patterns:
z.literal(true, "You must accept the terms")This renders a checkbox that must be checked to submit.
Select
z.enum(["pending", "active", "paused"])Renders as <select> with options. Optional selects include a blank placeholder option.
Configure the placeholder:
fields: {
status: { label: "Status", placeholder: "Choose a status" },
}File
z.file()Renders as <input type="file">.
String Arrays
z.string().array().min(1)Renders as a dynamic list of text inputs with add/remove/reorder controls.
Configure labels:
fields: {
tags: {
label: "Tags",
array: {
addLabel: "Add tag",
removeLabel: "Remove",
itemLabel: "Tag",
},
},
}Object Arrays
z.object({
name: z.string(),
email: z.email(),
}).array()Renders as fieldset groups with add/remove/reorder controls for each item.
Custom Component Override
Use component in field config to override the default rendering:
fields: {
bio: { component: "textarea" },
}Currently supported: "textarea". For full custom rendering, use a custom mapper.