0

I simply defined the code that popup.js, background.js, and content.js communicate, but nothing is printed to the console and they don't seem to be communicating with each other. I think the message exchange is like this-

popup.js (button click) -> background.js -> content.js -> background.js -> popup.js.

manifest.json

{
  "manifest_version": 3,
  "name": "Chrome Extension",
  "version": "0.1.0",
  "description": "project",
  "icons": {
    "32": "icons/icon_32.png"
  },
  "background": {
    "service_worker": "background.js",
    "icon": "icon-34.png"
  },
  "action": {
    "default_title": "Chrome Extension",
    "default_popup": "popup.html"
  },
  "host_permissions": [
    "https://*/*"
  ],
  "permissions": [
    "storage",
    "activeTab",
    "tabs",
    "scripting"
  ]
}

popup.js

function start(){
  let link = document.getElementById('request-btn');

  if(link){
    link.addEventListener('click', function() {  
      console.log('click check'); // This code prints to the console.
      chrome.runtime.sendMessage({
        type: "popup_send"
      })
    });
  }
}

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.type === "html") {
    console.log("HTML received in popup.js: ", request.data);
    console.log('popup check');
  }
});

window.onload = start;

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.type === "content_send") {
    chrome.runtime.sendMessage({
      type: "html",
      data: "background_send"
    })
  } else if(request.type === 'popup_send'){
    chrome.runtime.sendMessage({
      type: "content_request"
    })
  }
});

content.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
  if(request.type === "content_request"){
    chrome.runtime.sendMessage({
      type: "content_send"
    })
  }
})

Only "click check" is outputted to the console when I click the button.

What's the problem?

Neha Soni
  • 3,935
  • 2
  • 10
  • 32
hyehye
  • 45
  • 5
  • You need chrome.tabs.sendMessage to send to a content script, not chrome.runtime. Also remove the background script and simply send the message directly from the popup to the content script using chrome.tabs.sendMessage + sendResponse as shown in the [documentation](https://developer.chrome.com/extensions/messaging). – wOxxOm Mar 20 '23 at 13:45

2 Answers2

2

Here is a quick cheat sheet for passing messages between chrome extension scripts. You can match your code with this and figure out the falling point.

1. popup script --> background script

popup.js

chrome.runtime.sendMessage({
  message: "popup_to_background",
  data: any_data,
})

background.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if(request.message == 'popup_to_background') {
    console.log(request.message)
  }
})

2. background script --> content script-

We should use chrome.tabs.query when sending messages from the background to any other script. (Which you are missing, I guess)

background.js

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

content.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if(request.message == "background_to_content") {
    console.log(request.message)
  }
})

3. content script -> background script

content.js

chrome.runtime.sendMessage({
  message: "content_to_background",
  data: any_data,
})

background.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if(request.message == 'content_to_background') {
    console.log(request.message)
  }
})

4. background script --> popup script

There is no way to send a message from the background to the popup because the popup does not have any tab id that's why we need to use chrome.runtime.onMessage.addListener.

background.js

chrome.runtime.sendMessage({
  message: "background_to_popup",
  data: any_data,
})

popup.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.message === "background_to_popup") {
    console.log(request.message)
  }
});

But this approach will not work if you have multiple tabs opened. For more information on this, read this answer.

Neha Soni
  • 3,935
  • 2
  • 10
  • 32
  • does not work for me: background script --> content script, I got error "Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist." – Marcin Jul 14 '23 at 12:41
0

if you dont have tabs id and you want send message from background to content you can do like this

//background.js    
chrome.runtime.sendMessage({ message: "hello from background" }, function(response) {
      console.log(response);
    });

// content.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.message === "hello from background") {
    sendResponse({ message: "hello from content script" });
  }});

these code help send mess to all extension's content scripts

hayhahy
  • 13
  • 2