Frontend Development 19 min read

Understanding Message Passing in Chrome Extensions

This article provides a comprehensive guide to Chrome extension message passing, covering its core concepts, common use cases such as content-to-background communication, popup interactions, broadcast messaging, as well as detailed code examples for one‑way messages, long‑lived connections, and cross‑extension communication.

FunTester
FunTester
FunTester
Understanding Message Passing in Chrome Extensions

Revisiting Message

In Chrome extension development, the message communication mechanism is a core technology that enables different components (content scripts, background scripts, popup pages, options pages, etc.) to interact and collaborate by sending and receiving messages, breaking component isolation and allowing efficient teamwork.

Usage Scenarios

Common scenarios for message communication include:

1. Content Script ↔ Background Script

Scenario: Content scripts run in an isolated environment and cannot directly access background data or functions, so they use messages to request data or trigger tasks.

Example: A content script detects a DOM change and sends a message to the background script to fetch or update data.

2. Popup ↔ Background Script

Scenario: The popup is the user interface of the extension and needs to trigger background tasks based on user actions.

Example: Clicking a button in the popup sends a message to the background script to save data or show a notification.

3. Background ↔ Multiple Content Scripts

Scenario: The background script acts as a message hub, forwarding a message from one content script to others.

Example: An update made by one content script is broadcast to all open tabs so their content stays synchronized.

4. Options Page ↔ Background Script

Scenario: Options pages allow users to modify extension settings, which must be saved and applied immediately.

Example: Changing a setting in the options page sends a message to the background script, which updates the configuration for all active components.

5. Broadcast Messaging

Scenario: When an action in one part of the extension needs to be communicated to all other parts.

Example: After a popup triggers an operation, a broadcast message notifies content scripts and the background script to maintain consistency.

Message Types

Chrome extensions support several message patterns:

One‑Way Messaging

One‑way messages are sent from a sender to a receiver without expecting an immediate response, suitable for simple notifications or triggers.

Example – Content Script → Background Script

// Listen for button clicks in the page
document.getElementById('myButton').addEventListener('click', function() {
    // Send a message to the background script
    chrome.runtime.sendMessage({ action: 'buttonClicked', data: 'Hello from content script' });
});

Background Script Listener

// Listen for messages from content scripts
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.action === 'buttonClicked') {
        console.log('Received message:', message.data);
        // Additional processing can be done here
    }
});

Long‑Lived (Two‑Way) Connections

Long‑lived connections establish a persistent port between a content script and the background script, enabling continuous bidirectional data exchange.

Content Script (content.js)

// Establish a connection to the background script
const port = chrome.runtime.connect({ name: 'content-background' });

// Listen for messages from the background script
port.onMessage.addListener(function(msg) {
    console.log('Received message from background:', msg);
});

// Send a message to the background script
port.postMessage({ action: 'init', data: 'Hello from content script' });

Background Script (background.js)

// Listen for connection requests from content scripts
chrome.runtime.onConnect.addListener(function(port) {
    console.log('Connected:', port.name);

    // Listen for messages from the content script
    port.onMessage.addListener(function(msg) {
        console.log('Received message from content script:', msg);
        if (msg.action === 'init') {
            port.postMessage({ response: 'Connection established' });
        }
    });

    // Handle disconnection
    port.onDisconnect.addListener(function() {
        console.log('Port disconnected');
    });
});

Cross‑Extension Messaging

Extensions can exchange messages with other extensions or apps by specifying the target extension ID.

Send Message to Another Extension

// Send a message to a specific extension ID
chrome.runtime.sendMessage('TARGET_EXTENSION_ID', { action: 'someAction', data: 'Hello from extension A' });

Receive Message in Target Extension

// Listen for messages from other extensions
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.action === 'someAction') {
        console.log('Received message from another extension:', message.data);
        // Process the message
    }
});

Page ↔ Content Script Messaging

Communication between a page script and a content script uses window.postMessage and event listeners.

Content Script (content.js)

// Send a message to the page script
window.postMessage({ type: 'FROM_CONTENT_SCRIPT', data: 'Hello from content script' }, '*');

Page Script (page.js)

// Listen for messages from the content script
window.addEventListener('message', function(event) {
    if (event.origin !== 'http://expected-origin.com') return; // Verify origin
    if (event.data.type === 'FROM_CONTENT_SCRIPT') {
        console.log('Received message from content script:', event.data.data);
        // Handle the message
    }
});

Message Flow Steps

Page script uses window.postMessage to send a message to the content script.

Content script receives the message via window.addEventListener , optionally forwards it to the background script with chrome.runtime.sendMessage .

Content script can reply to the page script using window.postMessage .

Page script processes the response using window.addEventListener .

Proper permission declarations in manifest.json (e.g., *://*/* , identity ) are required for cross‑extension communication, and security considerations such as origin verification should be observed.

JavaScriptFrontend DevelopmentChrome ExtensionAPIMessage Passing
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.