Passing array (of objects) from popup.js to content.js in chrome extension

I have an array that is created and modified upon user input in my popup.js file, and I want to be able to send it to my content.js script upon the click of a button (in popup.html). Currently, chrome.runtime.sendMessage seems to only let me pass string (or JSON?) type messages to content.js, so I am having a hard time thinking of a solution to getting this array of objects as well as a message (something like ‘start_search’) over to content.js for execution.

For reference here is the array of objects:

var searchList = [];

Here is the function that constructs it (triggered upon user submission):

function addWord(userWord, userColor){ //append new word 
    var wordAndColorPair = {
        word: userWord,
        color: userColor,
        id: placementId.toString() //keep it as a string so it can be used for highlighted word's class
    searchList.push(wordAndColorPair); //pushing the new object with user inputs to array

Below is my attempt at using JSON.stringify:

    var jsonSearchList = JSON.stringify(searchList);
    chrome.tabs.sendMessage(, jsonSearchList);

    alert(request.message); //alerts "undefined"....

Chrome extension messages firing multiple times

I’m making my first chrome extension and noticed that messages being sent from my popup.html page were getting duplicated in my content.js message event listener. I’ve console logged “sending message” before every message send and “message received” before every message, and I don’t understand how the messages are being duplicated. I’ve also checked the chrome dev docs for sendMessage and onMessage and it specifies that the onMessage listener should only be fired once per sendMessage event.

Any help would be appreciated.


    Messaging Practice


Messaging Practice


    function(request, sender, sendResponse) {
        console.log('message received')


var messageButton = document.querySelector("#send-message");

messageButton.onclick = function() {
    chrome.tabs.query({currentWindow: true, active: true},
    function(tabs) {
            tabs[0].id, {file: "content.js"}
        console.log("sending message")
        chrome.tabs.sendMessage(tabs[0].id, "string message")


chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    conditions: [new chrome.declarativeContent.PageStateMatcher({
      pageUrl: {hostEquals: ''},
        actions: [new chrome.declarativeContent.ShowPageAction()]


    "name": "Send Messages Practice",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Simple messaging practice with the chrome api",
    "permissions": ["declarativeContent", "activeTab"],
    "background": {
        "scripts": ["background.js"],
        "persistant": true

    "page_action": {
        "default_popup": "popup.html",
        "scripts": ["content.js"],
        "matches": ["http://*/*","https://*/*"]


popup.js can`t receive messages from background Chrome extension

I try this:


receive messages from popup.js (work fine)

        chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
            if (request&&request.method&&request.action) {
                if($.isFunction(getLr()[request.method][request.action])) {
                } else {

send data to popup.js (don’t work)

    chrome.tabs.query({active: true}, function(tabs){
        for(let t in tabs) {
            chrome.tabs.sendMessage(tabs[t].id, $.extend({}, {method: method}, data), callback);


send to background script (work fine)

chrome.runtime.sendMessage({method: method, action: action, data: data}, callback);

receive from background (don’t work)

window.onload = function () {
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {

what wrong?

chrome extension message passing no response-farewell: undefined

I’m trying to message passing in a chrome extension. I follow this example (see here)- :


chrome.runtime.sendMessage({greeting: "hello"}, function(response) {


chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {


function(request, sender, sendResponse) {
    console.log( ?
        "from a content script:" + :
        "from the extension");
    if (request.greeting == "hello")
        console.log("message recive")
        sendResponse({farewell: "goodbye"});

Although I did copy-paste – the message is not sent. Error pops up:

Error in event handler for (unknown): TypeError: Cannot read property ‘farewell’ of undefined

Where is the mistake?

Is browser extension message passing private?

The title says it all – is message passing between an extension background page and an injected script that runs on the website being visited totally private?

For example, on chrome you have chrome.runtime.sendMessage() and chrome.tabs.sendMessage() as documented in

Do I need my message data to be unique in case another extension happens to use the same name for fields in the data?

If I was using window.postMessage() I would make sure my message was unique, do I need to do the same in the extension message passing?

Thanks …