Content script for iframe inside extension popup or background script

Solution 1:

Use "all_frames": true in your content script declaration to inject it into an iframe:

"content_scripts": [{
    "matches": [ "http://example.com/*" ],
    "js": [ "content.js" ],
    "all_frames": true
}],

To differentiate this iframe from normal tabs you can add a dummy parameter to the URL when you create the iframe e.g. http://example.com/?foo so you can match it in manifest.json like "http://example.com/*foo*" for example.

Then you can use messaging: the content script initiates it, and the extension script registers a listener.

  • Trivial one-time sendMessage:

    content.js:

    chrome.runtime.sendMessage('test', response => {
      console.log(response);
    });
    

    popup.js (or background.js and so on):

    chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
      console.log('popup got', msg, 'from', sender);
      sendResponse('response');
    });
    
  • Long-lived port:

    content.js:

    let port = chrome.runtime.connect({name: 'test'});
    port.onMessage.addListener((msg, port) => {
      console.log(msg);
    });
    port.postMessage('from-iframe');
    

    popup.js (or background.js and so on):

    let iframePort; // in case you want to alter its behavior later in another function
    chrome.runtime.onConnect.addListener(port => {
      iframePort = port;
      port.onMessage.addListener((msg, port) => {
        console.log(msg);
      });
      port.postMessage('from-popup');
    });
    

An example of popup.html is really straightforward:

<html>
  <body>
    <iframe width="500" height="500" src="http://example.com"></iframe>
    <script src="popup.js"></script>
  </body>
</html>

Of course you can also add the iframe(s) programmatically using DOM manipulation.