Formify Docs
Plugins

Plugins

Extend the form lifecycle with the Formify plugin system — one page per plugin

Plugins

Plugins hook into the form lifecycle. They can:

  • Transform values on change (onChange) — input normalization, masking
  • Add validation rules (validateField) — cross-cutting checks
  • Gate submissions (onSubmit) — re-verify unique fields via API, run analytics, block submit when something is missing
  • React to lifecycle events — onMount, onReset, onError

Plugin shape

interface FormPlugin<Values> {
  name: string;            // unique; replaces a built-in with the same name
  priority?: number;       // lower runs first (default 0)
  onMount?: (ctx) => void;
  onChange?: (ctx) => unknown;         // return a new value to transform
  onBlur?: (ctx) => void;
  validateField?: (ctx) => MaybeError | Promise<MaybeError> | void;
  onSubmit?: (values, helpers) => boolean | void | Promise<boolean | void>;
  onReset?: (values) => void;
  onError?: (errors) => void;
}

ctx is { values, field, value, fieldConfig, form } where form is the imperative helpers (setFieldValue, setFieldError, validateField, …).

Usage

const form = useForm({
  initialValues: { email: "" },
  plugins: [myPlugin],
  onSubmit: ...,
});

Plugin pages

Built-in plugins (included automatically, can be overridden)

  • normalize — the normalize field config (trim, uppercase, custom functions, …)
  • format — the format field config (SSN, phone, currency masks, …)

Ready-made plugins

Writing your own

  • custom — transform, validate, and gate submissions with your own plugin

Example: logging plugin

const loggerPlugin = {
  name: "logger",
  onChange: ({ field, value }) => {
    console.log(`[form] ${field} changed to`, value);
  },
  onError: (errors) => {
    console.warn("[form] invalid", errors);
  },
};

Built-in plugins (normalizePlugin, formatPlugin) are included automatically and can be overridden by passing a plugin with the same name.

On this page