Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mikefolsom's avatar

Preventing contact autocomplete in Safari

I am working on a pretty simple Vue typeahead to search for and select a customer record. It's working fine, except Safari (Mac, at least) attempts to autofill from my address book. Screenshot here.

I have tried everything I can think of to prevent it: declaring autocomplete="off", changing the input's name attribute, changing text inside the label, etc. Nothing short of adjusting Safari's preferences has had any effect. Ideas? Here's the component.

<template>
    <div class="relative">
        <input type="text" name="q" class="form-control" placeholder="Start typing name or customer ID" autocomplete="off" v-model="query" @keyup="autoComplete">
        <div class="text-block padding-half text-success" v-if="this.customerId">
            <i class="fa fa-check-circle"></i>&nbsp;&nbsp;{{ this.customerName }} ({{ this.customerId }})</div>
        <div class="results-menu" v-if="results.length">
            <ul class="nav nav-pills nav-stacked">
                <li v-for="result in results">
                    <a href="javascript:;" @click.prevent="selectItem(result)">{{ result.name }} ({{ result.id }})</a>
                </li>
            </ul>
        </div>
        <input type="hidden" name="customer_id" :value="customerId">
    </div>
</template>

<script>
export default {
  name: "CustomerSearch",

  data() {
    return {
      query: "",
      results: [],
      customerId: "",
      customerName: ""
    };
  },

  methods: {
    autoComplete() {
      this.results = [];

      if (this.query.length > 2) {
        axios
          .get("/admin/api/customers/search", {
            params: { q: this.query }
          })
          .then(response => {
            this.results = response.data;
          });
      }
    },

    selectItem(result) {
      console.log(result);
      this.query = result.name;
      this.customerName = result.name;
      this.customerId = result.id;
      this.results = [];
    }
  }
};
</script>

<style lang="css" scoped>
.results-menu {
  position: absolute;
  top: 31px;
  left: 0;
  right: 0;
  z-index: 1000;
  background: #fafafa;
  border: 1px solid gray;
  border-top: none;
}
input[autocomplete="off"]::-webkit-contacts-auto-fill-button,
input[autocomplete="off"]::-webkit-credentials-auto-fill-button,
input[autocomplete="off"]:focus::-webkit-textfield-decoration-container {
  visibility: hidden;
  display: none !important;
  pointer-events: none;
  height: 0;
  width: 0;
  margin: 0;
}
</style>
0 likes
3 replies
click's avatar

Maybe this could do the trick? Strange solution but maybe it can help

https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion

In some cases, the browser will keep suggesting autocompletion values even if the autocomplete attribute is set to off. This unexpected behavior can be quite puzzling for developers. The trick to really forcing the no-autocompletion is to assign a random string to the attribute, for example:"

autocomplete="nope"

Since this random value is not a valid one, the browser will give up.

And another not so nice but probably working solution could be to just randomize the field name. That should let the browser think it is a different field and so won't suggest previous values.

mikefolsom's avatar

@m-rk Thanks for the suggestions and the link. Still no dice. :(

I have tried randomizing the name, adding autocomplete="off" and autocomplete="nope" to both the form tag and the input tag. So weird...

murph133's avatar

Hi Mike,

Yes, changing the autocomplete doesn't work.

Solution: remove the word "name" from the name and placeholder attributes.

Example:

Before:
<input type="input" name="location_name" placeholder="Location Name">

After:
<input type="input" name="location" placeholder"Location">

That worked for me.

1 like

Please or to participate in this conversation.