Detecting Online Status with JavaScript

By  on  

It seems like there's been a huge push in the past year or two to make offline browsing an enjoyable experience with the web;  a large part of that push probably being HTML5 mobile apps, or just web apps in general.  Of course it would be helpful if we could determine whether or not the user is online at the time, and a navigator property promises to provide us that answer.

navigator.onLine

The navigator.onLine property provides a Boolean value for whether or not the user is connected to the internet.  You can access as such:

if(navigator.onLine) { // true|false
	// ...
}

Doesn't get easier than that!

Events

In addition to checking for the property value, you can hook into offline and online events:

function updateIndicator() {
	// Show a different icon based on offline/online
}

// Update the online status icon based on connectivity
window.addEventListener('online',  updateIndicator);
window.addEventListener('offline', updateIndicator);
updateIndicator();

If you wanna roll dumb-school old school you can use ononline and onoffline attributes on the body tag.  Gross.

I can think of many uses for these events and the property itself.  If the user was doing work locally without a connection, for example, the web app could detect that and save all changes within localStorage until the user connected to the internet and then the app could send data to the server.  That's just one example, I'm sure you could think of many more!

There is concern that this API isn't reliable, however. A basic fallback would be polling a given address and returning a desired response.

Recent Features

  • By
    Vibration API

    Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in...

  • By
    Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

Incredible Demos

  • By
    Unicode CSS Classes

    CSS class name structure and consistency is really important; some developers camelcase classnames, others use dashes, and others use underscores.  One thing I've learned when toying around by HTML and CSS class names is that you can actually use unicode symbols and icons as classnames.

  • By
    Dijit’s TabContainer Layout:  Easy Tabbed Content

    One of Dojo's major advantages over other JavaScript toolkits is its Dijit library.  Dijit is a UI framework comprised of JavaScript widget classes, CSS files, and HTML templates.  One very useful layout class is the TabContainer.  TabContainer allows you to quickly create a tabbed content...

Discussion

  1. Dav

    the problem is browser support. If I recall correctly Firefox returns the check false everytime. It’s not completely standard and that’s a shame!

  2. Szymon

    “dumb-school old school” – declarative markup is on the rise again (e.g. angular, polymer), so…

  3. Stefan

    I think the real issue with this is:

    > “online” does not always mean connection to the internet, it can also just mean connection to some network.
    (Quote vom caniuse.com)

  4. Ryvan

    Well,if anyone looking for a quick solution , try out my jquery plugin.

    https://github.com/ryvan-js/wiremonkey

    • Just ran into this and tested because of course I was skeptical… This is great! Will definitely use if you don’t mind.

  5. Jer

    Remy Sharp created a polyfill, which fills in some gaps. Though, Opera is not supported outright, and Safari (apparently) has support, but doesn’t update the “navigator.onLine” property.

    https://github.com/remy/polyfills/blob/master/offline-events.js

  6. Matt

    Tried testing, this doesn’t seem to account for if the internet connection drops after page load. I loaded form, disconnected internet, and submitted; but still returns true, and ajax call as success without connection.
    Testing in Chrome, suggestions?

  7. I am connected my laptop via mobile hostspot now I have switched off on mobile and I am still getting following result

    navigator.onLine
    // true
    
  8. Ian Kirkpatrick

    As stated, different browsers have their own definitions of what ‘online’ means.

    For example: I added a navbar to one of my apps where, when the status changes to offline, a banner appears notifying the user that they are in offline mode. This banner appears as expected when I simply turn off wifi with Chrome and Firefox but not in Safari.

    If I add a recursive function to check every navigator.onLine every second I get true every second for safari even after my wifi has been disconnected. (Chrome and Firefox give me my expected results of true/false)

  9. John McGovern

    Thank you David. You helped me before and I really appreciate it!

  10.         $(document).ready(function() {
                //1 seconds
                setInterval("checkOnline()", 1000);
            });
    
            //Check If Online
            function checkOnline() {
              // Handle IE and more capable browsers
              var xhr = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" );
    
              // Open new request as a HEAD to the root hostname with a random param to bust the cache
              xhr.open( "HEAD", "//" + window.location.hostname + "/?rand=" + Math.floor((1 + Math.random()) * 0x10000), false );
    
              // Issue request and handle response
              try {
                xhr.send();
                
                if (( xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304) )) {
                    console.log('ok');
                } else {
                    console.log('NG');
                }
                
              } catch (error) {
                console.log('false');
              }
            }
    
        

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!