Chrome Extension Content Scripts
Learn what chrome extension content scripts are and how to use them inside manifest.json and inject them dynamically with the chrome.scripting and chrome.action APIs.
Table of Contents 📖
- What are Content Scripts?
- Static Content Scripts
- Configuring Static Content Scripts
- Creating Content Script Files
- Dynamic Content Scripts
What are Content Scripts?
Content scripts are scripts that are ran in the context of web pages, allowing them to interact with the DOM. This allows them to do things such as change the style of a web page, add more content to a web page, etc. Content scripts also ran in their own private environment, isolating them from the web page and other extensions. This leads to better security and stability for extensions. However, as content scripts work in the context of a web page, there are certain Chrome APIs that they cannot interact with directly. Chrome APIs they can work with directly are the Chrome runtime, storage, and i18n APIs.
Above is an example of the power of content scripts. Here, each time we click our extension icon, the current page's body color will be turned red.
Static Content Scripts
There are multiple ways to include a content script in an extension. One way is to include them statically. Static content scripts are scripts that are declared inside the manifest.json file as an array under the content_scripts key.
{
"manifest_version": 3,
"name": "My Content Script",
"description": "Content script demonstration.",
"version": "1.0",
"content_scripts": [
{
"matches": ["https://blog.wittcode.com/*"],
"js": ["src/scripts/blog.js"]
}
]
}
The content_scripts key takes an array of content script objects. Each of these objects is a content script that can be uniquely configured to run on different domains, load different files, etc. Here, the file blog.js will be ran every time a page within the domain https://blog.wittcode.com is loaded. Simply put, static content scripts are ran every time pages provided to the matches key are loaded.
Configuring Static Content Scripts
We can further configure the objects provided to the content_scripts array. Here are a few other keys that can further configure these scripts.
- matches - Specifies the web pages that the content script is ran against. It is a required field.
- css - List of CSS files injected into the pages listed in matches
- js - List of JavaScript files injected into the pages listed in matches
- run_at - Specifies when the script is injected into the page
Creating Content Script Files
Now as a demonstration, lets create the blog.js content script file inside src/scripts and then use this script to change the body color of blog.wittcode.com to purple.
document.body.style.backgroundColor = 'purple';
If we navigate to blog.wittcode.com, we can see the background color of the document body is purple. Next, lets change the background color of blog.wittcode.com to red by using an external CSS file. First, we need to add the location of this CSS file to the content script object in our manifest.json file.
"content_scripts": [
{
"matches": ["https://blog.wittcode.com/*"],
"js": ["src/scripts/blog.js"],
"css": ["src/styles/blog.css"]
}
]
Now create a CSS class called my-background-color and add the background color red to it.
.my-background-color {
background-color: red;
}
Next, alter the JavaScript file to add this CSS class to the document body.
document.body.classList.add('my-background-color');
Now when we reload the extension and navigate to blog.wittcode.com the background color should be red.
Dynamic Content Scripts
We can also load a content script dynamically using the chrome scripting API. The Chrome scripting API is used to execute scripts in different contexts. This allows us to have more control over when our content scripts are injected as it is decided at runtime. To use the scripting API, we need to first add it to the manifest.json permissions. We also need to get permission from the host or active tab we want to run it against. Add the scripting and active tab permissions to manifest.json.
"permissions": ["scripting", "activeTab"]
Unlike content scripts, the Chrome scripting API is used inside a service worker and not in the web page. Therefore, we need to add a file as a service worker to manifest.json.
"background": {
"service_worker": "src/background/index.js"
},
Chrome service workers are an extension's central event handler. They respond to events such as closing a tab, network calls, etc. Now lets use the chrome scripting API to inject a content script when the chrome extension icon is clicked. Before doing this, we need to add the action key to manifest.json.
"action": {}
This action key will allows us to configure the extension's icon. We can use the chrome.action API to listen for a click event on the icon. When it is clicked lets execute our content script.
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["src/scripts/blog.js"]
});
});
Now when we click the chrome extension icon, our blog.js script will be injected and the background of the current tab will turn red. Note that the path supplied to files is relative to the root of the extension. The target key is the target to inject the content script into. Setting it to tab.id will inject it into the current tab.