# useGeolocation

The device's position, watched with `navigator.geolocation.watchPosition` and updated as it moves. Stops watching on unmount or when disabled.

Enabling it makes the browser ask the user for permission the first time, so pass `enabled: false` until the user asks for location (e.g. clicks "Use my location"). On the server and during hydration it returns the initial state: `loading` if enabled, with no position.

## Import

```ts
import { useGeolocation } from '@vincent.ri/react-tils'
// or only this hook
import { useGeolocation } from '@vincent.ri/react-tils/useGeolocation'
```

## Usage

```ts
const [asked, setAsked] = useState(false)
const { loading, position, error } = useGeolocation({ enabled: asked })
if (!asked) return <button onClick={() => setAsked(true)}>Use my location</button>
if (loading) return <p>Locating…</p>
if (error) return <p>Could not get your location: {error.message}</p>
return <Map lat={position!.coords.latitude} lng={position!.coords.longitude} />
```

## When to use it

Showing the user on a map, sorting nearby results, or filling in a location after the user asks.

## When not to

A rough region is enough; use IP-based location on the server, which needs no prompt. Don't enable it on page load: users deny unexpected prompts, and a denial is hard to undo. To check the permission without prompting, use `usePermission('geolocation')`.

## API

```ts
function useGeolocation(options?: GeolocationOptions): GeolocationState
```

| Parameter | Description |
| --- | --- |
| `options` | `enabled`, `enableHighAccuracy`, `maximumAge`, and `timeout`. All optional. |

### Types

```ts
export type GeolocationOptions = {
  /** Start watching. Default `true`. Pass `false` until the user asks, to avoid a prompt on page load. */
  enabled?: boolean;
  /** Ask for GPS-level accuracy. Slower and uses more battery. Default `false`. */
  enableHighAccuracy?: boolean;
  /** Accept a cached position up to this many milliseconds old. Default `0`. */
  maximumAge?: number;
  /** Give up after this many milliseconds per attempt. Default: no limit. */
  timeout?: number;
};
export type GeolocationState = {
  /** `true` while enabled and waiting for the first position or error. */
  loading: boolean;
  position: GeolocationPosition | null;
  /** `GeolocationPositionError` (denied, unavailable, timeout), or an `Error` if the browser has no geolocation. */
  error: GeolocationPositionError | Error | null;
};
```

## Browser support

Works in all modern browsers.

- Needs a secure page (HTTPS or localhost).

---

305 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useGeolocation.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useGeolocation/
Previous: [usePermission](https://vincentri.github.io/react-tils/hooks/usePermission.md)
Next: [useHydrated](https://vincentri.github.io/react-tils/hooks/useHydrated.md)
