Communicating Between Tabs in ReactJS with the BroadcastChannel API

Let's Integrate the BroadcastChannel API into our ReactJS Projects

The BroadcastChannel API is a web platform API that allows communication between different windows, tabs, frames or iframes of the same origin.

Let's understand it with a problem statement.

If you open Whatsapp Web in one tab and then open it again in another tab, the first tab will display a message or text indicating that it's opened in another tab. In this article, we will demonstrate how to create similar functionality using the BroadcastChannel API.

Now that we have a basic understanding of the BroadcastChannel API and its potential uses, let's begin building our application.

Getting Started

Pre-requisites for local development

The prerequisite tool for local development is:

  • Node

How to create a React application?

As we are using Reactjs, below is the command to create your one.

npx create-react-app broadcast-channel-demo

broadcast-channel-demo is the name of the folder where react is created and it is the root folder of the application we are going to build.

To start the development server, run the following

cd broadcast-channel-demo
npm start or npm run start

By default, the front end will run on localhost:3000, so open the URL in your browser.

let's start the coding part,

Inside src let's create a folder with a name hooks inside that let's create a file with a name tabsWarning.js we are using hooks for this article you can use it without using hooks based on your requirement.

import { useEffect, useMemo, useState } from 'react'

export const useTabsWarning = () => {
    const broadCastChannel = useMemo(() => new BroadcastChannel("tabs_warning"), [])
    const [openedInDifferentTab, setOpenedInDifferentTab] = useState(false)

    useEffect(() => {
        broadCastChannel.postMessage("instance")
    }, [broadCastChannel])

    useEffect(() => {
        broadCastChannel.onmessage = (event) => {
            if (event.data) {
                setOpenedInDifferentTab(true)
            } else {
                setOpenedInDifferentTab(false)
            }
        };
    }, [broadCastChannel])

    return {
        setOpenedInDifferentTab,
        openedInDifferentTab
    }
}

So, we created a BroadcastChannel called “tabs_warning”. We are sending the data in our case its instance with the help postMessage method inside the useEffect.

In the second useEffect hook, we are using the onmessage method to receive a message and then updating the state of openedInDifferentTab to true. In the end, we are returning the setOpenedInDifferentTab and openedInDifferentTab functions so that they can be used elsewhere in the application. This allows us to access the current value of openedInDifferentTab and update it as needed.

Now, Inside the app.js we are ready to use the state.

import { useEffect } from 'react';
import './App.css';
import errorfavicon from "./assets/errorfavicon.ico"
import { AnotherTabWarning } from './Components/AnotherTabWarning/AnotherTabWarning';
import { useTabsWarning } from './hooks/tabsWarning';

function App() {
  const { openedInDifferentTab } = useTabsWarning()

  useEffect(() => {
    let link = document.querySelector("link[rel~='icon']");
    if (!link) {
      link = document.createElement('link');
      link.rel = 'icon';
      document.getElementsByTagName('head')[0].appendChild(link);
    }
    if (openedInDifferentTab) {
      link.href = errorfavicon
    }
  }, [openedInDifferentTab]);

  return (
    <div className="App">
      {
        openedInDifferentTab ? <AnotherTabWarning /> : <h1>Your Content Here</h1>
      }
    </div>
  );
}

export default App;

In app.js, we are performing the following tasks:

  1. Destructuring the openedInDifferentTab value from the useTabsWarning function.

  2. Using the useEffect hook to update the favicon based on the openedInDifferentTab state.

  3. Conditionally rendering a component based on the openedInDifferentTab value. If openedInDifferentTab is set to true, we will display the AnotherTabWarning component. Otherwise, we will display some other content.

The code for AnotherTabWarning.jsx is below.

import React from 'react'

export const AnotherTabWarning = () => {
    return (
        <div className='anotherTabWarning'>
            <h2>
                You cannot have this website open in multiple tabs.
                Please close them until there is only one remaining. Thanks!
            </h2>
        </div>
    )
}

Some basic CSS that you can add to your App.css file

.anotherTabWarning>h2 {
  max-width: 50%;
  background-color: #fff;
  padding: 1rem;
  border: 1px solid rgb(94, 94, 94);
  border-radius: 10px;
}

* {
  margin: 0%;
  padding: 0%;
  box-sizing: border-box;
}

.App {
  background-color: #cccccc;
  height: 100vh;
}

Conclusion

In this article, we created a React application and integrated the BroadcastChannel API. I hope that this article has provided a helpful introduction to the BroadcastChannel API and given you some ideas for how you can use it in your project(s).

Do let me know your thoughts on it.

Thanks for reading!