Content scripts

Content scripts are files that run in the context of web pages. Using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them, and pass information to their parent extension.

Understand content script capabilities

Content scripts can access the following extension APIs directly:

Content scripts are unable to access other APIs directly. But they can access them indirectly by exchanging messages with other parts of your extension.

You can also access other files in your extension from a content script, using APIs like fetch(). To do this, you need to declare them as web-accessible resources. Note that this also exposes the resources to any first-party or third-party scripts running on the same site.

Work in isolated worlds

Content scripts live in an isolated world, allowing a content script to make changes to its JavaScript environment without conflicting with the page or other extensions' content scripts.

An extension may run in a web page with code similar to the following example.

webPage.html

<html>
  <button id="mybutton">click me</button>
  <script>
    var greeting = "hello, ";
    var button = document.getElementById("mybutton");
    button.person_name = "Bob";
    button.addEventListener(
        "click", () => alert(greeting + button.person_name + "."), false);
  </script>
</html>

That extension could inject the following content script using one of the techniques outlined in the Inject scripts section.

content-script.js

var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener(
    "click", () => alert(greeting + button.person_name + "."), false);

With this change, both alerts appear in sequence when the button is clicked.

Inject scripts

Content scripts can be declared statically, declared dynamically, or programmatically injected.

Inject with static declarations

Use static content script declarations in manifest.json for scripts that should be automatically run on a well known set of pages.

Statically declared scripts are registered in the manifest under the "content_scripts" key. They can include JavaScript files, CSS files, or both. All auto-run content scripts must specify match patterns.

manifest.json

{
 "name": "My extension",
 ...
 "content_scripts": [
   {
     "matches": ["https://*.nytimes.com/*"],
     "css": ["my-styles.css"],
     "js": ["content-script.js"]
   }
 ],
 ...
}

Name Type Description
matches array of strings Required. Specifies which pages this content script will be injected into. See Match Patterns for details on the syntax of these strings and Match patterns and globs for information on how to exclude URLs.
css array of strings Optional. The list of CSS files to be injected into matching pages. These are injected in the order they appear in this array, before any DOM is constructed or displayed for the page.
js array of strings Optional. The list of JavaScript files to be injected into matching pages. Files are injected in the order they appear in this array. Each string in this list must contain a relative path to a resource in the extension's root directory. Leading slashes (`/`) are automatically trimmed.
run_at RunAt Optional. Specifies when the script should be injected into the page. Defaults to document_idle.
match_about_blank boolean Optional. Whether the script should inject into an about:blank frame where the parent or opener frame matches one of the patterns declared in matches. Defaults to false.
match_origin_as_fallback boolean Optional. Whether the script should inject in frames that were created by a matching origin, but whose URL or origin may not directly match the pattern. These include frames with different schemes, such as about:, data:, blob:, and filesystem:. See also Injecting in related frames.
world ExecutionWorld Optional. The JavaScript world for a script to execute within. Defaults to ISOLATED. See also Work in isolated worlds.

Within a given stage of the document lifecycle, content scripts declared statically in the manifest are the first to be injected, before content scripts registered in any other way. They are injected in the order in which they are specified in the manifest.

Inject with dynamic declarations

Dynamic content scripts are useful when the match patterns for content scripts are not well known or when content scripts shouldn't always be injected on known hosts.

Introduced in Chrome 96, dynamic declarations are similar to static declarations, but the content script object is registered with Chrome using methods in the chrome.scripting namespace rather than in manifest.json. The Scripting API also allows extension developers to:

Like static declarations, dynamic declarations can include JavaScript files, CSS files, or both.

service-worker.js

chrome