Formify Docs

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):

  1. Per-field message override — { message: { ruleName: "..." } }
  2. Explicit message — email: "Custom", minLength: [8, "Custom"], V.email("Custom")
  3. Global dictionary — useForm({ messages: { required: "..." } })
  4. 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:

RulePlaceholders
minLength{min}
maxLength{max}
between{min}, {max}

Notes

  • message keys 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.

On this page