Complete HTML Course Module 14: Advanced: HTML Web APIs

HTML Geolocation API: Get the User's Location

  • Beginner
  • Lesson 14.2
  • 5 min read
  • 59 of 69 in the course

In short

The HTML Geolocation API lets a web page ask for the user's location, with their permission, and get latitude, longitude and accuracy. Store finders, weather sites, delivery apps and maps all use it.

The HTML Geolocation API lets a web page ask for the user's location, with their permission, and get latitude, longitude and accuracy.

Store finders, weather sites, delivery apps and maps all use it. In this lesson you will get a location once, follow it as the user moves, handle errors, show a map link, and respect the user's privacy.

How the Geolocation API works

The API lives in navigator.geolocation. When you ask for the position:

  1. The browser shows a permission prompt to the user.
  2. If they allow it, the device works out where it is. It may use GPS, nearby Wi-Fi networks, mobile towers or the IP address.
  3. Your code receives a position object with coordinates.

Coordinates are two numbers. Latitude says how far north or south (from -90 to 90). Longitude says how far east or west (from -180 to 180). For example, the Eiffel Tower is at about latitude 48.858, longitude 2.294.

The API needs a secure context (HTTPS or localhost), as you learned in the introduction lesson.

How to get the user's location with getCurrentPosition()

Here is a complete "Find me" page:

<button type="button" id="find-me">Show my location</button>
<p id="status" role="status"></p>
<p><a id="map-link" href="#" target="_blank" rel="noopener" hidden>Open in a map</a></p>

<script>
  const status = document.querySelector("#status");
  const mapLink = document.querySelector("#map-link");

  function success(position) {
    const lat = position.coords.latitude;
    const lon = position.coords.longitude;
    const accuracy = Math.round(position.coords.accuracy);

    status.textContent = `Latitude: ${lat.toFixed(5)}, Longitude: ${lon.toFixed(5)} (within ${accuracy} m)`;
    mapLink.href = `https://www.openstreetmap.org/?mlat=${lat}&mlon=${lon}#map=16/${lat}/${lon}`;
    mapLink.hidden = false;
  }

  function error(err) {
    status.textContent = `Sorry, we could not get your location: ${err.message}`;
  }

  document.querySelector("#find-me").addEventListener("click", () => {
    if (!("geolocation" in navigator)) {
      status.textContent = "Location is not supported by your browser.";
      return;
    }
    status.textContent = "Locating…";
    navigator.geolocation.getCurrentPosition(success, error);
  });
</script>

What each part does:

  • The success function runs when the location arrives. position.coords.latitude and .longitude are the numbers. .accuracy is how sure the browser is, in metres.
  • toFixed(5) rounds to 5 decimal places (about 1 metre), which is easier to read.
  • The map link uses the free OpenStreetMap website. mlat and mlon place a marker, and #map=16/... sets the zoom. The hidden attribute is removed so the link appears.
  • The error function runs if something goes wrong, and shows the browser's message.
  • getCurrentPosition(success, error) asks once. The page waits for the answer without freezing.

Click the button, allow the prompt, and you will see your coordinates and a link that opens a map with a pin on your position.

Tip: You can also link to Google Maps with https://www.google.com/maps?q=LAT,LON, replacing LAT and LON with the numbers.

Handling errors and options

The error object has a code that tells you exactly what happened:

CodeNameMeaning
1PERMISSION_DENIEDThe user clicked Block, or location is off for this site
2POSITION_UNAVAILABLEThe device could not find a position (no signal)
3TIMEOUTIt took longer than your timeout option

You can give friendlier messages and pass options as a third argument:

function error(err) {
  if (err.code === 1) {
    status.textContent = "You blocked location. You can type your city instead.";
  } else if (err.code === 3) {
    status.textContent = "This is taking too long. Please try again.";
  } else {
    status.textContent = "We could not find your position.";
  }
}

navigator.geolocation.getCurrentPosition(success, error, {
  enableHighAccuracy: true, // try GPS for a more exact position (uses more battery)
  timeout: 10000,           // give up after 10 seconds (in milliseconds)
  maximumAge: 60000         // accept a saved position up to 1 minute old
});

Replace the error function in the first example with this one, and change the getCurrentPosition line. Now a user who blocks location gets a helpful alternative instead of a technical message.

Common mistake: Asking for the location as soon as the page loads. Users don't know why you want it yet, so they click Block, and the browser may remember that choice. Always ask after a clear action, like a "Find stores near me" button.

Following movement with watchPosition()

For a running app or a delivery map, you want updates as the user moves. watchPosition() calls your success function every time the position changes. It returns an id number, which you use to stop watching with clearWatch().

<button type="button" id="start">Start tracking</button>
<button type="button" id="stop">Stop tracking</button>
<ul id="log"></ul>

<script>
  const log = document.querySelector("#log");
  let watchId = null;

  document.querySelector("#start").addEventListener("click", () => {
    watchId = navigator.geolocation.watchPosition((position) => {
      const item = document.createElement("li");
      item.textContent = `${new Date().toLocaleTimeString()}: ${position.coords.latitude.toFixed(5)}, ${position.coords.longitude.toFixed(5)}`;
      log.append(item);
    });
  });

  document.querySelector("#stop").addEventListener("click", () => {
    navigator.geolocation.clearWatch(watchId);
  });
</script>
  • let watchId = null creates a variable to remember the watch id.
  • watchPosition(...) starts watching. Each new position adds a list item with the time and coordinates. document.createElement("li") makes a new <li>, and log.append(item) adds it to the list.
  • clearWatch(watchId) stops the updates, which also saves battery.

On a phone, start tracking and walk around: a new line appears each time your position changes.

Location privacy: how to use it responsibly

A person's location is very personal data. It can reveal their home, workplace and daily routine. Follow these rules:

  • Explain why next to the button: "We use your location only to show the nearest store."
  • Ask only when needed, and always offer another way, such as typing a postcode.
  • Use the lowest accuracy you need. A weather site doesn't need GPS. Round the numbers before you send them to a server.
  • Don't store or share it without clear consent, and follow privacy laws such as the GDPR in Europe.
  • Pages inside an iframe can only use location if the parent page allows it with <iframe src="..." allow="geolocation">.

Practice exercise

Build a "Nearest coffee shop" page. Under a short explanation, add a "Use my location" button and a text field labelled "Or type your city". When the location arrives, show the coordinates rounded to 2 decimal places and a Google Maps link that searches for coffee near them.

Hint: Rounding is lat.toFixed(2). A Google Maps search link can look like https://www.google.com/maps/search/coffee/@LAT,LON,15z.

Key takeaways

  • navigator.geolocation.getCurrentPosition(success, error, options) asks for the location once.
  • The position gives coords.latitude, coords.longitude and coords.accuracy (in metres).
  • Handle errors by code: 1 permission denied, 2 unavailable, 3 timeout.
  • watchPosition() follows movement; stop it with clearWatch(id).
  • Ask only after a user action, explain why, offer an alternative, and treat location as private data.