Browser Geolocation API Explained — What Websites Can and Can't See

Ahmed Anwar
9 min read

If you’ve ever called navigator.geolocation.getCurrentPosition once and assumed you understood what it does — same. Then I built a site whose entire purpose is to call that one function in every plausible permutation, and the surprising answer is that the API itself is the small part. Most of what looks like behaviour of the browser is actually behaviour of the operating system underneath it, and the same five lines of JavaScript can return a 3-meter GPS fix, a 25-meter Wi-Fi guess, or a 5-kilometre IP estimate depending on what the OS decides to hand back.

This article is the version of the W3C Geolocation API I wish I had when I started. What the page sees. What it doesn’t. What enableHighAccuracy really does. Which error codes are recoverable and which aren’t.

PagegetCurrentPosition()Browserpermission checkOSsignal fusionGPS satellites · 3–5 mWi-Fi BSSID · 10–25 mCell tower · 500 m+IP fallback · kilometressingle coordinate flows back
The browser never measures location itself. It asks the OS, which picks whichever combination of signals is available and hands one coordinate back.

The surface area is tiny

The browser exposes navigator.geolocation with three methods:

The first call (of either method) triggers the permission prompt: “getmylocations.com wants to use your location: Allow / Block.” The actual coordinate only flows back after Allow.

What lands in the success callback

A GeolocationPosition with two parts: a timestamp and a coords dictionary containing:

That’s the whole payload. The page does not receive: which satellites were heard, which Wi-Fi BSSIDs were scanned, the user’s IP (that comes from the connection itself, not from the API), the device’s unique identifier, or any history. Each call returns a fresh reading; nothing about previous calls is shared with the page.

Where the coordinate actually comes from

The browser doesn’t measure location. It asks the OS, which fuses signals depending on hardware and permissions:

The OS picks the most accurate combination it can and presents a single coordinate. The accuracy field is the only signal you get about which source won — under 10 m almost always means GPS, 20–100 m typically Wi-Fi, 1000+ usually IP-only.

enableHighAccuracy is not always what you want

The options object accepts the flag { enableHighAccuracy: true }. Setting it asks the OS to use GNSS even when it’s slower and more battery-hungry. Off, the OS may return a cached Wi-Fi-only fix in milliseconds. On, it spends a few seconds talking to satellites for a meter-grade reading.

Counterintuitively, high accuracy is sometimes worse for the user. If you’re indoors with no GPS line-of-sight, asking for high accuracy makes the OS fight a losing battle for several seconds before giving up and falling back anyway. For most map-style use cases, the default is right.

The permission model has more layers than you’d expect

The API is gated by a stack of restrictions, not one:

  1. HTTPS required. The API silently fails on plain HTTP. This blocks a man-in-the-middle attacker from injecting a fake location.
  2. User gesture required (sometimes). Some browsers refuse to show the prompt unless the call originates inside a click handler, to prevent surprise prompts on page load.
  3. Per-site permission, remembered. The user’s choice is stored per origin. They can revoke it at any time from the browser’s site-settings UI.
  4. Iframe restrictions. Modern browsers require third-party iframes to carry an explicit allow="geolocation" attribute to even ask.
  5. OS-level kill switch. If the user has disabled location at the operating-system level, the browser falls back to IP-only regardless of what the page does.

The three error codes and what to do about each

The error callback receives a GeolocationPositionError with a numeric code. They behave very differently:

Distinguishing these matters because the recovery flow is different for each. The biggest UX win I ever shipped on this site was a dedicated permission-denied screen that walks the user through re-enabling location for the site in their specific browser, with the right instructions for Chrome, Safari, and Firefox. That alone roughly doubled successful re-fixes.

What a page can and can’t infer about you

Once you grant permission, the page sees a coordinate. From one reading, less is deducible than people fear:

The single most useful privacy lever a user has is to revoke permission for sites that don’t need live location. A map site asking once per visit is fine. A games or social app silently calling watchPosition in the background is something to be skeptical of.

How this site uses the API

GetMyLocations calls getCurrentPosition once on page load after permission is granted, then optionally switches to watchPosition if the user enables live tracking. Coordinates are processed entirely in the browser. Map tiles and reverse-geocoding requests go to third parties as described in the Privacy Policy, but the raw coordinate itself is never sent to a server I operate.

If you want to feel the difference between accuracy values directly, open the tool and toggle precise-location off and back on in your browser’s site settings. The accuracy radius drawn on the map jumps from ~5 m to ~10 km in real time. More intuitive than any blog post.

← Back to all posts