Quick Tip: Detecting Your Location With JavaScript

Quick Tip: Detecting Your Location With JavaScript

Most modern devices are capable of detecting their own location either through GPS, WiFi, or IP geolocation. Developers can use this information to provide better search suggestions, nearby store locations, and implement all kinds of useful map interactions in their apps and websites.

In the article below we’re going to take a look at an easy, pure-JavaScript way to access a device’s whereabouts without relying on any external dependencies or third-party services. Let’s begin!

Location sources

JavaScript offers a simple, yet powerful tool for locating devices in the form of the Geolocation API. It consists of a small set of easy to use methods that can obtain the device position through all three of the previously mentioned services:

  • GPS – primarily on mobile devices, very accurate up to 10 meters.
  • WiFi – available on most internet connected devices, also very accurate.
  • IP geolocation – limited to region and often times unreliable, used as a worst-case scenario when the other two fail.

When geo data is requested the browser will try and use all three of the above options depending on what’s available. The results from the WiFi source are usually used as it is quicker than GPS and way more accurate than IP geolcation.

Using the Geolocation API

The Geolocation API has almost full cross-browser support, but to make sure that it’s accessible to our users, it’s a good idea before doing anything to check whether the geolocation object exists in the Window.navigator interface.

if (navigator.geolocation) {
  // geolocation is available
} 
else {
  // geolocation is not supported
}

Inside the navigator.geolocation object reside all of the methods for the API:

  • Geolocation.getCurrentPosition() – Determines the device’s current location.
  • Geolocation.watchPosition() – Listens for changes in the location and invokes a callback on every movement.
  • Geolocation.clearWatch() – Removes a watchPosition event handler.

Тhe getCurrentPosition() and watchPosition() methods are used in a nearly identical fashion. They both work asynchronously, trying to obtain the device position and depending on the outcome of the attempt call a success callback or an error callback if it’s provided.

navigator.geolocation.getCurrentPosition(

    // Success callback
    function(position) {

        /*
        position is an object containing various information about
        the acquired device location:

        position = {
            coords: {
                latitude - Geographical latitude in decimal degrees.
                longitude - Geographical longitude in decimal degrees. 
                altitude - Height in meters relative to sea level.
                accuracy - Possible error margin for the coordinates in meters. 
                altitudeAccuracy - Possible error margin for the altitude in meters. 
                heading - The direction of the device in degrees relative to north. 
                speed - The velocity of the device in meters per second.
            }
            timestamp - The time at which the location was retrieved.
        }
        */

    },

    // Optional error callback
    function(error){

        /* 
        In the error object is stored the reason for the failed attempt:

        error = {
            code - Error code representing the type of error 
                    1 - PERMISSION_DENIED
                    2 - POSITION_UNAVAILABLE
                    3 - TIMEOUT

            message - Details about the error in human-readable format.
        }
        */

    }
);

As you can see, using the Geolocation API is pretty straightforward. We just have to call the right method, wait for it to return the coordinates, and then do whatever we want with them.

User permission

Since the Geolocation API exposes deeply personal information, when an application tries to access it for the first time, a dialog pops up requesting permission. This ensures that users will not have their private data revealed unless they explicitly allow it.

Permission Dialog In Desktop Chrome

Permission Dialog In Chrome On Android

Permission Dialog In Chrome On Android

The browser usually takes care for displaying the dialog, but permission can also be requested programmatically by the developer. This is sometimes necessary, since once denied the original browser-generated dialog doesn’t show itself a second time.

Secure hosts

Another protective measure is the usage of an HTTPS connection. Due to a new web security policy, Google Chrome (both desktop and mobile versions) no longer allows non-secure hosts to run the Geolocation API. Instead, developers who want to use this feature are required to serve their apps over HTTPS, thus minimizing the risks of having people’s data stolen or abused.

You can read more about the issue in this Google Developers blog post.

Demo app

To demonstrate how the whole process works, we’ve built an oversimplified app showcasing some of the capabilities of the API. It consists of a button, which when pressed, grabs the device coordinates and feeds them to this GMaps plugin, pinpointing the location on the map.

findMeButton.on('click', function(){

    navigator.geolocation.getCurrentPosition(function(position) {

        // Get the coordinates of the current position.
        var lat = position.coords.latitude;
        var lng = position.coords.longitude;

        // Create a new map and place a marker at the device location.
        var map = new GMaps({
            el: '#map',
            lat: lat,
            lng: lng
        });

        map.addMarker({
            lat: lat,
            lng: lng
        });

    });
    
});

The demo, as well as the full code are available on JSFiddle:

Demo on JSfiddle

Demo on JSfiddle

Conclusion

The Gelocation API is reliable and production ready, so we encourage you to play around with it and see what it’s capable of. If you’ve seen some original uses of this technology on the web, or you’ve made a cool project yourself, fell free to share it in the comment section below – we would love to see it!

Presenting Bootstrap Studio

a revolutionary tool that developers and designers use to create
beautiful interfaces using the Bootstrap Framework.

Learn more
Web Browser Frame DevKit Box Mouse Cursor
by Danny Markov

Danny is Tutorialzine's Bootstrap and HTML5 expert. When he is not in the office, you can usually find him riding his bike and coding on his laptop in the park.

1Share this post
2Read one more article
3Get your free book
Book Cover
jQuery Trickshots

Tutorialzine's advanced jQuery techniques book.

Download

7 Comments

  1. Ivan Yosifov says:

    Great article, but could you do a demo doing the same thing with PHP and MySQL database. IP detection is mostly done through services or paid databases. I would really appreciate a tutorial where you have your own database populated from CSV file and accessed though PHP.

  2. Michael says:

    Thanks for the article! :)

    Wonder is there a typo over there?
    " latitude - Geographical longitude in decimal degrees. "

    Should it be " longitude - Geographical longitude in decimal degrees. " ?

    1. Danny Markov says:

      Hi Michael!

      Yep, it's a typo, thanks for pointing it out. It's fixed now :)

  3. Luis Cabrera says:

    Really good!

  4. Robbie Jackson says:

    Hi, Danny!
    Thank you for your awesome tutorial!
    I appreciate your work.

    By the way, I've found something unpleasant. I get wrong locale of my own via your sample.
    Would you help me? Thank you.
    Regards

    1. Danny Markov says:

      Hi Robbie!

      Depending on which service is used, the GeolocationAPI may return a location that is nowhere near your real one. There isn't much you can do about this except to fiddle with the PositionOptions object and setting the enableHighAccuracy to true.

      Hope I've been helpful :)

  5. Jamie Young says:

    Can this be adapted so that if not on a HTTPS connection it defaults to locating by IP, so that it is 'foolproof'?

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links