DEV Community

Cover image for How a French word tricked Chrome into suggesting a credit card
Arthur Violy
Arthur Violy

Posted on

How a French word tricked Chrome into suggesting a credit card

TL;DR

We had a plain numeric text field labeled "Numéro de commande" (French for "Order number") in a form.
Despite setting autocomplete="off", inputmode="numeric", and a maxlength, Chrome (and Android's Autofill Manager, tied to Google Pay) kept suggesting the user's saved credit cards on that field.

The fix that actually worked: breaking the word that triggers the heuristic with an invisible Unicode character in the field's label, while leaving autocomplete="off" in place as a first line of defense.

Google Chrome numéro Autofill

The bug report

On Chrome, tapping the "Numéro de commande" field
opens Google Pay with the list of saved credit cards.

Here is a simplified version of the actual input, straight from the DOM:

<input
  type="text"
  placeholder="Numéro de commande"
  aria-label="Numéro de commande"
  name="field__order_number"
  autocomplete="off"
  inputmode="numeric"
  maxlength="9"
/>
Enter fullscreen mode Exit fullscreen mode

Nothing unusual here. It's a text input, autofill is explicitly disabled, and the only "special" thing is a numeric keyboard hint for mobile users. Yet Chrome and Android's Autofill Manager both treat it as a credit card number field.

Why autocomplete="off" doesn't help

This isn't a bug, it's documented, deliberated behavior, on Chromium's part:

  • The Chromium issue tracker confirms Chrome deliberately ignores autocomplete="off" for payment-related Autofill.
  • A 2014 WHATWG mailing list thread, with responses from Chromium engineers, explains the reasoning: autocomplete="off" was so commonly misused on real checkout forms that Chrome decided not to trust it for payment and address fields at all.

In short: Chrome's autofill heuristic for credit cards does not rely solely on the autocomplete attribute.
It also looks at other signals: field type, numeric input mode, length constraints, and, as we found out, the label/placeholder text itself.

This is also called out in Chrome provides no way to disable credit card autofill,
which documents the same frustration from a different angle and confirms there's no clean way to opt out.

Finding the real trigger: the label

Since autocomplete="off" alone wasn't enough,
we started testing which signal actually mattered.
The field's maxlength (8-9 digits) and inputmode="numeric"
looked like plausible suspects, matching typical card-number-ish constraints but the real breakthrough came from testing the label.

We temporarily changed the placeholder from:

Numéro de commande
Enter fullscreen mode Exit fullscreen mode

to:

Num éro de commande
Enter fullscreen mode Exit fullscreen mode

(a single, visible extra space in the middle of "numéro"). The Google Pay suggestion strip disappeared immediately.

That confirmed it: Chrome's (and Android's) credit-card-field classifier does some form of semantic matching against the label text, and "numéro" (French for "number") was scoring high enough, combined with the numeric input mode, to be classified as a card number field.

The fix: an invisible character

We used U+200B, the Zero Width Space (a character with no visual rendering that most screen readers silently skip):

// Breaks up words in a label so Chrome/Android's credit-card-field
// heuristic (label-based, not just autocomplete-based) no longer
// recognizes a false-positive keyword, language-agnostic, no
// hardcoded keyword list needed.
const obfuscateLabelForAutofill = (label) =>
  label
    .split(" ")
    .map((word) => {
      const mid = Math.ceil(word.length / 2);
      return word.length > 3
        ? `${word.slice(0, mid)}${word.slice(mid)}`
        : word;
    })
    .join(" ");

obfuscateLabelForAutofill("Numéro de commande");
// => "Num​éro de comm​ande" (renders as "Numéro de commande")
Enter fullscreen mode Exit fullscreen mode

Applied to our field:

<input
  type="text"
  placeholder="Num&#8203;éro de commande"
  aria-label="Num&#8203;éro de commande"
  name="field__order_number"
  autocomplete="off"
  inputmode="numeric"
  maxlength="9"
/>
Enter fullscreen mode Exit fullscreen mode

Visually, nothing changes: the placeholder still reads "Numéro de commande".
But Chrome's keyword matching no longer finds "numéro" as a contiguous string, and the autofill suggestion disappears.

A note on accessibility

Because the label feeds both the placeholder and aria-label in our case,
inserting a zero-width character mid-word raises an obvious question:
does this confuse screen readers?

We haven't done a proper investigation here: no testing across screen readers/browsers, no accessibility audit. Our assumption is that U+200B
is commonly treated as a non-rendering character with no phonetic value, so it should be silently skipped rather than mispronounced or read out as a pause. But that's an assumption, not a verified result, and screen reader behavior around zero-width characters is known to vary depending on the engine, the browser, and even the surrounding characters.

If you're considering reusing this trick, treat this as an open question rather than a solved one.

References

Top comments (0)