DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for Detecting if the user is online with JavaScript
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Detecting if the user is online with JavaScript

Sometimes you might want to enhance your application to notify users they might have lost their internet connection.

Users might be visiting your website and receiving a cached version, so it can often appear that their internet is still working.
However, they lost a connection under the hood, and nothing new will load.

This is where it can be beneficial to show them some messages to let them know they should check their connection.

Detecting connection status

We can leverage the navigator.onLine API to detect the connection status.
This will return a boolean to indicate whether the user is online.

Note: Be aware browsers implement this differently so results may vary.

This would work great on the initial load so we could do something like this.

window.addEventListener('load', () => {
  const status = navigator.onLine;
});
Enter fullscreen mode Exit fullscreen mode

But we won't know if the network status changes after load, which is not ideal.

We can subscribe to offline and online events to listen to those specific changes.

window.addEventListener('offline', (e) => {
  console.log('offline');
});

window.addEventListener('online', (e) => {
  console.log('online');
});
Enter fullscreen mode Exit fullscreen mode

Demo

Let's set up a quick demo to demonstrate this.
We'll be using a basic text element in the center of the screen, but you can, of course, style and implement this in whatever way you like.

Note: I'm using SCSS to style this

<div class="status">
  <div class="offline-msg">You're offline ๐Ÿ˜ข</div>
  <div class="online-msg">You're connected ๐Ÿ”—</div>
</div>
Enter fullscreen mode Exit fullscreen mode

We are building this with the premise that the default is a connected state.

Let's add some basic styling to the mix.

