Super simple communication between tabs, windows or iframes
Simon Ström
Posted on February 8, 2021
At the time of writing this is not supported in Safari browsers. This code example uses this polifill, 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:
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. For example the same domain name, scheme (HTTP/HTTPS), and port.
Now you need to do two things:
- Subscribe to messages
- Send messages
So to subscribe, you need an event handler for the onmessage
event:
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:
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:
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:
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:
channel.onmessage = e => {
const { data } = e
switch(e.action) {
case "ACTION_1":
doActionOne(e.payload)
return
/* etc. */
}
}
And dispatching like this
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
Cover photo by erica steeves on Unspash
Posted on February 8, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.