gform-react
Back to Guides

Constraint Validation

Validate with the browser's native constraint validation API - required, minLength, pattern, type, and more - each paired with a custom GValidator message.

Validation in gform-react is built on the browser's native constraint validation API. You declare a native HTML constraint on the GInput and register a matching message on its GValidator: the constraint triggers the browser's validity check, the validator supplies the message. Custom and async rules build on top of this - see Custom Validation and Async Validation.

The validators object

validators maps each formKey to a GValidator. The special key '*' is the default validator applied to every field that doesn't have its own entry. This object is shared by all three kinds of validation.

import { GValidator, type GValidators } from "gform-react";
 
const base = new GValidator().withRequiredMessage("This field is required");
 
const validators: GValidators<SignInForm> = {
  "*": base, // default for all fields
  password: new GValidator(base).withMinLengthMessage("Password is too short"),
};
Compose validators

new GValidator(base) copies the rules from base, so per-field validators can extend the default rather than redefining it.

Native constraints

Add a native HTML constraint to the GInput and register a matching message on its GValidator. The constraint triggers the browser's validity check; the validator supplies the message.

<GInput
  formKey="email"
  type="email"
  pattern="[^\s@]+@[^\s@]+\.[^\s@]+"
  required
  minLength={5}
  element={/* … */}
/>
const validators: GValidators<Form> = {
  email: new GValidator()
    .withRequiredMessage("Email is required")
    .withPatternMismatchMessage("Enter a valid email")
    .withMinLengthMessage("Too short"),
};

Constraint → message method

GInput constraintValidity violationGValidator method
requiredvalueMissingwithRequiredMessage
minLengthtooShortwithMinLengthMessage
maxLengthtooLongwithMaxLengthMessage
patternpatternMismatchwithPatternMismatchMessage
minrangeUnderflowwithRangeUnderflowMessage
maxrangeOverflowwithRangeOverflowMessage
stepstepMismatchwithStepMismatchMessage
type (email/url…)typeMismatchwithTypeMismatchMessage
-badInputwithBadInputMessage
type is a UX hint - validate with pattern

type="email" (and type="tel", type="url", …) mainly exists to hint the right virtual keyboard on mobile; native enforcement of typeMismatch varies across browsers, so it isn't a reliable check on its own. Keep type for the keyboard and semantics, but carry the real rule with pattern + withPatternMismatchMessage (or a custom / schema rule).

When a field declares both type and pattern, an invalid value trips typeMismatch and patternMismatch at the same time. gform resolves this deterministically - it defers typeMismatch in favor of the stricter patternMismatch (on the live check and the initial-value check alike) - so your withPatternMismatchMessage is always the message shown, and the two constraints never conflict to block submission.

Static or dynamic messages

Every with…Message accepts either a string or a function that receives the input state - useful for interpolating the constraint value:

new GValidator().withMinLengthMessage(
  (input) => `${input.formKey} must be at least ${input.minLength} characters`
);

Try it live

Each field below pairs a native constraint with a GValidator message. Submit stays disabled while any constraint is violated (state.isInvalid).

Loading playground…

Next

  • Custom Validation - rules the native API can't express, like comparing two fields.
  • Async Validation - server-side checks like "is this username taken?".
  • GValidator - the full class reference: inheritance, the mutation gotcha, execution order, and dev-mode diagnostics.