JavaScript Geolocation Table

PieceWhat it doesField note
getCurrentPosition(ok, err)One-shot locationAsync always - GPS can take seconds; design the loading state
watchPosition(id)Continuous trackingReturns an id - clearWatch or the GPS stays hot (battery)
coords.accuracyThe honesty numberMeters of uncertainty - a 2000m accuracy is a neighborhood, not an address
Permission promptThe user decidesDeny = PERMISSION_DENIED forever-ish - design the denied state first
HTTPS onlyThe gateLike clipboard and camera - insecure contexts get no geolocation
timeout + maximumAgeThe patience knobsmaximumAge accepts cached fixes - fresh-only requests drain batteries
No background trackingPage-visible onlyReal background location needs a native app - web stops with the tab
reverse geocodingCoordinates to addressNOT in the API - a map service call (and its key) comes after
Reference: the MDN Geolocation reference. Geolocation returns COORDINATES with an honesty number: coords.accuracy in meters is the uncertainty radius - treating a 2-kilometer fix as a precise address is the classic UX lie. The contract is permission-gated (prompt once per origin, deny sticks), HTTPS-only, and page-visible-only - real background tracking is a native-app capability. Bottom line: watchPosition holds the GPS hot (clearWatch or drain batteries), maximumAge accepts cached fixes for fast starts, and converting coordinates to addresses is a separate map-service call the API does not include. Related tools: notifications table (the other deny-sticks permission), getUserMedia table (the same permission family), and security headers table (the HTTPS gate).

Geolocation returns COORDINATES with an honesty number: coords.accuracy is the uncertainty radius in meters - treating a 2-kilometer fix as a precise address is the classic UX lie, and reading the accuracy before drawing the map is what separates honest location UI from confident nonsense.

Bottom line: the contract is permission-gated (a prompt the user decides once, where deny sticks), HTTPS-only, and page-visible-only - real background tracking is a native-app capability that the web deliberately does not offer. watchPosition holds the GPS radio hot; clearWatch is the battery valve.

The honest part: the API stops at coordinates. Turning them into addresses (reverse geocoding) is a separate map-service call with its own key and quota - and that service, not the browser, decides how much location detail your users actually get.

How to use

  1. Design the denied state first: the error callback (code 1 = PERMISSION_DENIED) needs a manual-entry fallback - location is an enhancement, not the form.
  2. Budget the accuracy: if coords.accuracy > 500m, show 'near you' granularity, not an address pin - the honesty number is part of the data, not noise.
  3. Watch with discipline: watchPosition for live tracking, clearWatch(id) the moment tracking ends - an orphaned watch keeps the GPS radio hot for hours.

Frequently asked questions

Why is my location reading wildly different between requests?

Because the source changes under you. The browser picks the best available fix: GPS (accurate, slow, battery-hungry), Wi-Fi triangulation (medium), or IP geolocation (city-level, instant) - and each request can land on a different source, especially indoors where GPS degrades. coords.accuracy exists precisely to report WHICH quality you got: a 30m fix is GPS, a 2000m fix is probably IP-level. The UX rule: gate your granularity on the accuracy number (a 'near you' radius, not a pin), and use maximumAge to accept a recent cached fix for instant starts instead of demanding a fresh GPS lock for every page view.

What does the permission flow look like when a user denies?

Deny sticks. The prompt appears once per origin per granting decision; a denial is remembered, and subsequent getCurrentPosition calls fail immediately with PERMISSION_DENIED (code 1) without ever re-prompting. The recovery path is user-manual: browser site settings, which no script can open. This is why the denied state is a first-class UI screen, not an error toast: explain what location enables, link the settings instructions, and offer a manual alternative (city picker, postal code) - the same discipline as the notifications permission, because both are relationships the user can end permanently with one click.

How do timeout and maximumAge change the request behavior?

They control patience and freshness. timeout caps how long the browser may work on a fix before erroring (a GPS cold-start can take 30+ seconds; without a timeout the user waits blind). maximumAge says how old a CACHED fix may be and still be returned - maximumAge: 60000 returns a fix up to a minute old instantly, trading freshness for speed; maximumAge: 0 (the default) demands fresh, which is slower and more battery-hungry. The pattern: first call with a generous maximumAge for an instant coarse position, then a fresh request (or watchPosition) to refine - progressive enhancement applied to location itself.

Can a web page track location in the background?

No - by design, and it is one of the sharpest web/native lines. Geolocation callbacks only fire while the page is alive and visible; switching tabs throttles them, closing the tab stops them entirely. Continuous background tracking (a run logger, a delivery app) requires a native app or a browser-specific installable surface with its own stricter permissions. Within a page, watchPosition is the tool - but it is a foreground contract: the GPS radio stays hot while the page lives, which is both the feature (live updates) and the cost (battery) - clearWatch when the user stops moving or the feature ends.

Related tools