Published
Reading Time
5 min read
Creating Interactive Websites With Socket.io
Enhance your website or application with toast notifications using Socket.io.
Disclaimer: This tutorial assumes you have Node.js > 8.0 installed on your machine. I use yarn in this tutorial to install dependencies however, you can accomplish the same thing with npm.
What Are We Building and Why?
Users expect applications and websites to be interactive and give immediate feedback about tasks being performed. A common occurrence in web development is the need to perform a task in the background and at its point of completion provide the user who launched the task with feedback. This is especially useful for tasks that are long-running and so they must be offloaded to background processes or for scheduled jobs.
In this tutorial we will be building a very simple web page that provides interactive alerts or "toasts" to the user when background tasks have been performed. To accomplish this, I'm using Socket.io and Express.
Project Setup
Firstly, let's begin by setting up our project. We can do so with just a couple of files:
project/
| index.js
| index.html
| static/
| | styles.css
Next we need to add our dependencies via npm or yarn:
yarn add express nodemon socket.io
After we have our dependencies installed, we're going to start out by setting up a very simple web page where we will be sending our toast notifications. For the sake of this tutorial we're going to keep the styles and elements to a minimum to maximize comprehension.
Begin by copy pasting the following into your index.html:
<!DOCTYPE html>
<html>
<head>
<title>Socket.IO Live Toasts Example</title>
<link rel="stylesheet" type="text/css" href="static/styles.css">
</head>
<body>
<div id="container">
<h1>User Details</h1>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
<div id="socketid" class="toast"></div>
<div id="globalToast" class="toast"></div>
<div id="userToast"></div>
<button id="update">Update Settings</button>
</div>
<script src="/socket.io/socket.io.js"></script>
</body>
</html>
Next copy the following to your static/styles.css file. With these styles we are creating a very simple toast notification container. Credit where credit is due, the styles and the animation are both heavily influenced by W3 Schools Snackbar/Toast.
body {
margin: 0;
padding-bottom: 3rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.toast {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 50%;
top: 30px;
font-size: 17px;
box-shadow: 0 0.25rem 0.75rem rgba(0,0,0,.1);
}
.toast.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
Finally, inside index.js let's scaffold our Express application, import Socket.io and serve our index.html file on port 3000:
const express = require('express')
const app = express()
const http = require('http').Server(app)
const io = require('socket.io')(http)
const port = process.env.PORT || 3000
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.use('/static', express.static('static'))
At this point you can run the application locally using nodemon. Doing so will automatically restart the server any time you make changes to index.js:
nodemon index.js
Creating A Global Toast
Creating a global event in Socket.io is very simple. Let's start out by editing our index.js and creating a listener for the global notification event.
For the sake of example, let's say we have a background job that syncs user account details across systems every 6 seconds. To mimic this, we're going to set up an event that will be emitted every 6 seconds called global sync:
io.on('connection', socket => {
// Global toast
setInterval(() => { io.emit('global sync', 'Users have been synced') }, 6000)
})
In the code above, we're tapping into the connection event for Socket.io and via setInterval we're repeatedly emitting a "global sync" message to all open connections. Now that the server side of the application is emitting the event, we're going to need to configure our client, index.html, to listen for the event being emitted and take some action:
<!-- just below socket.io.js inclusion -->
<script>
var socket = io();
function animateToast(id, msg) {
var item = document.getElementById(id);
item.innerHTML = msg;
item.className = "toast show";
setTimeout(function() { item.className = item.className.replace("show", ""); }, 3000);
}
socket.on('global sync', function(msg) {
animateToast('globalToast', msg);
});
</script>
At this point, if you refresh your browser you will be able to see the global toast notification appearing every 6 seconds near the top of your screen.
Creating a User Specific Toast
We've seen how to send a toast to all of our users, but how do we specifically target a single user? To do that we need to capture the socket id when the connection is first established and then refer to just that socket when emitting our message.
For this example we'll first rig up our update settings button in index.html to emit a message to the server:
/* just below prior socket.on */
document.getElementById("update").addEventListener("click", function() {
socket.emit('user update', { active: true })
});
Then in index.js we'll set up the listener which will wait for 2 seconds and emit the user update event:
socket.on('user update', (msg) => {
setTimeout(() => {
io.to(socket.id).emit('user update', `Settings Updated for ${socket.id}`)
}, 2000)
})
Now, we'll head back into index.html and add the final listener:
socket.on('user update', function(msg) {
animateToast('userToast', msg);
});
Once your changes have been made be sure to refresh your browser for the most recent changes to take effect. Go ahead and click the Update Settings button and after 2 seconds you should receive a toast letting you know that the update was successful.
Conclusion and Source Code
While these are two relatively contrived and simple examples of using Socket.io for real time toast notifications, hopefully they will inspire you to leverage this awesome technology to create more interactive websites and applications.
You can download the final copy of the code from the GitHub repository. If you have any questions or run into issues let me know in the comments below.
Written by
Ben Durham-Kilcullen
Chief AI Officer at Ondaro · Forbes Technology Council · Founder, Kilcullen Technologies
Technology executive with a deep foundation in data science and software engineering. Dedicated to translating complex technical insights into impactful business strategies across healthcare, financial services, and enterprise software.