0

I'm developing chrome extension. I want to send message from content.js to background.js but it's not working.

If I click on the plugin icon and click on the button I added to YouTube with the popup open, the message is sent to background.js. But I have to click the plugin icon again for the message to be sent every time.

content.js

if(location.hostname.includes("youtube.com")){
    document.addEventListener('yt-navigate-finish', process);
    document.addEventListener('DOMContentLoaded', process);

    function process() {
        if (!location.pathname.startsWith('/watch')) {
        return;
        }

        if(document.getElementById("yt-btn-music-12atv") == null) {
            var yt_btn_music = document.createElement("button");
            yt_btn_music.innerHTML = "Keşif Kuyruğu";
            yt_btn_music.id = "yt-btn-music-12atv";
        } else {yt_btn_music = document.getElementById("yt-btn-music-12atv");}

        document.getElementById("below").insertBefore(yt_btn_music, document.getElementById("below").firstChild);

        document.getElementById("yt-btn-music-12atv").addEventListener("click", function() {
            chrome.runtime.sendMessage({request: "call-func_openMusic"});
        });
    }
}

background.js

function openMusic() {
    openTab("https://www.youtube.com/" + music, "Şarkı Köşesi", "www.youtube.com");
    if(lastMusics.length >= 10) {
        lastMusics.shift();
    }
    if(lastMusics.includes(music) == false) {
        lastMusics.push(music);
    }
    setStorage();
    loadStorage();
}

chrome.runtime.onMessage.addListener(
    function(response, sender, sendResponse) {
        if (response.request === "call-func_openMusic")
            openMusic();
            sendResponse();
        }
);

manifest.json

{
  "name": "Extension",
  "description": "Şimdiye kadar yapılmış en özel akıllı tahta eklentisi...",
  "version": "3.0.0",
  "manifest_version": 3,
  "options_page": "popup.html#settings",

  "background.service_worker": {
    "scripts": ["/js/background.js"],
    "persistent": false
  },

  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": [ "/js/content.js" ],
    "css": [ "/css/content.css" ],
    "run_at": "document_end"
  }],

  "permissions": [
    "storage",
    "unlimitedStorage",
    "tabs",
    "activeTab"
  ],
    
  "icons": {
    "16": "/img/16.png",
    "48": "/img/48.png",
    "128": "/img/128.png"
  },

  "action": {
    "default_title": "Extension",
      "default_popup": "popup.html",
      "default_icon": {
        "16": "/img/16.png",
        "48": "/img/48.png",
        "128": "/img/128.png"
      }
  }
}
Ekin
  • 107
  • 1
  • 9
  • Show us openMusic and if it's not in background.js indicate where it is and how you load that other file. Also check the [background console](/a/10258029). – wOxxOm Dec 17 '22 at 18:52
  • The openMusic() function is in background.js and works correctly. But when I add alert("message") instead of openMusic function it still doesn't work – Ekin Dec 17 '22 at 19:06
  • Uncaught Error: Extension context invalidated. – Ekin Dec 17 '22 at 19:14
  • 1
    You can't use `alert` in ManifestV3 background script. Use devtools of the background script to set breakpoints and debug the code. The context error is caused by reloading of the extension, see [How to remove orphaned script](https://stackoverflow.com/a/57471345) + [Chrome extension content script re-injection after upgrade or install](https://stackoverflow.com/q/10994324) – wOxxOm Dec 17 '22 at 19:48
  • chrome.runtime.onInstalled.addListener(async () => { chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) { chrome.scripting.executeScript({ target: {tabId: tabs.id}, files: "/js/content.js", }); }); }); – Ekin Dec 17 '22 at 20:00
  • No, this won't work because the active tab may be chrome://extensions, please refer to the links I gave. – wOxxOm Dec 17 '22 at 20:01
  • Popup.html runs every time I click the button when it is opened. It doesn't work if I don't click on the plugin icon. – Ekin Dec 17 '22 at 21:15
  • The popup page is completely unrelated. Are you loading content.js or background.js in the popup? If so, it's a mistake. Make sure your question contains a full [MCVE](/help/mcve). – wOxxOm Dec 17 '22 at 22:34
  • I updated my question. Can you review my question again? – Ekin Dec 18 '22 at 06:18
  • You didn't show where you declare/load background.js. If you do it in popup.html then it's a mistake. It should be **only** in manifest.json in `background` section, see the documentation. – wOxxOm Dec 18 '22 at 08:37
  • No, content.js and popup.html have no code relationship. With content.js, the plugin detects that the page is a youtube page and adds a button to the page accordingly. When users click the button, it triggers the openMusic() function in background.js, which is used to open songs on youtube. This function is working correctly. But the problem is why the message is not sent to background.js without clicking the plugin icon. So when I open the plugin with the mouse and click the button while the plugin is open, a message is sent and the openMusic() function works. I tried but it didn't work. – Ekin Dec 19 '22 at 15:14
  • You didn't confirm whether you load background.js in popup.html or not, but judging by manifest.json you do, and that is a mistake #1. Mistake #2 is `background.service_worker` declaration, which is completely invalid. See the correct example [in this documentation article](https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/#manifest). – wOxxOm Dec 19 '22 at 17:21

1 Answers1

0

My test results contradict your claims.

I have one question. You are sending a response but not receiving it.

enter image description here

index.html

<html>
  <body>
    <button id="yt-btn-music-12atv">button</button>
  </body>
</html>

background.js

const openMusic = () => {
  console.log("openMusic");
}

chrome.runtime.onMessage.addListener(
  function (response, sender, sendResponse) {

    if (response.request === "call-func_openMusic")
      openMusic(); //the function is working
    sendResponse();
  }
);

content.js

document.getElementById("yt-btn-music-12atv").addEventListener("click", function () {
  chrome.runtime.sendMessage({ request: "call-func_openMusic" });
});

manifest.json

{
  "name": "hoge",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "content.js"
      ]
    }
  ]
}
Norio Yamamoto
  • 1,495
  • 2
  • 3
  • 10
  • Popup.html runs every time I click the button when it is opened. It doesn't work if I don't click on the plugin icon. – Ekin Dec 17 '22 at 21:16
  • Popup.html? It doesn't exist in your post. – Norio Yamamoto Dec 17 '22 at 21:40
  • I updated my question. Can you review my question again? – Ekin Dec 18 '22 at 06:18
  • Please post manifest.json, popup.html and pupup.js. – Norio Yamamoto Dec 18 '22 at 06:32
  • No, content.js and popup.html have no code relationship. With content.js, the plugin detects that the page is a youtube page and adds a button to the page accordingly. When users click the button, it triggers the openMusic() function in background.js, which is used to open songs on youtube. This function is working correctly. But the problem is why the message is not sent to background.js without clicking the plugin icon. So when I open the plugin with the mouse and click the button while the plugin is open, a message is sent and the openMusic() function works. – Ekin Dec 19 '22 at 15:15
  • I added manifest.json – Ekin Dec 19 '22 at 15:15
  • Please post popup.html and pupup.js. – Norio Yamamoto Dec 19 '22 at 21:36