Super simple communication between tabs, windows or iframes
Tags: webdev, javascript, programming
Published: 2021-02-08 21:29:05

> At the time of writing this is not supported in Safari browsers. This code example uses [this polifill](https://www.npmjs.com/package/broadcastchannel-polyfill), it offers partial support.

So, you have your web app running. The user opens it multiple times, in tabs or windows, or you might have several iframes on the same page, like the example below. Now you want to send data, events, or any other information across them. How do you do? Well, the answer is actually really simple...

# Enter `BrodacastChannel`

All you have to create is a `BroadcastChannel` instance:

```javascript
const channel = new BroadcastChannel('test')
```
It only needs one parameter, the name of the channel. So in any other web app or piece of code you can create a connection by creating a new channel with the same name. 

> Note that the applications must be under the same [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin). For example the same domain name, scheme (HTTP/HTTPS), and port. 

Now you need to do two things:

1. Subscribe to messages
2. Send messages

So to subscribe, you need an event handler for the `onmessage` event:

```javascript
channel.onmessage = e => {
  const { data } = e
  /* The code above is the same as:
   const data = e.data
   and uses a feature called object destructruring
  */
  console.log(data)
}
```
The `onmessage` handler will receive the event payload, and the most interesting property would be the data sent. That is what is sent from another tab, frame, iframe, or window. Now look at how we send some data:

```javascript
channel.postMessage('Hello!!!')
```

Just use the `postMessage` function on your channel. 

Now we send a simple string message to every other listener. Running the code above in one tab would look like this in another console: `Hello!!!` 

The data you can send is not limited to strings. You can send objects as well. 

To close a channel you can call the `close` method, so it stops listening and can be garbage collected:

```javascript
channel.close()
```
Below is a simple demo where you can change the background gradient in both iframes by clicking any button in either one of them:

{% codesandbox efqce%}
{% codesandbox efqce%}

# Reuse the channel
If you want to reuse the channel you might do it by sending actions across like you handle actions using a reducer/redux. Example:

```javascript

channel.onmessage = e => {
  const { data } = e

  switch(e.action) {
    case "ACTION_1":
      doActionOne(e.payload)
      return
    /* etc. */
  }
}

```
And dispatching like this
```javascript
channel.postMessage({
  type: "ACTION_1",
  payload: 42
})
```
# Summary
This is a really simple way to handle events across your application instances or different applications under the same domain. It might be session-/user information or any other data you want to broadcast. One day it might be working across all browsers without polyfill as well...

More information can be found [here in the MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API)

Cover photo by [erica steeves](https://unsplash.com/@ecees?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText) on [Unspash](https://unsplash.com/s/photos/mail?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText)