The Geolocation API is a very simple API that allows to get a device’s current location coordinates. It has only two methods: getCurrentPosition and watchPosition and the data returned is very straightforward, but when coupled with a mapping API, complex location-aware web apps can be created.
Before doing anything, you’ll want to check if the API is available in the user’s browsers:
if (navigator.geolocation) {
// 🗺️ yep, we can proceed!
} else {
// no can do
}
Note that your website or app has to be served over https for the API to work. For local development, you’ll want to run a local server instead of opening an html file directly. If you have npm 5.2 or above available on your machine, you can use npx to quickly run an http server:
$ npx http-server
Use the getCurrentPosition method to get the user’s coordinates once. The first and only required argument should be a success callback function that will be called with a position object if the position request is successful.
Here’s a simple example that prints out the device’s longitude and latitude to the console:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayLocationInfo);
}
function displayLocationInfo(position) {
const lng = position.coords.longitude;
const lat = position.coords.latitude;
console.log(`longitude: ${ lng } | latitude: ${ lat }`);
}
Here’s the shape and example data of the position object that’s passed to the success callback:
coords:
accuracy: 52
altitude: null
altitudeAccuracy: null
heading: null
latitude: 27.380583
longitude: 33.631839
speed: null
timestamp: 1509152059444
As you can see from the above example, some of the properties for coords may have a value of null. The availability of the data will depend on the capabilities of the device that’s under use. The heading value, if any, will be in degrees relating to true North and going clockwise and the speed value, if any, will be in meters per second.
Because position information is potentially sensitive, the first time a domain makes a call to get a user’s position, the browser will ask the user for permission by showing a widget that looks a little bit like this:
If the user refuses access, the error callback, if any, will be called with an error code of 1 (PERMISSION_DENIED).
There’s also a watchPosition method that will return new position data each time the device changes position significantly.
In the following example, we initiate a position watcher and then stop it after 15 seconds:
const watcher = navigator.geolocation.watchPosition(displayLocationInfo);
setTimeout(() => {
navigator.geolocation.clearWatch(watcher);
}, 15000);
function displayLocationInfo(position) {
// ...do something with the data each time
}
We use clearWatch with a watcher id to stop watching for position data.
You can provide an error handler callback as the second argument to either getCurrentPosition or watchPosition. If the error callback is called, an error object will be passed-in and will contain a code property that will have a value of 3 (TIMEOUT), 2 (POSITION_UNAVAILABLE) or 1 (PERMISSION_DENIED), depending on the nature of the error.
Here’s a simple example where we trigger an automatic error by setting a timeout value of 0ms:
navigator.geolocation.getCurrentPosition(displayLocationInfo, handleLocationError, { timeout: 0 });
function displayLocationInfo(position) {
// ...do stuff
}
function handleLocationError(error) {
switch (error.code) {
case 3:
// ...deal with timeout
break;
case 2:
// ...device can't get data
break;
case 1:
// ...user said no ☹️
}
}
Finally, you can pass-in a third argument with options for the following:
Here’s an example with options passed-in for maximumAge and timeout:
navigator.geolocation.getCurrentPosition(
displayLocationInfo,
handleLocationError,
{ maximumAge: 1500000, timeout: 0 }
);
function displayLocationInfo(position) {
const lng = position.coords.longitude;
const lat = position.coords.latitude;
console.log(`longitude: ${lng} | latitude: ${lat}`);
}
function handleLocationError(error) {
switch (error.code) {
case 3:
// timeout was hit, meaning nothing's in the cache
// let's provide a default location:
displayLocationInfo({ coords: { longitude: 33.631839, latitude: 27.380583 } });
// now let's make a non-cached request to get the actual position
navigator.geolocation.getCurrentPosition(displayLocationInfo, handleLocationError);
break;
case 2:
// ...
break;
case 1:
// ...
}
}
If there’s cached position data that’s available and that’s a maximum of 25 minutes old (1500000ms) we return that. If not, we error-out immediately (using a timeout of 0ms). In the error handler case for a timeout, we provide a default location value and then make another call to get fresh location data. This way, the app can avoid showing a blank state while fresh position data is being gathered.
Browser Support
Can I Use geolocation? Data on support for the geolocation feature across the major browsers from caniuse.com.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.