Add address autocomplete to Vue

An address field that suggests as you type is the highest-value hundred lines in most checkout flows, and the part people get wrong is not the API call. It is the throttling, the minimum query length, and what happens when the person types faster than the network answers.

Install

npx @unmap/cli add geocoder

On Vue and Nuxt the registry lane is shadcn-vue, so the item arrives as a directory with an index.ts and builds on your own Combobox, Field and Input.

The component

<script setup lang="ts">
import { UnmapGeocoder } from "@/components/ui/geocoder";
 
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
</script>
 
<template>
  <UnmapGeocoder :api-key="apiKey" placeholder="Adresse" :limit="5" />
</template>

Note the key spelling again: the component takes api-key, the composable takes key. results and loading are refs, so the template unwraps them and script code needs .value.

Debouncing is your job on the package path

The snippet above fires on every keystroke, and every autocomplete request is one metered call. Typing a street address unthrottled is twenty calls to answer one question. The copied component debounces at 200ms; the composable does not, on purpose.

<script setup lang="ts">
import { ref, watch } from "vue";
import { useGeocoder } from "@unmap/vue";
 
const { autocomplete, results } = useGeocoder({
  key: import.meta.env.VITE_UNMAP_KEY as string,
});
 
const query = ref("");
let timer: ReturnType<typeof setTimeout> | undefined;
 
watch(query, (value) => {
  clearTimeout(timer);
  if (value.length < 3) return;
  timer = setTimeout(() => void autocomplete(value, { limit: 5 }), 200);
});
</script>
 
<template>
  <div>
    <input v-model="query" placeholder="Adresse" />
    <ul>
      <li v-for="result in results" :key="result.id">{{ result.name }}</li>
    </ul>
  </div>
</template>

What this is not

This suggests addresses from an open Canadian corpus. It does not validate that an address is deliverable, correct it to Canada Post's formatting, or confirm that a unit number exists. If you need certified address verification for mailing, that is a different kind of product and unmap is not one.

What it is good at is finding the place someone means, in English or in French, with both names on the same record.

Common problems

Every keystroke is a request. See above.

Nothing appears for a two-letter query. Keep the three-character floor. Short queries match almost everything and help nobody.

Results are in the wrong language. Pass lang: "fr" to get French names where the record has one. Without it the gateway follows the request's Accept-Language.