Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Technology handbook

Conform - Validation libraries

Progressively enhanced forms with schema validation, accessible errors and server integration.

Topics
24
Sections
4

Form fundamentals

useForm

Create a form whose state derives from the last submission result.

  • Form state is derived from the last submission result rather than kept separately.
  • Because the result is the source, a server round trip and a client check produce the same render.
  • It returns the form and field metadata together, so nothing is wired by hand.

Field metadata

Read a field's name, id, errors and validation attributes from one object.

  • One object carries a field's name, id, errors and validation attributes.
  • Spreading it onto an input is what links the label, the control and the message.
  • Reading the id from it is what keeps aria-describedby pointing at the real element.

Progressive enhancement

Keep the form working as a plain HTML submission.

  • The form posts and works before any script has loaded.
  • Scripting improves the same form rather than replacing how it submits.
  • A control that only works through a click handler is the part that breaks without it.

FormData parsing

Turn a submission into a typed object with nested and repeated fields.

  • A flat FormData is turned into a typed object with nesting and repetition restored.
  • Bracketed names are what encode structure the browser itself cannot express.
  • Every value arrives as a string, so parsing is where types re-enter.

Validation timing

Validate on blur, on input or on submit per field.

  • Per-field timing decides whether a message appears on blur, on input or on submit.
  • Validating on input as a field is first typed reports an error before it can be right.
  • Timing is per field, so a slow async check need not run on every keystroke.

Accessible errors

Associate messages with inputs so assistive technology announces them.

  • A message is associated with its input so assistive technology announces it.
  • Colour alone marks an error for sighted users and for nobody else.
  • Moving focus to the first invalid field is what makes a long form recoverable.

Schema integration

Zod integration

Parse and validate a submission with a Zod schema on both sides.

  • One Zod schema validates the submission on the server and the client.
  • Issue paths map onto field names, which is what puts a message on the right input.
  • Sharing the schema keeps the two sides from drifting apart silently.

Valibot and Yup

Use an alternative schema library through the matching adapter.

  • An adapter lets an alternative schema library produce the same result shape.
  • Only the adapter changes; the form code above it does not.
  • Libraries differ on coercion and optionality, which shows up as different errors.

Shared schemas

Define the shape once and reuse it for the form and the API.

  • The shape is defined once and reused by the form and the API.
  • A single definition is what stops the endpoint accepting what the form rejects.
  • Only the schema is shared; messages can still be written per surface.

Coercion

Convert string form values into numbers, dates and booleans safely.

  • Form values arrive as strings, so numbers, dates and booleans need converting.
  • An unchecked checkbox sends nothing at all rather than a false value.
  • Coercing before validating is what stops a valid number failing as a string.

Conditional schemas

Require a field only when another value makes it relevant.

  • A field becomes required only when another value makes it relevant.
  • The condition belongs in the schema so the server enforces it too.
  • A hidden field that is still required is a form nobody can submit.

Async validation

Check uniqueness against a server without blocking every keystroke.

  • A uniqueness check reaches the server without running on every keystroke.
  • Debouncing is what keeps one check per pause rather than one per character.
  • The async result must be re-checked on submit, because it can go stale.

Complex forms

Nested objects

Model grouped fields and read their errors at the right level.

  • Grouped fields are addressed by path, and their errors read at that level.
  • An error on the group is not the same as an error on a field inside it.
  • The path in the name is what lets the server return errors to the right place.

Field lists

Add, remove and reorder repeating rows with the form's intent API.

  • Rows are added, removed and reordered through the intent API rather than local state.
  • Intent keeps the list working when scripting is unavailable.
  • Keying rows by index makes a removal renumber every row after it.

Intent buttons

Drive an action other than submit from within the same form.

  • A button can drive an action other than submit from inside the same form.
  • The intent travels in the submission, so the server knows which action was meant.
  • One form can hold several intents without a second form element.

File inputs

Validate uploads by type and size before accepting them.

  • Type and size are checked before an upload is accepted.
  • The client check is a courtesy; the server still receives whatever is sent.
  • A file input needs the right encoding type or the file never arrives.

Multi-step forms

Carry state across steps and validate each one independently.

  • Each step validates on its own while state carries across the whole flow.
  • Validating only at the end makes a user correct errors they made three screens ago.
  • The final submit must re-validate everything, not trust the earlier steps.

Default values

Populate a form from existing data and detect what changed.

  • A form is populated from existing data and reports what actually changed.
  • Sending only changed fields is what avoids overwriting a concurrent edit.
  • A default that is not in the schema is a value that never round-trips.

Server integration

Server actions

Handle a submission server-side and return a result the form can render.

  • The submission is handled server-side and returns a result the form renders.
  • Returning the result rather than throwing is what keeps the errors renderable.
  • The action runs on the server, so it may reach the database directly.

Returning errors

Map server-side failures back onto the fields that caused them.

  • A server-side failure is mapped back onto the field that caused it.
  • A unique-constraint violation belongs on the field, not in a banner.
  • An error with no field to attach to needs a form-level place to land.

Redirect after success

Avoid a resubmission on refresh after a successful write.

  • Redirecting after a successful write stops a refresh resubmitting it.
  • Post-then-redirect is what keeps the back button from replaying the write.
  • Redirecting before the write commits reports success that may not have happened.

Framework adapters

Integrate with Next.js, Remix or React Router.

  • An adapter connects the form to Next.js, Remix or React Router.
  • Only submission and redirect handling differ; the schema does not.
  • The adapter decides where the result comes from on a server render.

Security

Treat every submitted field as untrusted regardless of the client schema.

  • Every submitted field is untrusted no matter what the client schema said.
  • A direct post never runs the client validation at all.
  • Accepting fields the schema does not name is how extra values reach the database.

Testing

Test a submission with scripting disabled as well as enabled.

  • The form is tested with scripting disabled as well as enabled.
  • Only the scriptless path proves the progressive enhancement actually works.
  • Asserting on the rendered message catches a break the schema test cannot.

Sources

  • Conform - Validation libraries official documentation

Ask follow-up questions on any topic in your dashboard.

Start learning