If you ever used WhatsApp Web, you might have noticed that it shows a warning if you open the same account in two different tabs.
I wondered how they did it, so I decided to research it and found out that it's actually quite simple.
The BroadcastChannel
API
The MDN documentation says that the BroadcastChannel
API is a simple way to communicate between different tabs.
Think of it as a person who gets a message from you and then tells it to another person.
Tab 1 sends a message to the BroadcastChannel
and then the BroadcastChannel
sends the message to Tab 2. Tab 2 listens to the BroadcastChannel
when it receives a message.
How to use it
We'll create a simple HTML file with two buttons.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com/3.2.4"></script>
<!-- TODO: Make your own UI framework -->
</head>
<body>
<div class="min-h-screen bg-slate-100 flex justify-center items-center">
<div class="px-8 py-4 bg-white shadow-md rounded">
<h1 class="msg text-2xl">I'm only opened in this tab 😢</h1>
<a
href="#"
class="mt-4 block text-center p-2 bg-blue-600 rounded text-white hover:bg-blue-700 text-sm"
onclick="window.opened = window.open('index.html', 'my-window')"
>
Open in another tab
</a>
<a
href="#"
class="mt-4 block text-center p-2 bg-gray-100 rounded text-gray-900 hover:bg-gray-200 text-sm"
onclick="(window.opened ? window.opened.close() : window.close()), window.opened = null"
>
Close that tab
</a>
</div>
</div>
<script>
// Your code here
</script>
</body>
</html>
The fronted uses Tailwind CSS for styling, but you can use any other CSS framework or even write your own CSS. So, the page looks like this:
Now, here's the scripting part. We first create a constant to select the .msg
element.
const msg = document.querySelector(".msg");
Then we create a broadcast channel to communicate.
const bc = new BroadcastChannel("my-channel");
We first emit the open
event that fires when the page loads.
// Send a message to the other tab
bc.postMessage("open");
Then we listen to the message
event that fires when the BroadcastChannel
receives a message.
bc.onmessage = ({ data }) => {
if (data === "open") {
// If the other tab is opened
bc.postMessage("yes"); // We send a message to the other tab
msg.textContent = "I'm opened in another tab 😄";
} else if (data === "yes") {
// If we receive a message from the other tab
msg.textContent = "I'm opened in another tab 😄";
} else {
msg.textContent = "I'm only opened in this tab 😢"; // Reset the message
}
};
Now if you open the page in two different tabs, you'll see that the message changes but, if you close one of the tabs, the message will not change. That's because we didn't emit the close
event. So, we'll add a beforeunload
event listener to the window that fires when the page is about to be closed.
// Close the channel when the tab is closed
window.addEventListener("beforeunload", () => {
bc.postMessage("close");
bc.close();
});
Now, if you open the page in two different tabs and close one of them, the message will change.
Conclusion
And, that's it! You can use this to make something like WhatsApp Web.
Here's the full code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="min-h-screen bg-slate-100 flex justify-center items-center">
<div class="px-8 py-4 bg-white shadow-md rounded">
<h1 class="msg text-2xl">I'm only opened in this tab 😢</h1>
<a
href="#"
class="mt-4 block text-center p-2 bg-blue-600 rounded text-white hover:bg-blue-700 text-sm"
onclick="window.opened = window.open('index.html', 'my-window')"
>
Open in another tab
</a>
<a
href="#"
class="mt-4 block text-center p-2 bg-gray-100 rounded text-gray-900 hover:bg-gray-200 text-sm"
onclick="(window.opened ? window.opened.close() : window.close()), window.opened = null"
>
Close that tab
</a>
</div>
</div>
<script>
const msg = document.querySelector(".msg");
// Listen for the message event
const bc = new BroadcastChannel("my-channel");
bc.onmessage = ({ data }) => {
if (data === "open") {
bc.postMessage("yes");
msg.textContent = "I'm opened in another tab 😄";
} else if (data === "yes") {
msg.textContent = "I'm opened in another tab 😄";
} else {
msg.textContent = "I'm only opened in this tab 😢";
}
};
// Send a message to the other tab
bc.postMessage("open");
// Close the channel when the tab is closed
window.addEventListener("beforeunload", () => {
bc.postMessage("close");
bc.close();
});
</script>
</body>
</html>
Also wish you a very happy new year! 🎉🎉🎉
Comments (0)