Skip to main content

Overview

The useLocation hook provides comprehensive location detection capabilities with a simple and intuitive API. It leverages the browser’s native geolocation API to detect user’s current position and converts coordinates into human-readable location names using reverse geocoding.

Installation

npx shadcn@latest add https://rigidui.com/r/use-location.json

Features

  • Browser Geolocation - Leverages the browser’s native geolocation API to detect user’s current position with high accuracy
  • Reverse Geocoding - Converts latitude/longitude coordinates into human-readable location names using OpenStreetMap’s Nominatim API
  • Configurable Options - Customizable API endpoints and geolocation settings including timeout, accuracy, and cache options
  • Error Handling - Comprehensive error handling for permission denials, timeouts, and network failures with descriptive messages
  • Request Prevention - Automatically prevents duplicate requests when a location is already available
  • State Management - Built-in loading and error states for seamless UI integration

Usage

import { useLocation } from "@/hooks/use-location";

export default function LocationDisplay() {
  const { location, isLoading, error, getCurrentLocation } = useLocation();

  return (
    <div className="space-y-4">
      <button
        onClick={getCurrentLocation}
        disabled={isLoading}
        className="px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
      >
        {isLoading ? "Detecting..." : "Get My Location"}
      </button>
      
      {location && (
        <div className="p-3 bg-green-100 rounded">
          <p>You are in: {location}</p>
        </div>
      )}
      
      {error && (
        <div className="p-3 bg-red-100 text-red-800 rounded">
          {error}
        </div>
      )}
    </div>
  );
}

API Reference

Parameters

options
UseLocationOptions
Configuration options for the hook
options.apiUrl
string
default:"'https://nominatim.openstreetmap.org'"
The API endpoint URL for reverse geocoding requests. By default, uses OpenStreetMap’s Nominatim API.
options.geolocationOptions
PositionOptions
default:"{ timeout: 10000, enableHighAccuracy: true }"
Configuration options for the browser geolocation API
timeout
number
default:"10000"
Maximum time in milliseconds to wait for location detection
enableHighAccuracy
boolean
default:"true"
Whether to request high accuracy location (may take longer and use more battery)
maximumAge
number
default:"0"
Maximum age in milliseconds of a cached position that is acceptable to return

Return Values

location
string
The current location name (city, county, or state). Returns an empty string if no location has been detected.
coordinates
LocationCoordinates | null
The latitude and longitude coordinates of the current location. Returns null if no location has been detected.
type LocationCoordinates = {
  latitude: number;
  longitude: number;
}
isLoading
boolean
Loading state indicator for location operations. true when fetching location, false otherwise.
error
string | null
Error message if location detection fails. Returns null if no error has occurred.
getCurrentLocation
() => void
Function to get the user’s current location using browser geolocation API. Automatically prevents duplicate requests if a location is already available.
getLocationFromCoordinates
(lat: number, lon: number) => Promise<void>
Function to get location name from specific latitude and longitude coordinates using reverse geocoding.
clearLocation
() => void
Function to clear the current location, coordinates, and any error state, resetting the hook to its initial state.

TypeScript

export type LocationCoordinates = {
  latitude: number;
  longitude: number;
}

export interface UseLocationOptions {
  apiUrl?: string;
  geolocationOptions?: PositionOptions;
}

export interface UseLocationReturn {
  location: string;
  coordinates: LocationCoordinates | null;
  isLoading: boolean;
  error: string | null;
  getCurrentLocation: () => void;
  getLocationFromCoordinates: (lat: number, lon: number) => Promise<void>;
  clearLocation: () => void;
}

Error Handling

The hook provides detailed error messages for different failure scenarios:
All errors are stored in the error state and can be displayed to users for better UX.
Geolocation Errors:
  • Permission Denied - “Location access denied by user” - User declined location permission
  • Position Unavailable - “Location information unavailable” - Device cannot determine location
  • Timeout - “Location request timed out” - Request exceeded timeout duration
  • Browser Support - “Geolocation is not supported by this browser” - Browser lacks geolocation API
API Errors:
  • Network Error - Custom error message from the geocoding API when reverse geocoding fails
  • Response Error - “Failed to fetch location: [statusText]” - API returned non-OK status

Important Notes

Browser geolocation requires HTTPS in production environments. The geolocation API will not work on insecure HTTP connections except for localhost during development.
Users will be prompted to allow location access on first use. The browser remembers this permission for future visits.
The hook automatically prevents duplicate requests when a location is already available. Call clearLocation() first if you need to refresh the location.
Additional Considerations:
  • The hook uses OpenStreetMap’s Nominatim API by default for reverse geocoding
  • Coordinates are cached until clearLocation() is called or the component unmounts
  • The maximumAge option can be used to cache positions and reduce battery usage
  • High accuracy mode (enableHighAccuracy: true) may take longer and consume more battery but provides better precision
  • The hook returns location names in priority order: county → city → state → full display name

Browser Compatibility

The useLocation hook relies on the Geolocation API, which is supported in all modern browsers:
  • Chrome 5+
  • Firefox 3.5+
  • Safari 5+
  • Edge (all versions)
  • Opera 10.6+
  • iOS Safari 3.2+
  • Android Browser 2.1+
Always check for browser support using the error state. The hook will set an error if geolocation is not supported.

Build docs developers (and LLMs) love