Sharing Data Between Tabs With JavaScript

Sharing Data Between Tabs With JavaScript

The BroadcastChannel API is a Web API that allows communication between tabs, browser windows, iframes and workers, provided they are of the same origin.

Two URLs are said to be of the same origin if the have the same the protocol, port (if specified), and domain.

Consider the following URL

http://example-website.com/example/example.html

It is using the HTTP protocol, port 80 and has example-website.com as the domain.

URLOutcomeReason
http://example-website.com/test/test.htmlSame OriginOnly the path differs
http://example-website.com/example/example2.htmlSame OriginOnly the path differs
https://example-website.com/example/example.htmlFailureDifferent protocol and port
http://example-website.com:3000/example/example.htmlFailureDifferent port
http://test-website.com/example/example.htmlFailureDifferent domain

How it works

To begin communication, you create a BroadcastChannel object and then you can receive any message that is posted to it. Other frames or workers can also create channels with the same name to join in the communication. This way, you can achieve bi-directional communication without storing references to any tabs, widows or other entities.

Using the BroadcastChannel API

A client can join a channel by creating a BroadcastChannel instance. The channel gets created when the first connection is made.

const channel = new BroadcastChannel("myChannel");

Sending messages can be done via the postMessage method provided by the BroadcastChannel object which takes in any object as an argument. Note that the API is message-agnostic, leaving it to the code to interpret message types and handle them appropriately.

channel.postMessage({msg: "New site instance"});

Once a client is connected to a channel, an event will be dispatched to it every time a message is posted.

channel.onmessage = (event)=>{
    const date = event.data;
    console.log(data.msg);
};

Usage example

The BroadcastChannel API allows you to track site instances, sync data between them and so much more.

Here is an example of a chat app the works over browser windows. Pretty useless, I know. But it does a good job of showcasing the APIs functionality.

const form = document.querySelector("#form");
const messageBox = document.querySelector(".messages");
const input = document.querySelector("#msg");

const name = prompt("what is your name");

const channel = new BroadcastChannel("mychannel");

channel.onmessage = (event) => {
    const data = event.data;
    const element = document.createElement("p");
    element.textContent = `${data.name}: ${data.value}`;
    element.classList.add("other");
    messageBox.appendChild(element);
};

form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log(e);

    const element = document.createElement("p");
    element.textContent = `You: ${input.value}`;
    element.classList.add("self");
    messageBox.appendChild(element);

    const msg = { value: input.value, name };
    input.value = "";
    channel.postMessage(msg);
});

Here’s the HTML if you want to take a look

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <style>
            body {
                margin: 0;
                padding: 0;
            }

            .container {
                width: 100vw;
                height: 100vh;
                display: flex;
                flex-direction: column;
                align-items: center;
                gap: 1rem;
            }

            h1 {
                margin-bottom: 3rem;
            }

            .messages {
                width: 100%;
                max-width: 25rem;
                height: 20rem;
                border: 1px solid black;
                border-radius: 5%;
            }

            #msg {
                font-size: 1rem;
                padding: 0.25rem;
            }
            .messages {
                padding: 1rem;
            }

            .self {
                text-align: right;
            }

            .other {
                text-align: left;
            }

            form {
                width: 100%;
                max-width: 25rem;
            }

            input {
                width: 80%;
            }

            button {
                font-size: 1rem;
                padding: 0.25rem;
            }
        </style>
        <script defer src="main.js"></script>
        <title>Broadcast Channel API</title>
    </head>
    <body>
        <div class="container">
            <h1>Broadcast Channel API</h1>
            <div class="messages">
                <p class="self">Hello there, how are you doing.</p>
            </div>
            <form id="form">
                <input type="text" name="msg" id="msg" />
                <button>Send</button>
            </form>
        </div>
    </body>
</html>

Conclusion

The BroadcastChannel API allows for communication across tabs, browser and even iframes. This is a very useful feature that can come in handy. Feel free to leave a comment on the interesting ways you have use this API. Thank you for reading 🙏🏾

Stay s3cur3 lads 😎