Multi-Step Form Wizard with Zod Schema Validation
Enterprise registration flows, project setups, or complex checkout journeys are typically divided into multiple steps to avoid overwhelming users. A critical engineering requirement is ensuring that each step strictly validates its input before allowing progression, preventing partial or invalid states from reaching the server.
This recipe teaches how to integrate PxFormWizard with Zod for robust, typed validation per step.
Interactive Demonstration
Try advancing without filling in the required fields: PxFormWizard intercepts navigation, displays a focused error message, and retains step state. Upon completing the final step, the validated payload is emitted.
Patterns & Best Practices
1. safeParse instead of parse
When validating user forms reactively, avoid letting Zod throw uncaught exceptions. Use safeParse():
const result = accountSchema.safeParse(data)
if (!result.success) {
// Return the first human-readable error message to display
return result.error.issues[0]?.message
}
return true2. Persisting Progress to localStorage
To prevent user frustration from accidental page reloads or network drops, synchronize wizard state with useStorage from @vueuse/core:
import { useStorage } from '@vueuse/core'
const formState = useStorage('praxis_onboarding_draft', {
fullName: '',
email: '',
orgName: '',
role: '',
plan: 'pro'
})
// Clear draft on successful completion:
function onWizardComplete() {
localStorage.removeItem('praxis_onboarding_draft')
}3. Asynchronous Validation (Username / Subdomain Uniqueness)
If you need to check whether an organization name or subdomain is available on the server before proceeding to step 2, step validate functions can be async:
validate: async (data) => {
const isAvailable = await checkOrgAvailability(data.orgName)
if (!isAvailable) {
return 'This organization name is already taken'
}
return true
}