Skip to content

About

Browser Geolocation API for Vue 3 — useGeolocation() composable + standalone promise-based functions. TypeScript. npm: vue-browser-geolocation

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

85 stars

Watchers

3 watching

Forks

Repository files navigation

vue-browser-geolocation

Tiny, type-safe Geolocation for Vue 3 — a reactive useGeolocation() composable and standalone Promise-based helpers.

npm version npm downloads CI minzipped size license

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 — coords updates on every position fix, not just the first.
  • Real errors — rejects with the full GeolocationPositionError so you can branch on error.code.
  • Type-safe — written in TypeScript, ships .d.ts. ESM + CJS builds.
  • Lightweight — zero runtime dependencies, vue is a peer dependency.

Install

npm install vue-browser-geolocation
# or
pnpm add vue-browser-geolocation
# or
yarn add vue-browser-geolocation

Requires Vue 3 (^3.2.25).

Composable (recommended)

<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.

Why not VueUse's useGeolocation?

  • Flat, typed Coordinates result ({ lat, lng, accuracy, ... }) instead of raw GeolocationCoordinates/GeolocationPosition fields spread across refs.
  • Typed error classes — GeolocationUnsupportedError and GeolocationForcedRejectError — so you can instanceof-check failure modes instead of parsing messages.
  • Built-in forceReject testing hook on getLocation/watchLocation to exercise failure paths without mocking navigator.geolocation.
  • Zero dependencies beyond the vue peer dependency — no @vueuse/core / @vueuse/shared pulled in.

Standalone functions

Everything is also importable directly, no Vue instance required:

import {
  getLocation,
  watchLocation,
  clearWatch,
  isSupported,
} from 'vue-browser-geolocation'

Coordinates

interface Coordinates {
  lat: number
  lng: number
  altitude: number | null
  altitudeAccuracy: number | null
  accuracy: number
  heading: number | null
  speed: number | null
}

Distance helper

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)

Options

See PositionOptions — { enableHighAccuracy?, timeout?, maximumAge? }.

Testing escape hatch

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) // rejects

Migrating from v2 (plugin API)

v3 drops the VueGeolocation plugin and the $getLocation / $watchLocation / $clearLocationWatch global properties — use useGeolocation() or the standalone functions directly.

Migrating from v1 (Vue 2)

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.

License

MIT © Marco Boffo

About

Browser Geolocation API for Vue 3 — useGeolocation() composable + standalone promise-based functions. TypeScript. npm: vue-browser-geolocation

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

85 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages