Tiny, type-safe Geolocation for Vue 3 — a reactive
useGeolocation()composable and standalone Promise-based helpers.
Live demo — ask for a fix, watch position updates, measure the distance travelled.
- Reactive composable —
useGeolocation()for<script setup>; auto-clears watches on unmount. - Reactive streaming —
coordsupdates on every position fix, not just the first. - Real errors — rejects with the full
GeolocationPositionErrorso you can branch onerror.code. - Type-safe — written in TypeScript, ships
.d.ts. ESM + CJS builds. - Lightweight — zero runtime dependencies,
vueis a peer dependency.
npm install vue-browser-geolocation
# or
pnpm add vue-browser-geolocation
# or
yarn add vue-browser-geolocationRequires Vue 3 (^3.2.25).
<script setup lang="ts">
import { useGeolocation } from 'vue-browser-geolocation'
const { coords, error, isWatching, getLocation, watchLocation, clearWatch } =
useGeolocation({ enableHighAccuracy: true })
// one-shot
async function locate() {
await getLocation()
console.log(coords.value) // { lat, lng, accuracy, ... }
}
// continuous — coords.value updates on every fix
watchLocation()
</script>
<template>
<p v-if="error">Error {{ error.code ?? '' }}: {{ error.message }}</p>
<p v-else-if="coords">{{ coords.lat }}, {{ coords.lng }}</p>
<button @click="locate">Locate me</button>
<button v-if="isWatching" @click="clearWatch">Stop watching</button>
</template>useGeolocation() returns reactive refs and automatically clears the active watch when the component unmounts.
| Field | Type | Description |
|---|---|---|
coords |
Ref<Coordinates | null> |
Latest fix, null before the first one. |
error |
Ref<GeolocationError | null> |
Latest error (full object), null when fine. |
isWatching |
Ref<boolean> |
Whether a watch is active. |
getLocation(options?) |
Promise<Coordinates> |
One-shot fetch; updates coords/error. |
watchLocation(options?) |
number | undefined |
Starts a watch, returns its watchID. |
clearWatch() |
void |
Stops the active watch. |
- Flat, typed
Coordinatesresult ({ lat, lng, accuracy, ... }) instead of rawGeolocationCoordinates/GeolocationPositionfields spread across refs. - Typed error classes —
GeolocationUnsupportedErrorandGeolocationForcedRejectError— so you caninstanceof-check failure modes instead of parsing messages. - Built-in
forceRejecttesting hook ongetLocation/watchLocationto exercise failure paths without mockingnavigator.geolocation. - Zero dependencies beyond the
vuepeer dependency — no@vueuse/core/@vueuse/sharedpulled in.
Everything is also importable directly, no Vue instance required:
import {
getLocation,
watchLocation,
clearWatch,
isSupported,
} from 'vue-browser-geolocation'interface Coordinates {
lat: number
lng: number
altitude: number | null
altitudeAccuracy: number | null
accuracy: number
heading: number | null
speed: number | null
}distanceBetween(a, b) is a pure, Vue-free haversine helper returning the great-circle distance in meters between two points. It accepts this package's Coordinates or a raw { latitude, longitude } pair, mixed or matched.
import { distanceBetween } from 'vue-browser-geolocation'
distanceBetween(
{ latitude: 45.4642, longitude: 9.19 }, // Milan Duomo
{ latitude: 41.8902, longitude: 12.4922 }, // Rome Colosseum
) // ≈ 477000 (meters)See PositionOptions — { enableHighAccuracy?, timeout?, maximumAge? }.
getLocation and watchLocation accept a trailing forceReject flag. When true, the promise rejects immediately with a GeolocationForcedRejectError, letting you exercise failure paths without touching the real device API:
await getLocation({}, true) // rejects
await watchLocation({}, undefined, true) // rejectsv3 drops the VueGeolocation plugin and the $getLocation / $watchLocation / $clearLocationWatch global properties — use useGeolocation() or the standalone functions directly.
v2/v3 target Vue 3 only. Breaking changes from v1:
| v1 (Vue 2) | v3 (Vue 3) |
|---|---|
Vue.use(VueGeolocation) |
use useGeolocation() composable |
reject(error.message) (string) |
reject(error) — full GeolocationPositionError; read error.code |
$watchLocation() resolved once |
watchLocation(options, onUpdate) resolves with { watchID, coordinates } and streams via onUpdate (#15) |
| no composable | reactive useGeolocation() |
| plain JS, no types | TypeScript, ships .d.ts |
If you cannot migrate to Vue 3 yet, stay on vue-browser-geolocation@1.8.0.
MIT © Marco Boffo