X Enterprises
Composables

useGeolocation

Reactive wrapper around the browser Geolocation API plus Haversine distance helper for "near me" features.

useGeolocation

Reactive composable for the browser Geolocation API, plus helpers for distance calculation and formatting.

Usage

<script setup>
const { coords, request, supported } = useGeolocation()

// Trigger permission prompt + fetch on mount (or on user gesture)
onMounted(() => request())
</script>

<template>
  <span v-if="coords">Near {{ coords.lat.toFixed(2) }}, {{ coords.lng.toFixed(2) }}</span>
  <UButton v-else-if="supported" @click="request">Use my location</UButton>
  <span v-else>Geolocation not available</span>
</template>

The composable does not auto-request permission — you must call request() from a user gesture or after explicit consent. Most browsers require this.

Returns

KeyTypeDescription
coordsRef<{ lat: number, lng: number } | null>Current position. null until request() succeeds.
errorRef<string | null>Last error message (e.g., permission denied). null on success.
loadingRef<boolean>true while a position request is in flight.
supportedbooleanWhether navigator.geolocation exists.
request() => voidTrigger the position request. No-op if already loading or unsupported.

Helpers

distanceMiles(lat1, lng1, lat2, lng2)

Haversine great-circle distance between two lat/lng pairs, in miles.

import { distanceMiles } from '#imports'

const mi = distanceMiles(47.61, -122.20, 47.60, -122.33)  // ~6 mi Bellevue→Seattle

formatDistance(miles)

Formats miles as "< 0.1 mi" / "0.3 mi" / "12 mi" (rounds up after 10).

import { formatDistance } from '#imports'

formatDistance(0.05)   // '< 0.1 mi'
formatDistance(1.234)  // '1.2 mi'
formatDistance(12.5)   // '13 mi'

Notes

  • State is shared via useState — multiple components calling useGeolocation() see the same coords/error/loading values.
  • The position is cached for 5 minutes (maximumAge) — calling request() repeatedly won't keep prompting for fresh GPS fixes.
  • highAccuracy: false is used by default for battery efficiency.

AI Context

composable: useGeolocation
package: "@xenterprises/nuxt-x-restaurants"
use-when: >
  Adding "near me" features — sort by distance, show distance on cards,
  geolocation-aware filters. The composable wraps navigator.geolocation
  with reactive state. Distance helper uses Haversine for accurate
  great-circle distances in miles.
Copyright © 2026