Formify Docs

Custom Plugins

Write your own plugin — transform values, add rules, gate submissions

Custom Plugins

Any plugin is an object with a unique name and any subset of lifecycle hooks (see the plugin shape on the Plugins overview page). Here are the three most common jobs.

Transform values on change

Return a new value from onChange to transform it (like a field-level normalizer):

const uppercaseNames = {
  name: "uppercase-names",
  priority: -10, // run before the built-in normalize plugin
  onChange: ({ field, value }) =>
    field === "firstName" || field === "lastName"
      ? String(value ?? "").toUpperCase()
      : undefined,
};

Return undefined to leave the value untouched.

Add a validation rule

Use validateField for cross-cutting checks that apply to any field:

const notPwned = {
  name: "not-pwned",
  validateField: ({ field, value }) =>
    field === "password" && PWNED_LIST.includes(value)
      ? "This password appeared in a data breach"
      : undefined,
};

Gate submission with an API call

Use onSubmit to block submit (return false) and surface an error:

const verifyEmailOnSubmit = {
  name: "verify-email",
  onSubmit: async (values, helpers) => {
    const res = await fetch(`/api/verify-email?email=${values.email}`);
    const { ok } = await res.json();
    if (!ok) {
      helpers.setFieldError("email", "This email is not verified");
      return false; // blocks submission
    }
  },
};

Priority

priority orders plugins with the same hook — lower numbers run first (default 0). Use it to run your plugin before or after the built-ins (normalize, format).

Things to know

  • name must be unique; a plugin named normalize or format replaces the built-in.
  • ctx is { values, field, value, fieldConfig, form } — form exposes the imperative helpers (setFieldValue, setFieldError, validateField, …).

On this page