Custom Messages
How Formify resolves error messages — overrides, dictionaries, and placeholders
Custom Messages
Every validator ships with a built-in default message. Formify resolves which message to show through a fixed priority order, so you can override messages per field, per rule, or globally.
Resolution order
When a rule fails, Formify picks the message by walking this list (highest priority first):
- Per-field
messageoverride —{ message: { ruleName: "..." } } - Explicit message —
email: "Custom",minLength: [8, "Custom"],V.email("Custom") - Global dictionary —
useForm({ messages: { required: "..." } }) - Built-in default dictionary
1. Per-field message override
validationSchema: {
name: {
required: true,
minLength: 3,
message: {
required: "Please enter your name",
minLength: "Your name is too short",
},
},
}2. Explicit message on the rule
Any validator accepts a string instead of true to override its message:
validationSchema: {
email: { email: "Enter a valid email" },
}Parameterized rules use a [value, message] tuple:
validationSchema: {
password: { minLength: [8, "At least {min} characters"] },
age: { between: [[18, 120], "You must be 18–120 years old"] },
}V builder rules take the message as the last argument:
V.email("Enter a valid email")
V.minLength(8, "At least {min} characters")3. Global dictionary
Pass a message dictionary to useForm — any rule not overridden per field falls back to it:
const form = useForm({
initialValues: { email: "" },
messages: {
required: "This field is required",
minLength: "Must be at least {min} characters",
},
validationSchema: {
email: { required: true, email: true, minLength: 5 },
},
});This makes i18n trivial — keep one dictionary per locale and swap it per form:
const messages = {
required: "Ce champ est obligatoire",
email: "Veuillez saisir un email valide",
minLength: "Au moins {min} caractères",
};
useForm({ initialValues, messages, validationSchema, onSubmit });The resolved dictionary (defaults + overrides) is also exposed on the form bag as form.messages.
4. Built-in defaults
Every validator has a default message. Parameterized rules interpolate their arguments into the message:
| Rule | Placeholders |
|---|---|
minLength | {min} |
maxLength | {max} |
between | {min}, {max} |
Notes
messagekeys match the validator flag names:required,email,minLength,pattern, and so on.- Placeholders (
{min},{max}) are replaced at validation time with the rule's arguments.