'How to pass input value from popup.html to current page with a chrome extension

I'm trying to grab the textarea value of the form from the popup.html file and display it on a test page with the id="demo". But for some reasons I'm not getting anything back.

Here is the error I've got: Uncaught TypeError: Cannot read property 'addEventListener' of null

Manifest V3

{
  "name": "Test Extension",
  "version": "0.01",
  "description": "-",
 "background":{
   "service_worker": "background.js"
 },
    "permissions": ["storage", "activeTab", "scripting"],
  "host_permissions": ["<all_urls>"],
  "web_accessible_resources": [{
  "resources": ["popup.js"],
  "matches": ["<all_urls>"]
}],
  "manifest_version": 3,
    "action": {
    "default_popup": "popup.html"
  }
}

Popup.html

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
        <form id="myForm">
            <textarea id="summary" name="summary" rows="6" cols="35">
            </textarea>
            <input id="submit" type="submit" value="Send" />
    </form>
    <script src="popup.js"></script>
  </body>
</html>

Popup.js

// Initialize submit
let submitButton = document.getElementById("submit");
   
// When the button is clicked, inject setFormInput into current page
submitButton.addEventListener("click", async () => {
  let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    function: setFormInput,
  });
});

// The body of this function will be executed as a content script inside the
// current page
function setFormInput() {

alert('form submitted');

var formTextarea = document.getElementById("summary").value;
document.getElementById("demo").innerText = formTextarea;
}


Solution 1:[1]

You see that error in chrome://extensions UI and it's an old error caused by your old incorrect code, it's no longer relevant. Click the clear all button there.

Note that the popup is a separate window so it has its own separate devtools and console: right-click inside the popup and select "inspect" in the menu.

The actual problem is the code you inject in the web page (setFormInput) tries to access elements from the popup page, which is a totally different page.

submitButton.addEventListener('click', async evt => {
  evt.preventDefault(); // prevents `submit` event from reloading the popup
  const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
  const text = document.getElementById('summary').value;
  await chrome.scripting.executeScript({
    target: {tabId: tab.id},
    func: (id, text) => {
      document.getElementById(id).textContent = text;
    },
    args: ['demo', text],
  });
});

P.S. There's no need for web_accessible_resources and host_permissions for this task.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1