Autofill Check

Highlights fields that the browser or password manager autofilled and flags values that look wrong, like an email in the Name field.

StopsAutofill put email in name field

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/autofill-check.json

The files land in your project. They're yours to edit.

Usage

autofill-check-usage.tsx
import { AutofillCheck } from "@/components/ui/autofill-check"

<AutofillCheck reference={{ address: "B-204, Sai Residency, Baner Road" }}>
  {field("name", "Full name", { autoComplete: "name" })}
  {field("email", "Email", { type: "email", autoComplete: "email" })}
  {field("tel", "Phone", { type: "tel", autoComplete: "tel" })}
  {field("address", "Delivery address", { autoComplete: "street-address" })}
  <div className="flex items-center justify-between gap-2">
    <button type="button" onClick={simulate} className="h-8 rounded-md px-3 text-sm text-muted-foreground hover:bg-accent outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50">
      Autofill again
    </button>
    <button type="submit" className="h-9 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:bg-primary/90 outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50">
      {sent ? "Sent" : "Place order"}
    </button>
  </div>
</AutofillCheck>

What it catches

  • Fields filled without typing, detected by the :autofill hook or a timing heuristic
  • Values that do not fit the field (an email in Name, a number in Email)
  • Values that differ from what the account already holds (an old address), with a one-tap replacement
  • The same value filled into two different fields

Props

AutofillCheck props
PropTypeDefault
reference

What the account already holds, by field name. An autofilled value that differs (an old address) is flagged.

Record<string, string>{}
holdSubmit

Stop the first submit while a filled value looks wrong, and move focus to it. The second submit goes through.

booleantrue
batchWindow

Fields set without typing within this many ms of each other count as one fill (password managers, Firefox).

number120
onAutofill

Called with the field names each time a fill is detected.

(fields: string[]) => void—
message

Text. `{count}` is filled in; `{value}` and `{other}` in the reasons.

string"{count} fields were filled by your browser. Check them."
suspectText

Banner text when a filled value looks wrong.

string"{count} look wrong"
heldText

Banner text when the first submit was held.

string"Check the outlined fields first, then send again."
reviewedLabel

Text for the button that marks all filled fields as reviewed.

string"Looks right"
clearLabel

Text for the button that clears a suspect value.

string"Clear"
useLabel

Text for the button that uses the account's value instead.

string"Use {value}"
reasons

Override the explanation shown for each kind of issue.

Partial<Record<FilledIssue["reason"], string>>—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Review banner is aria-live="polite" and becomes role="alert" when a submit is held
  • A held submit moves focus to the first suspect field; list entries focus their field
  • The highlight animation respects prefers-reduced-motion
  • Field names in the list come from their <label> or aria-label

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Detection is heuristic; some password managers and browsers fill in ways it cannot see, and fast pasting can look like autofill
  • Field types are guessed from autocomplete, type and name attributes
  • The first submit is held only once; the second goes through

What it stops

Autofill put email in name field

Also known as

autofill · autocomplete · password manager · chrome autofill · address form · checkout form · 1password

Dependencies

Pairs well with