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;
});
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');
});
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>
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;
}
}
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;
}
}
}
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);
});
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.
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 (24)
Great Chris as usual :-)
A detail, instead of
Why not
And in your CSS
Regards
We could do that indeed, really depends on the setup, but yeah this is quite neat 🥳
@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!
Elements that are only available when online could be given the class
online-only
.Thank you Bill, nice idea.
I have never thought to set a class on html tag...
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.
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.
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');
}`
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?
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?
Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍
Amazing! 🥳
Very useful. Thank you.
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.
Sure thing, go for it 🙏
Amazing
This is nice..
Thanks! glad you enjoyed it ❤️