External Publication
Visit Post

✍🏻 Easy Data-entry Verification with a Web Component

Hi! :: Aaron Gustafson [Unofficial] May 25, 2026
Source

Sometimes the simplest form pattern ends up being the one you repeat ad infinitum : “Type it once, then type it again.” We do it for password confirmations, email verification, and any flow where a typo can create expensive follow-up work. This week I released a small web component to handle that pattern cleanly: form-matching-fields.

The component wraps two related form fields and adds validation to ensure they match. It’s intentionally additive, which means it works with native browser validation rather than trying to replace it.

# Wrap and go

The API is intentionally simple:

<form-matching-fields><labelfor=“password”>Password</label><inputid=“password”type=“password”required/><labelfor=“password-again”>Password again</label><inputid=“password-again”type=“password”required/></form-matching-fields>

The component evaluates the first two eligible text-type inputs it contains and applies mismatch validation to the second one when both fields have values.

# What counts as an eligible field?

To keep behavior predictable, the component only considers descendant input elements of these types:

  • text
  • email
  • password
  • search
  • tel
  • url

It ignores disabled and readonly controls, which helps prevent false positives when you have conditional or locked fields in the same wrapper.

# Validation behavior that plays nicely

One of the core goals here was to avoid stepping on existing validation rules. In practice, that means:

  • If the second field already has a native validation issue (like required or type mismatch), this component won’t obscure that.
  • If the second field already has a custom validity message, this component won’t overwrite that either.
  • It only clears mismatch errors that it set itself.

That last point is especially useful in larger forms where multiple constraints can overlap. You don’t want one helper trying to be the sole source of truth.

# Customizing the validation message

By default, the component uses this template for the validation message:

The fields “{label_1}” and “{label_2}” should match

It smartly resolves the labels ({label_1} and {label_2}) from your markup in this order:

  1. associated <label for> text
  2. wrapping <label> text
  3. aria-label
  4. name
  5. id

You can override it with the validation-message attribute:

<form-matching-fieldsvalidation-message=“Please ensure {label_2} matches {label_1}.”><labelfor=“email”>Email</label><inputid=“email”type=“email”required/><labelfor=“verify-email”>Verify email</label><inputid=“verify-email”type=“email”required/></form-matching-fields>

In most forms, that gives you a clear error message without requiring extra setup.

# Demo

I put together a demo of the web component over on GitHub:

# Grab it

You can explore the source, file issues, and suggest enhancements in the form-matching-fields repository.

Discussion in the ATmosphere

Loading comments...