Message passing between tabs in Chrome extensions

Contents scripts run in the context of a web page, sometimes they need to communicate with other tabs. However, they cannot directly communicate with each other.

One common method is to use the background script as a mediator:

  1. Content scripts in different tabs send messages to the background script using chrome.runtime.sendMessage().
  2. The background script receives these messages and can then forward them to the appropriate tab using chrome.tabs.sendMessage().

Sending a request from a content script looks like this:

content-script-a.js

1
2
3
4
5
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();

Next we need to add a listener for messages comming from content scripts in the background script, then forward them to the target tabs.

1
2
3
4
5
6
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
const tabs = await chrome.tabs.query({/* specify conditions to target the desired tab */});
tabs.forEach(tab => {
chrome.tabs.sendMessage(tab.id, message);
});
});

To receive the message in the desired tab, set up a runtime.onMessage event listener in the content script:

1
2
3
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
console.log("Data received:", message);
});