Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

513
Views
Cannot send one time message from popup.js to content.js using Chrome MV3

I am building my first ever chrome extension (using MV3) and am trying to use a button in popup.html to send a tab ID from popup.js to content.js. I need for either the content.js or the background.js service worker to run a JS function that collects DOM object data from the tab and then run additional processes on it. This seems like such a simple thing to accomplish despite having spent many hours of frustration with no successful communication between scripts.

I am unsure of proper design, but many sources suggest calling chrome.tabs.query within popup.js from the button ID in order to send over the tab ID to content.js so that has been my approach. I still cannot find guidance on which (content.js or background.js) is better design practice to place processes like DOM data grabbing?.

In my approach, I keep getting this connection error in the console:

Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.

Here is my closest attempt:

manifest

{
    "manifest_version": 3,
    "name": "Data Analyzer",
    "description": "Analyzes some page data",
    "version": "1.0",
    "background": {
        "service_worker": "background.js"
    },
    "content_scripts": [
        {
            "matches": ["*://google.com/*"],
            "js": ["content.js"]
        }
    ],
    "action": {
        "default_icon": "chrome_ext.png",
        "default_popup": "popup.html"
    },
    "host_permissions": ["*://google.com/*"],
    "permissions": ["tabs", "activeTab"]
}

popup.js

document.addEventListener('DOMContentLoaded', documentEvents, false);

function myAction(input) {
  chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {"message": "start"}, function(response) {
      console.log(response.status);
    });
  });
}

function documentEvents() {    
  document.getElementById('submit_btn').addEventListener('click', 
    function() { myAction(document.getElementById('value_textbox'));
  });
}

content.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        console.log("content.js runtime function has fired");
        if(request.message === "start") {
            start();
        } 
    }
);

function start() {
    alert("Started content.js");
    
    // DOM data grab and additional processing goes here
}

The slightest bit of help would mean so much. Thanks for your time.

about 4 years ago · Juan Pablo Isaza
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!