Web APIs Cheatsheet

Geolocation

Use this Web APIs reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Checking Support

if ('geolocation' in navigator) {
  // API available
}

getCurrentPosition

navigator.geolocation.getCurrentPosition(
  successCallback,
  errorCallback,   // optional
  options          // optional
);

// Example
navigator.geolocation.getCurrentPosition(
  pos => {
    const { latitude, longitude, accuracy, altitude,
            altitudeAccuracy, heading, speed } = pos.coords;
    const timestamp = pos.timestamp; // ms since epoch
    console.log(latitude, longitude);
  },
  err => {
    // err.code: 1=PERMISSION_DENIED, 2=POSITION_UNAVAILABLE, 3=TIMEOUT
    // err.message: human-readable string
    console.error(err.code, err.message);
  },
  {
    enableHighAccuracy: true,  // GPS (battery-intensive); default false
    timeout: 5000,             // ms until error; default Infinity
    maximumAge: 0,             // ms to use cached position; 0 = always fresh
  }
);

Promise wrapper

function getPosition(options) {
  return new Promise((resolve, reject) =>
    navigator.geolocation.getCurrentPosition(resolve, reject, options)
  );
}

try {
  const pos = await getPosition({ enableHighAccuracy: true, timeout: 8000 });
  console.log(pos.coords.latitude, pos.coords.longitude);
} catch (e) {
  console.error(e.code, e.message);
}

watchPosition

const watchId = navigator.geolocation.watchPosition(
  pos => {
    // Called whenever position changes
    updateMap(pos.coords.latitude, pos.coords.longitude);
  },
  err => console.error(err),
  { enableHighAccuracy: true, maximumAge: 1000 }
);

// Stop watching
navigator.geolocation.clearWatch(watchId);

GeolocationCoordinates Properties

PropertyTypeDescription
latitudenumberDecimal degrees (-90 to 90)
longitudenumberDecimal degrees (-180 to 180)
accuracynumberMeters radius of uncertainty
altitudenumber | nullMeters above WGS84 ellipsoid
altitudeAccuracynumber | nullMeters uncertainty for altitude
headingnumber | nullDegrees clockwise from true north (0–360), NaN if speed is 0
speednumber | nullMeters per second; null if unavailable

Error Codes

CodeConstantCause
1PERMISSION_DENIEDUser denied or site not allowed
2POSITION_UNAVAILABLENetwork down, GPS unavailable
3TIMEOUTResponse took longer than timeout ms

Options Reference

OptionTypeDefaultDescription
enableHighAccuracybooleanfalseRequest GPS-level accuracy
timeoutnumberInfinityMax ms to wait for a position
maximumAgenumber0Accept cached position up to N ms old

Permissions API Integration

// Check permission status without triggering a prompt
const status = await navigator.permissions.query({ name: 'geolocation' });
status.state; // 'granted' | 'denied' | 'prompt'
status.addEventListener('change', () => console.log(status.state));

Distance Between Two Points (Haversine)

function haversineKm(lat1, lon1, lat2, lon2) {
  const R = 6371; // Earth radius km
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = Math.sin(dLat / 2) ** 2
    + Math.cos(lat1 * Math.PI / 180)
    * Math.cos(lat2 * Math.PI / 180)
    * Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}

Geolocation in a Worker

navigator.geolocation is not available inside Web Workers or Service Workers. Call it on the main thread and postMessage the coordinates.

// main.js
navigator.geolocation.getCurrentPosition(pos => {
  worker.postMessage({ lat: pos.coords.latitude, lon: pos.coords.longitude });
});

Common Patterns and Gotchas

  • HTTPS required: Geolocation is blocked on plain HTTP (except localhost).
  • User gesture: Some browsers require a user gesture to trigger the permission prompt.
  • Coordinates from watchPosition may jump. Apply smoothing (e.g., Kalman filter or rolling average) for smoother tracking.
  • heading is NaN when speed is 0 on most devices.
  • altitude and altitudeAccuracy are null on many desktop browsers.
// Timeout + high-accuracy with fallback to low-accuracy
async function getBestPosition() {
  try {
    return await getPosition({ enableHighAccuracy: true, timeout: 5000 });
  } catch (e) {
    if (e.code === 3 /* TIMEOUT */) {
      return getPosition({ enableHighAccuracy: false, timeout: 10000 });
    }
    throw e;
  }
}

Reverse Geocoding (Coordinates to Address)

The Geolocation API only gives coordinates. Use an external service for addresses.

const { latitude: lat, longitude: lon } = position.coords;

// Nominatim (OpenStreetMap, free, rate-limited)
const res = await fetch(
  `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json`
);
const { display_name } = await res.json();

// Google Maps Geocoding API
const res2 = await fetch(
  `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lon}&key=API_KEY`
);