Accessing `window`/DOM/HTML of the webpage from the extension

Problem: extension pages (popup, options, background page in MV2, etc.) are separate from the web page and they have their own DOM, document, window, and a chrome-extension:// URL.

  • Note that service worker doesn’t have any DOM/document/window at all.
  • To inspect each context of the extension use its own devtools.

Solution: use a content script to access the web page or interact with its contents.

  • Content scripts execute in the web page, not in the extension.
  • Content scripts are isolated by default, see how to run code in page context (aka MAIN world).
  • Don’t load your content scripts in the extension page.

Method 1. Declarative


"content_scripts": [{
  "matches": ["*://**"],
  "js": ["contentScript.js"]

It will run once when the page loads. After that happens, use messaging .

Warning! It can’t send 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.

Method 2. Programmatic

  • 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:

    • "*://*" 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:

    • Use chrome.tabs.executeScript.
    • Specify sites in permissions.

Leave a Comment