I'm writing a Chrome extension and trying to overlay a <div>
over the current webpage as soon as a button is clicked in the popup.html file.
When I access the document.body.insertBefore
method from within popup.html it overlays the <div>
on the popup, rather than the current webpage.
Do I have to use messaging between background.html and popup.html in order to access the web page's DOM? I would like to do everything in popup.html, and to use jQuery too, if possible.
Your code doesn't run in the context of the web page, but in an extension context (popup, options, background script/page, etc.), which similarly to a separate browser tab has its own DOM, document
, window
, and a chrome-extension://
URL.
Solution: use a content script to access the web page or interact with its contents.
manifest.json:
"content_scripts": [{
"matches": ["*://*.example.com/*"],
"js": ["contentScript.js"]
}],
It will run automatically when the page loads. After that happens, use messaging .
⚠️ Messaging in Chrome doesn't support DOM elements, Map, Set, ArrayBuffer, classes, functions, and so on. It can only send JSON-compatible simple objects and types so you'll need to manually extract the required data and pass it as a simple array or object.
⚠️ You'll need to re-inject content scripts after reloading/installing the extension.
ManifestV3:
Use chrome.scripting.executeScript in the extension script (like the popup) to inject a content script/function into a tab on demand.
The result of this method is the last expression in the content script so it can be used to extract data. Data must be JSON-compatible, see the warning above.
Required permissions
in manifest.json:
"scripting"
- mandatory;"activeTab"
- ideal scenario, suitable for a response to a user action (usually a click on the extension icon in the toolbar). Doesn't show any permission warning when installing the extension.If ideal scenario is impossible add the allowed sites to host_permissions
in manifest.json:
"*://*.example.com/"
plus any other sites you want.
"<all_urls>"
or "*://*/"
these will put your extension in a super slow review queue in the Chrome Web Store because of broad host permissions.
ManifestV2 differences to the above:
chrome.scripting.executeScript
."activeTab"
in "permissions"
, no need for "scripting"
.