Messaging

or “how to get different parts of your browser extension to talk to each other”

One aspect of browser extension that can be challenging is getting the different components of your extension to talk to each other. A popup might need to access data set by a background script, or a content script might need to access information that it is not able to access directly due to browser security restrictions. In those cases, you will need to use the messaging APIs to send “messages” between the different components of your extension.

Communication between background and popup

Also applies to bundled web pages, options pages, and sidebar (Firefox)

Popup and other bundled web pages in your extensions run in a priviledged context, so you can access the full set of browser APIs directly. So, for example, you can call browser.storage.local.set() in your background script, and brower.storage.local.get() in a popup, and both scripts will be accessing the same datastore. You generally shouldn’t need to have the popup page and background script directly communicate with each other, but if the need arises you can use runtime.getBackgroundPage(), which lets you access data and call functions defined in your background script directly from the popup. You can also use the messaging APIs described in the next section, but that is generally more difficult to use.

Messaging between background and content scripts

Content scripts, which run directly in the pages the user visits, however, are not considered priviledged by the browser. This means that they cannot call most browser APIs, so if, for example, you need your content script to know the current tabs open, you can’t just call browser.tabs.query() directly. However, you can send a message to the background script, have the background script access the information, and then send a response back. You can do this using browser.runtime.sendMessage() and browser.runtime.onMessage().

This is more complicated than it should be because the different browsers want to do things slightly different ways. Our example extension implements this in a way that should work on both Chrome and Firefox—if it doesn’t please let us know! See content.js and background.js for how this is implemented.

Alternative messaging methods

There also is another way to send and recieve messages: you can open a “port” between two components with browser.runtime.connect(), and then send and recieve messages through that port. You may find code online that uses it, but it can be difficult to work with and unless you have some need that the above methods don’t satisfy I wouldn’t recommend using it.