.status {
  background: #efefef;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  div {
    padding: 1rem 2rem;
    font-size: 3rem;
    border-radius: 1rem;
    color: white;
    font-family: Roboto, 'Helvetica Neue', Arial, sans-serif;
  }
  .online-msg {
    background: green;
    display: block;
  }
  .offline-msg {
    background: red;
    display: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

This would, by default, only show the online message ever.
Let's add a condition that if the status element has an offline class, we switch the two divs.

.status {
  &.offline {
    .online-msg {
      display: none;
    }
    .offline-msg {
      display: block;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, if we add the offline class to the status div, we should see the offline message.

So how can we switch these based on the network status?

const status = document.querySelector('.status');
window.addEventListener('load', () => {
  const handleNetworkChange = () => {
    if (navigator.onLine) {
      status.classList.remove('offline');
    } else {
      status.classList.add('offline');
    }
  };

  window.addEventListener('online', handleNetworkChange);
  window.addEventListener('offline', handleNetworkChange);
});
Enter fullscreen mode Exit fullscreen mode

Yep, this piece of code does the trick!
We initialized this on the first load and created a new function to check the navigator status.

Then we add event listeners to listen to the changes so we can act based on them.
On change, it can add or remove the class name.

If we try it out, it looks like this.

JavaScript online, offline detection

Or give it a try on this CodePen.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (25)

Collapse
 
artydev profile image
artydev • Edited on

Great Chris as usual :-)

A detail, instead of

  <div class="offline-msg">You're offline ๐Ÿ˜ข</div>
  <div class="online-msg">You're connected ๐Ÿ”—</div>
Enter fullscreen mode Exit fullscreen mode

Why not

   <div class="msg" data-status="offline">You're offline ๐Ÿ˜ข</div>
   <div class="msg" data-status="online">You're connected ๐Ÿ”—</div>
Enter fullscreen mode Exit fullscreen mode

And in your CSS

.msg[data-status='offline'] {
  color: red
}

.msg[data-status='online'] {
  color: green
}
Enter fullscreen mode Exit fullscreen mode

Regards

Collapse
 
dailydevtips1 profile image
Chris Bongers

We could do that indeed, really depends on the setup, but yeah this is quite neat ๐Ÿฅณ

Collapse
 
billernet profile image
Bill๐Ÿ’ก

@artydev I would go one step further and put the status value as a class on the root html node. That way any other online/offline dependent elements can be captured. After all, the status is an aspect of the document as a whole!

html.online .msg {
    color: green
}

html.offline .msg {
    color: red
}
Enter fullscreen mode Exit fullscreen mode

Elements that are only available when online could be given the class online-only.

html.offline .online-only {
    display:none;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
artydev profile image
artydev

Thank you Bill, nice idea.
I have never thought to set a class on html tag...

Collapse
 
omril321 profile image
Omri Lavi

Hi Chris, thank you for this article! It was very interesting.
Keep in mind that relying on the browser alone may not be enough. In some scenarios the browser may falsly "think" it is connected, for example if connected to a network that has no connection to the internet. If the status is "offline" then there's no connection, but "online" does not necessarily mean a connection exists.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Yeah correct, it's very rare you'll need this much detail.
In general for specific type of applications that would need this I think this will do, but if it highly depends on the status there are alternatives indeed.

Collapse
 
jozsef88 profile image
Jozsef88

In case anyone uses react, here's a solution:

`import React, { useState, useEffect } from 'react';
import './OnlineStatus.css';

export default function OnlineStatus() {
const [status, setStatus] = useState('offline');

useEffect(() => {
    const onlineCheck = setInterval(() => {
        if (navigator.onLine) {
            setStatus('online');
        } else {
            setStatus('offline');
        }
    }, 1000)
    return () => { clearInterval(onlineCheck) };
}, [])

return (
    <div className="status">
        <div style={status === "offline" ? { display: "block" } : { display: "none" }} className="offline-msg">Offline</div>
        <div style={status === "online" ? { display: "block" } : { display: "none" }} className="online-msg">Online</div>
    </div>
)
Enter fullscreen mode Exit fullscreen mode

}`

Collapse
 
arunbohra12 profile image
Arun Bohra

Hi Chirs, you can get true even when device can't access internet. Such as using software that use virtual ethernet adapters that are always "connected." Do you know something for that as well?

Collapse
 
dailydevtips1 profile image
Chris Bongers

That's very tricky, think only server side would be able to handle those events?
Like try to reach something (ping) and see if it actually responds?

Collapse
 
fruntend profile image
fruntend

ะกongratulations ๐Ÿฅณ! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up ๐Ÿ‘

Collapse
 
dailydevtips1 profile image
Chris Bongers

Amazing! ๐Ÿฅณ

Collapse
 
qq449245884 profile image
qq449245884

Dear Chris Bongers๏ผŒmay I translate your article into Chinese?I would like to share it with more developers in China. I will give the original author and original source.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Sure thing, go for it ๐Ÿ™

Collapse
 
timhuang profile image
Timothy Huang

Very useful. Thank you.

Collapse
 
premierdan profile image
premierdan

Amazing

Collapse
 
ewenikeemmanue4 profile image
Ewenike Chukwuemeka Emmanuel๐Ÿ‘จโ€๐Ÿ’ป

This is nice..

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks! glad you enjoyed it โค๏ธ

Collapse
 
jhon1989 profile image
Jhon Janer Moreno Caceres • Edited on

Thanks for sharing

Collapse
 
uploadcare profile image
Uploadcare

This API is too unstable and usually you don't want to use it in production, because online in terms of user's browser may not be the same as online in terms of the user themselves.

There are better ways to detect offline:

  1. Long-pooling request to the server.
  2. Periodical check for a dummy image/resource without caching.
  3. Showing such a status only when the user's request fails due to unstable network.

Relying on navigator.onLine only you may scare your user. So, please do not.

Collapse
 
bobbyiliev profile image
Bobby Iliev

Very cool!

Collapse
 
lovepreetsingh profile image
Lovepreet Singh

Great one. Kindly check it out too dev.to/lovepreetsingh/oops-write-s...

Collapse
 
artydev profile image
artydev • Edited on

@lovepreetsingh

You could be interested by Learning JavaScript Design Patterns

from wellknown Addy Osmani

Regards

Collapse
 
lovepreetsingh profile image
Lovepreet Singh

Sure, I am going to check this one

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Hi Chris, thank you!

BTW, what design tool are you using for your featured image?

All DEV content is created by the community!

Hey, if you're landing here for the first time, you should know that this website is a global community of folks who blog about their experiences to help folks like you out.

Sign up now if you're curious. It's free!