Return popup window response with the Broadcast Channel API
/ 5 min read
Introduction
The Broadcast Channel API is a Web API that allows communication between browser windows and tabs on the same origin.
In this blog post I will demonstrate how you can use it to communicate a response from a browser popup window back to the main window which opened the popup.
Background
In Cloudpress, I allow users to connect their Content Management System (CMS), Google Drive, and Notion accounts. Some of these applications uses OAuth 2.0 (or OpenID Connect) for authorization. When a user connects one of these applications, I initiate the OAuth 2.0 Authorization Code flow in a popup window.
Once the user has completed the authorization flow, I need to be able to access the details for the newly connected account inside the browser tab that initiated the flow. To achieve this, I use the Broadcast Channel API to communicate back from the popup window to the originating browser tab.
The following diagram describes this flow better:

- The user uses Cloudpress and wants to export a document from their Google Drive. They do not have a Google Drive connected, so they click the “Connect Account” button.
- The Google OAuth flow is initiated in a popup window and the user authorizes Cloudpress to access their Google account.
- The main application browser tab is notified that the user completed the authorization flow, and refreshes the list of available accounts using
XMLHttpRequest
(i.e. an AJAX call).
In the scenario above, I use the Broadcast Channel API to notify the main application browser tab once the authorization flow is complete and the popup window closes.
Why use a popup window?
A quick sidenote about why I chose to open a popup window for the authorization flow, rather than initiate the authorization flow inside the current browser tab:
- Cloudpress is a React application. If I navigate the user away from the current page in Cloudpress to perform the authorization flow in the same window, upon redirect, the entire React application will need to load again.
- Cloudpress has many multistep processes for exporting content. If I launch the authorization flow in the same browser tab as Cloudpress, I will interrupt the user’s current flow. Having it open in a popup window is less interrupting.
If you’re curious and want to see this in action, look at our video for connecting your Notion account to Cloudpress to get a better understanding of the flow from the user’s point of view.
Using the Broadcast Channel API
The Broadcast Channel API itself is pretty simple. The first thing you need to do is to create a channel by calling the constructor and passing the name of the channel as the name
parameter:
const bc = new BroadcastChannel('add-oauth-connection-channel');
The second step is to listen for events by connecting a handler to the onmessage
event or using the addEventListener
method.
// Register a handler in the window where you want to listen to eventsbc.onmessage = (event) => { console.log(event);};
// Alternatively, you can add an event listener by calling the addEventListener methodbc.addEventListener("message", (event) => { console.log(event);});
To broadcast a message to the channel, call the postMessage
method. This method takes any kind of Object as a parameter.
// Broadcast an event to all listeners by calling the postMessage methodbc.postMessage("This is a test message.");
What this looks like in Cloudpress
In the scenario described previously, where I use this when connecting external accounts via the OAuth 2.0 Authorization Code flow, this looks as follows:
First, in the Cloudpress frontend (a React application), I create a BroadcastChannel
instance and hook up the onmessage
event which uses the Fetch API to refresh the list of accounts. I also make sure to clean up after myself by calling the close()
method to terminate the connection to the underlying channel.
// In the Cloudpress frontend (a React application)useEffect(() => { const bc = new BroadcastChannel('add-oauth-connection-channel'); bc.onmessage = (event) => { // Do a fetch request to update the list of available accounts };
return () => { bc.close(); };});
In the Cloudpress backend, an ASP.NET Core application which handles the OAuth 2.0 Authorization Code flow, once the flow is complete, I render the following HTML response.
<!-- In the Cloudpress backend (an ASP.NET Core application) --><script> const bc = new BroadcastChannel('add-oauth-connection-channel'); bc.postMessage("[The message to send to the frontend]");
window.close();</script>
This will create a Broadcast
channel with the same name as the Cloudpress frontend and broadcasts a message to the frontend. After broadcasting the message, I close the popup by calling the Window.close()
method.
What about using window.postMessage?
Another option to do this could be to use the postMessage()
method of the Window
object. This is what I did for the longest time in Cloudpress, but I suddenly started receiving support requests from users that they were unable to connect their accounts.
Looking into this it seemed that, due to browser security settings, this approach stopped working for many users. So, I had to find a different approach and came across the Broadcast Channel API.
The Broadcast Channel API has worked reliably for me and is arguably a more modern and correct approach. It has been widely available across browsers since March 2022.
If you currently use the Window.postMessage()
event, I suggest you look into replacing it with the Broadcast Channel API.
Conclusion
In this blog post, I described how I use the Broadcast Channel API to communicate a response back from a browser popup window to the window which opened it.
This is one use specific use case, but you can use the Broadcast Channel API in a number of different scenarios where you want to communicate between different browser windows or tabs of your application.