Tab Talk: Chatting Across Tabs Like It's Tea Time! ☕️

Ever tried to get two web pages to chat like old friends at a reunion? 🥳 Well, in the vast land of web development, there are these sneaky messengers that can help. The Broadcast Channel API! 📡 If you're scratching your head thinking, 'The Broad-what Channel?', fret not! By the end of this article, you'll be introducing it to all your web pages like the ultimate matchmaker. 💘 Let's dive into the world of inter-page gossip!

What is the Broadcast Channel API?

The Broadcast Channel API is your go-to toolkit when you need streamlined communication between browsing contexts - be it windows, tabs, frames, or iframes - and workers within the same origin. It's a cohesive bridge 🌉 for inter-context chatter, ensuring that all your digital spaces stay interconnected.

Diving into Broadcast Channels: Creation & Connection

Having grasped the essence of the Broadcast Channel API, it's time to roll up our sleeves and dive into the nitty-gritty of wielding its power. Ready to embark on this digital journey? Let's delve in with a simple example.

Click on "Open a new tab" and experiment by altering the background color using the color picker. For a more noticeable transformation, select the SOLID Tab within the color picker. Watch the magic unfold: the background color will change across all open tabs of the article!

Now, you've seen the power of this Web API. I can imagine you're eager to learn how to harness its capabilities. 🪄


Let's begin by connecting to our channel *:

const bc = new BroadcastChannel("fbChannel");

*Note: If you're using React or other libraries/frameworks, I recommend declaring this constant outside of the component function to prevent it from being re-rendered, which would defeat its purpose.

Now that we've connected to our broadcast channel, let's look at the mechanics of sending and receiving messages.

Sending a Message 💌

Sending a message via the Broadcast Channel is simple. You can send any serializable data using the postMessage method. This is how it's done:

bc.postMessage({ type: 'toastNotification', message: 'hi guys' });

In this example, we're sending a message of type 'toastNotification' with a message text.

Receiving a Message 📩

The onmessage event listener is used to listen for messages on the broadcast channel:

bc.onmessage = (event) => {
    if (event.data.type === 'toastNotification') {
        // do something like:
        //toast(event.data.message)
    }
};

When a message is received, the event handler determines the message type and takes appropriate action.

Closing the Channel

When the communication is complete or when the channel is no longer required, it is important to close it to free up resources:

bc.close();

So..let's make a component to allow us to send notifications to another tab. I'm envisioning an input field and a button. When you click "send", the other tabs should receive the message and display it as a toast notification.

import React, { useState, useEffect, useCallback } from "react";
import { toast } from "react-toastify";

// Create a new BroadcastChannel named 'fbChannel'
const bc = new BroadcastChannel("fbChannel");

function BroadcastNotifier() {
   const [message, setMessage] = useState("");

   // Function to handle sending the message to the broadcast channel
   const handleSend = useCallback(() => {
      // Check if the message is not empty
      if (message.trim()) {
         // Post a new toast notification to the channel with the message
         bc.postMessage({ type: "toastNotification", message });
         setMessage(""); // Clear the input field after sending
      }
   }, [message]);

   // Set up an effect to listen to messages from the broadcast channel
   useEffect(() => {
      // Check if the broadcast channel is available
      if (bc) {
         bc.onmessage = (event) => {
            // If the message type is 'toastNotification', display the message using a toast
            if (event.data.type === "toastNotification") {
               toast(event.data.message);
            }
         };
      }

      // Cleanup function: Close the broadcast channel when the component is unmounted
      return () => {
         if (bc) {
            bc.close();
         }
      };
   }, []); // Empty dependency array to ensure this effect runs only once (on component mount and unmount)

   return (
      <>
         <input
            className="inputBroadCast"
            type="text"
            value={message}
            onChange={(e) => setMessage(e.target.value)} // Update the message state when the user types
            placeholder="Enter your message"
         />
         <button onClick={handleSend}>Send</button>
      </>
   );
}

export default BroadcastNotifier;

Result:

Tada! 🎉 Try switching to the other tabs you've opened, and you'll see the toast notification with the message you've written! As you can see, the Broadcast Channel API is a valuable and powerful tool. Think of the vast possibilities: from real-time notifications 🔈 to synchronized user experiences across tabs . For instance, if I log out of a web app and have other tabs open, even though I'm actually logged out, I should, on the frontend, log out all other tabs to avoid a scenario where the user forgets they've logged out, makes a server request, and gets an unpleasant error. 🛑 (This is just one example.) So, the next time your web pages want to gossip , remember you've got a truly awesome tool at your disposal! Happy coding 💻 , and see you at our next digital meetup! 👋👨‍💻