Exploring the Broadcast Channel API for cross-tab communication
The Broadcast Channel API enables communication between different browser windows, tabs, iframes, and web workers. It provides a simple and efficient way to synchronize data and behavior across multiple contexts of a browser for more reactive and engaging web applications.
In this article, we will explore Broadcast Channel API concepts, usage, and real-world applications. We'll also walk through a practical example of building a small application that uses the API to send messages to different tabs and windows.
Understanding the Broadcast Channel API
The Broadcast Channel API introduces a mechanism for different contexts by the same user and browser within the same origin to communicate with each other. It operates on the principle of creating a single, shared channel that multiple browser contexts can join and leave at any time.
Once joined, these contexts can send and receive messages through the channel, enabling seamless data exchange and event propagation. This mechanism eliminates the need for complex server-side communication. Here's a quick look at how you use the API.
Creating or joining a channel:
const bc = new BroadcastChannel("test_channel");
Sending a message:
bc.postMessage("This is a test message");
Receiving a message (see BroadcastChannel: message event for details):
bc.onmessage = (event) => {
console.log(event.data);
// { method: "add", note: "This is a test message" }
};
Building a Node.js application
To begin, deploy a server by following the steps in Deploying a server on Vultr section in our previous article. Next, let's proceed to access the server terminal via SSH and set up a project for our web application.
We'll be using the Nano text editor to create and edit our project files on the server.
You can check the shortcuts cheatsheet for help using Nano.
We'll also be using Uncomplicated Firewall (UFW) to control the traffic that is allowed in and out of the server.
In our application, we use Node.js to serve the index of our application and run the application using http-server
.
Any other kind of server such as Python and Apache can also be used to achieve the same.
We also use the port 8080
to enable incoming traffic only through this port using UFW.
-
Create a project directory, and navigate into it.
bashmkdir notes-app cd notes-app
-
Initialize a Node.js project.
bashnpm init -y
-
Install an HTTP server dependency.
bashnpm install http-server
-
Create an HTML file.
bashnano index.html
-
Copy and paste the code below into the
index.html
file.html<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Note-taking App</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <h1>Note-taking App</h1> <div id="noteList"></div> <div id="noteForm"> <label for="noteInput">New note</label> <input type="text" id="noteInput" placeholder="A note..." /> <button id="addNoteButton">Add Note</button> <button id="resetNoteButton">Reset Notes</button> </div> <script src="app.js"></script> </body> </html>
-
Save and exit the file.
-
Create a CSS file.
bashnano styles.css
-
Copy and paste the code below into the
styles.css
file.cssbody { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 20px; } h1 { color: #333; text-align: center; } #noteList { display: grid; row-gap: 10px; background-color: #fff; border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin-bottom: 20px; } #noteList div { background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 3px; padding: 10px; } #noteForm { display: grid; column-gap: 10px; align-items: center; grid-template-columns: max-content 1fr max-content max-content; } #noteInput { padding: 10px; border: 1px solid #ddd; border-radius: 3px; font-size: 16px; } button { padding: 10px 20px; background-color: #4caf50; color: #fff; border: none; border-radius: 3px; font-size: 16px; cursor: pointer; } button:hover { background-color: #45a049; }
-
Save and exit the file.
Implementing the Broadcast Channel API
-
In the
notes-app
directory, create a JavaScript file.bashnano app.js
-
Copy and paste the JavaScript code below into
app.js
.jsconst noteList = document.getElementById("noteList"); const noteInput = document.getElementById("noteInput"); const addNoteButton = document.getElementById("addNoteButton"); const resetNoteButton = document.getElementById("resetNoteButton"); let notes = []; function renderNotes() { noteList.innerHTML = ""; notes.forEach((note) => { const noteItem = document.createElement("div"); noteItem.textContent = note; noteList.appendChild(noteItem); }); } addNoteButton.addEventListener("click", () => { const newNote = noteInput.value.trim(); if (newNote) { notes.push(newNote); renderNotes(); noteInput.value = ""; channel.postMessage({ action: "add", note: newNote }); } }); resetNoteButton.addEventListener("click", () => { notes = []; renderNotes(); channel.postMessage({ action: "reset" }); }); const channel = new BroadcastChannel("notes-channel"); channel.addEventListener("message", (event) => { const { action, note } = event.data; if (action === "add") { notes.push(note); renderNotes(); } else if (action === "reset") { notes = []; renderNotes(); } });
-
Save and exit the file.
-
Allow incoming connections to port
8080
:bashsudo ufw allow 8080
-
Start a file server.
bashnpx http-server
-
Visit the application URL at
http://<server-ip>:8080
Now you can open two browser windows or tabs side by side. Add a note on one page in the application, and you will see that the note appears in the second tab without the need to refresh the page. Try resetting all the notes, and you will see the notes get deleted from both the tabs without refreshing.
Let's look at the code we have written in app.js
. The renderNotes
function creates an element for each note added.
The addNoteButton
function allows us to add notes in the application, and channel.postMessage
broadcasts the "add" action to other windows or tabs.
Similarly, resetNoteButton
allows us to delete all existing notes, and channel.postMessage
broadcasts the "reset action" to other windows or tabs.
At the end, a new BroadcastChannel
is created with the name 'notes-channel', allowing communication between different windows/tabs that share the same origin.
The event listener for BroadcastChannel
listens for message
events from the channel and takes action according to the input provided.
Real-world use cases and examples
- In news and media websites
- Use case: For synchronizing the reading progress of an article across multiple windows.
- Example: A user can start reading an article and continue seamlessly from the same point on another window or tab, which allows for a consistent reading experience.
- In Productivity apps
- Use case: For enabling real-time synchronization of changes in documents or files across multiple contexts.
- Example: In a collaborative text editor, changes made by one user can be broadcast to other contexts in real-time.
- On social media platforms
- Use case: For notifying users of new updates, messages, or notifications across multiple tabs or windows.
- Example: If a user has multiple tabs open for a social media platform, they can receive real-time updates in all contexts, ensuring they never miss important information.
Conclusion
In this article, we explored the concepts, usage, and practical implementation of the Broadcast Channel API. We built a basic synchronized note-taking application and learned how to use the Broadcast Channel API to build interconnected web experiences.
This is a sponsored article by Vultr. Vultr is the world's largest privately-held cloud computing platform. A favorite with developers, Vultr has served over 1.5 million customers across 185 countries with flexible, scalable, global Cloud Compute, Cloud GPU, Bare Metal, and Cloud Storage solutions. Learn more about Vultr