Why autofill measurement matters

Forms are the conversion point of most ecommerce journeys, and browser autofill is a major factor in how quickly users can complete them. When autofill works smoothly, form submissions speed up and abandonment drops. But without visibility into how autofill behaves on your forms, you can't tell whether it's helping or hurting.

Tracking autofill usage gives you three practical benefits:

  • Align testing with real user behavior. If analytics show heavy autofill reliance, autofill testing becomes a priority in your QA workflow.
  • Catch regressions. Sudden shifts in autofill signals on a field after a deployment can point to a broken autofill behavior.
  • Verify autofill-friendly markup. If fields you expect users to autofill are being filled manually, something in your implementation may need attention.

A complete implementation

Try the demo and inspect the source on GitHub{{BLOCK_0}} to see the full approach in context. The demo supports these cases, all of which your tracking should handle:

  • Autofilling all fields.
  • Autofilling a field then clearing it manually.
  • Autofilling then manually modifying the value.
  • Filling a field entirely by hand.
  • Leaving a field blank.

The technique relies on the CSS :autofill pseudo-class, which is supported in recent versions of all major browsers.

Step 1: Track each field's autofill state

Define the possible states

Each field can end up in one of four states:

  • EMPTY: The user leaves the field empty.
  • AUTOFILLED: The field is filled exclusively by autofill.
  • AUTOFILLED_THEN_MODIFIED: The browser fills the field, then the user edits it. For example, autofilling an address but replacing the phone number.
  • ONLY_MANUAL: The field is populated entirely by hand.

Define these states as constants or a shared type:

{{BLOCK_3}}

Detect autofilled fields

Two utility functions form the core of the detection logic:

  • getAllAutofilledFields scans all <input> and <select> elements within the form and returns the ones that currently match the :autofill pseudo-class.
  • checkIsAutofilled tests whether a specific element appears in that autofilled list.

{{BLOCK_4}}

You also need a helper to determine whether a field is empty:

{{BLOCK_5}}

Initialize statuses and listen for changes

Set up a global object, autofillStatuses, to hold the state of each field. Grab all field IDs from the form and initialize every entry to EMPTY:

{{BLOCK_6}}

The initialization routine collects the field elements through a helper function:

{{BLOCK_7}}

With state initialized, attach a change event listener to each form element. Whenever a change fires, check whether the element is autofilled and update its status in the object based on its previous value and the current DOM state.

For example, a field whose previous status was AUTOFILLED that no longer has the :autofill pseudo-class must have been edited manually after autofill, so its status becomes AUTOFILLED_THEN_MODIFIED:

{{BLOCK_8}}

Report the results

When the form submits, send the autofillStatuses object to your analytics endpoint. For an address form, the server could receive data like this:

{{BLOCK_9}}

Step 2: Interpret the data

Aggregate the status objects you collect from users and look for patterns.

Start with the big picture: what percentage of users rely on browser autofill for at least one field? Then zoom in on individual fields. If a field that should be autofill-compatible shows a high share of manual fill-ins, investigate:

  • Are the field <label>s ambiguous, or are placeholders misleading?
  • Is the autocomplete attribute using the correct token? A common error is <input autocomplete="first-name">, which browsers ignore: the proper value is "given-name".

Armed with these signals, you can spot regressions early and keep your forms aligned with how users genuinely complete them. More autofill resources and guidance are available for deeper implementation details.