The chrome.declarativeContent
API is an API use to take specific actions depending on the contents of the page without the use of the host_permissions
in the manifest.json
file or the help of the content scripts. Due to this the actions that can be trigged are limited;
- Show the action icon on the toolbar
- Setting another icon on the action icon.
- Registering a content script.
You can find documentation of the chrome.declarativeContent
API here: https://developer.chrome.com/docs/extensions/reference/api/declarativeContent
How to declare it in the Manifest.json
{
...
"permissions":[
"declarativeContent"
],
...
}
How to use it
To use chrome.declarativeContent
will need to define 2 items, conditions and actions. These 2 make up a rule
Conditions
These are the filters that the extensions will be looking for within the page to match. The filter options will
- Is the page bookmarked
- If the page contents a specific element.
- The url pattern of the page.
pageUrl
, css
and isBookmarked
are the only options you have for conditions
Actions
These are a list of declarative content actions that are trigged when the conditions are satisfied.
// This rule tells the extension to show the icon in the toolbar
// when the page is on google.com and there is a password input.
let rule1 = {
id: "my rule 1", // optional, will be generated if not set.
priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
css: ["input[type='password']"]
})
],
actions: [ new chrome.declarativeContent.ShowAction() ]
};
// This rule tells the extension to show the icon in the toolbar
// and register a content scripts 'content.js'
// when the page is on google.com and there is a password input.
// or if a video exists on the page
let rule2 = {
id: "my rule 2", // optional, will be generated if not set.
priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
css: ["input[type='password']"],
isBookmarked: false,
}),
new chrome.declarativeContent.PageStateMatcher({
css: ["video"]
})
],
actions: [
// show icon
new chrome.declarativeContent.ShowAction(),
// register content scripts
new chrome.declarativeContent.RequestContentScript({
css: [],
js: ["content.js"]
})
]
};
Note: As long as one of the conditions of a rule is met all the actions will fire
CSS Matching
Notice how the css
has selectors similar to the ones you would use for document.querySelector
however, they are a bit limited. You can use compound selectors like;
a
iframe.special[src^='http']
ns|*
#abcd:checked
But not complex ones like;
div p
p>span.highlight
p + ol
p::first-line
You can read the doc here for more info on the CSS Matching patterns.
Page Filter
As for pageUrl
it follows a JSON structure called UrlFilter containing, hostSuffix
, schemes
and more many. For all the options you can use for it go here: https://developer.chrome.com/docs/extensions/reference/api/events#type-UrlFilter
Adding and Remove Rules
Now that we able to define rules how do we add/remove them? We are able to do so using the event listener chrome.declarativeContent.onPageChanged
// when the extension is installed.
chrome.runtime.onInstalled.addListener(function(details) {
// ...code to define rule1 and rule2
let removeRuleIds = ['my rule 1', 'my rule 2'];
// use undefine to remove all the rules else use an array of rule ids.
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// add rules
chrome.declarativeContent.onPageChanged.addRules([rule1, rule2]);
});
});
Sample Project
We are going to make a chrome extensions that makes use of the declarativeContent
API to display the action icon and register a content script that changes the background to gold, when a webpage is from Facebook, Google, Instagram, YouTube or if the webpage as a video element in it.
You can find the source code for the project here: https://github.com/BuildChromeExtensions/chromeDeclarativeContent
We will need 3 files for this one; manifest.json
, background.js
and content.js
manifest.json
{
"name": "Declarative Content Extension",
"version": "1.0.0.0",
"manifest_version": 3,
"action": {
"default_title": "Actions for Declartive content"
},
"permissions": [
"activeTab",
"declarativeContent"
],
"background": {
"service_worker": "background.js"
}
}
content.js
The content script that will registered
document.body.style.background = 'gold';
background.js
// when the extension is installed.
chrome.runtime.onInstalled.addListener(function (details) {
const rule = {
// id: "myrule", // optional, will be generated if not set.
// priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.youtube.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.facebook.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.instagram.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
}),
],
actions: [
// show icon
new chrome.declarativeContent.ShowAction(),
// register content scripts
new chrome.declarativeContent.RequestContentScript({ js: ["content.js"] })
]
};
// use undefine to remove all the rules else use an array of rule ids.
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
console.log('Rule Removed');
// add rules
chrome.declarativeContent.onPageChanged.addRules([rule], function (rules) {
console.log('Rule Added', rules)
});
});
});
Leave a Reply