chrome.scripting
- Description
Use the
chrome.scripting
API to execute script in different contexts. - Permissions
scripting
- AvailabilityChrome 88+ MV3+
Manifest
In order to use the chrome.scripting
API, you need to specify a "manifest_version"
of 3
or higher and include the "scripting"
permission in your manifest file.
{
"name": "Scripting Extension",
"manifest_version": 3,
"permissions": ["scripting"],
...
}
Usage
You can use the chrome.scripting
API to inject JavaScript and CSS into websites. This is similar to what you can do with content scripts, but by using the chrome.scripting
API, extensions can make decisions at runtime.
Injection targets
You can use the target
parameter to specify a target to inject JavaScript or CSS into.
The only required field is tabId
. By default, an injection will run in the main frame of the specified tab.
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId},
files: ['script.js'],
},
() => { ... });
To run in all frames of the specified tab, you can set the allFrames
boolean to true
.
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId, allFrames: true},
files: ['script.js'],
},
() => { ... });
You can also inject into specific frames of a tab by specifying individual frame IDs. For more information on frame IDs, see the webNavigation API.
const tabId = getTabId();
const frameIds = [frameId1, frameId2];
chrome.scripting.executeScript(
{
target: {tabId: tabId, frameIds: frameIds},
files: ['script.js'],
},
() => { ... });
You cannot specify both the frameIds
and allFrames
properties.
Injected code
Extensions can specify the code to be injected either via an external file or a runtime variable.
Files
Files are specified as strings that are paths relative to the extension's root directory. The following code will inject the file script.js
into the main frame of the tab.
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId},
files: ['script.js'],
},
() => { ... });
Runtime functions
When injecting JavaScript with scripting.executeScript()
, you can specify a function to be executed instead of a file. This function should be a function variable available to the current extension context.
function getTitle() {
return document.title;
}
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId},
func: getTitle,
},
() => { ... });
This function will be executed in the context of injection target. However, this will not carry over any of the current execution context of the function. As such, bound parameters (including the this
object) and externally-referenced variables will result in errors. For instance, the following code will not work, and will throw a ReferenceError because color
is undefined when the function executes:
const color = getUserColor();
function changeBackgroundColor() {
document.body.style.backgroundColor = color;
}
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId},
func: changeBackgroundColor,
},
() => { ... });
You can work around this by using the args
property:
const color = getUserColor();
function changeBackgroundColor(backgroundColor) {
document.body.style.backgroundColor = backgroundColor;
}
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId},
func: changeBackgroundColor,
args: [color],
},
() => { ... });
Runtime strings
If injecting CSS within a page, you can also specify a string to be used in the css
property. This option is only available for scripting.insertCSS()
; you can't execute a string using scripting.executeScript()
.
const css = 'body { background-color: red; }';
const tabId = getTabId();
chrome.scripting.insertCSS(
{
target: {tabId: tabId},
css: css,
},
() => { ... });
Handling results
The results of executing JavaScript are passed to the extension. A single result is included per-frame. The main frame is guaranteed to be the first index in the resulting array; all other frames are in a non-deterministic order.
function getTitle() {
return document.title;
}
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId, allFrames: true},
func: getTitle,
},
(injectionResults) => {
for (const frameResult of injectionResults)
console.log('Frame Title: ' + frameResult.result);
});
scripting.insertCSS()
does not return any results.
Promises
If the resulting value of the script execution is a promise, Chrome will wait for the promise to settle and return the resulting value.
async function addIframe() {
const iframe = document.createElement('iframe');
const loadComplete = new Promise((resolve) => {
iframe.addEventListener('load', resolve);
});
iframe.src = 'https://example.com';
document.body.appendChild(iframe);
await loadComplete;
return iframe.contentWindow.document.title;
}
const tabId = getTabId();
chrome.scripting.executeScript(
{
target: {tabId: tabId, allFrames: true},
func: addIframe,
},
(injectionResults) => {
for (const frameResult of injectionResults)
console.log('Iframe Title: ' + frameResult.result);
});
Summary
- Types
- Methods
Types
ContentScriptFilter
Properties
- ids
string[] optional
If specified,
getRegisteredContentScripts
will only return scripts with an id specified in this list.
CSSInjection
Properties
- css
string optional
A string containing the CSS to inject. Exactly one of
files
andcss
must be specified. - files
string[] optional
The path of the CSS files to inject, relative to the extension's root directory. Exactly one of
files
andcss
must be specified. - origin
StyleOrigin optional
The style origin for the injection. Defaults to
'AUTHOR'
. - target
Details specifying the target into which to insert the CSS.
ExecutionWorld
The JavaScript world for a script to execute within.
Type
"ISOLATED" "MAIN"
InjectionResult
Properties
- frameId
number
Chrome 90+The frame associated with the injection.
- result
any optional
The result of the script execution.
InjectionTarget
Properties
- allFrames
boolean optional
Whether the script should inject into all frames within the tab. Defaults to false. This must not be true if
frameIds
is specified. - frameIds
number[] optional
The IDs of specific frames to inject into.
- tabId
number
The ID of the tab into which to inject.
RegisteredContentScript
Properties
- allFrames
boolean optional
If specified true, it will inject into all frames, even if the frame is not the top-most frame in the tab. Each frame is checked independently for URL requirements; it will not inject into child frames if the URL requirements are not met. Defaults to false, meaning that only the top frame is matched.
- css
string[] 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.
- excludeMatches
string[] optional
Excludes pages that this content script would otherwise be injected into. See Match Patterns for more details on the syntax of these strings.
- id
string
The id of the content script, specified in the API call. Must not start with a '_' as it's reserved as a prefix for generated script IDs.
- js
string[] optional
The list of JavaScript files to be injected into matching pages. These are injected in the order they appear in this array.
- matches
string[] optional
Specifies which pages this content script will be injected into. See Match Patterns for more details on the syntax of these strings. Must be specified for
registerContentScripts
. - persistAcrossSessions
boolean optional
Specifies if this content script will persist into future sessions. The default is true.
- runAt
RunAt optional
Specifies when JavaScript files are injected into the web page. The preferred and default value is
document_idle
. - world
ExecutionWorld optional
Chrome 102+The JavaScript "world" to run the script in. Defaults to
ISOLATED
.
ScriptInjection
Properties
- args
any[] optional
Chrome 92+The arguments to curry into a provided function. This is only valid if the
func
parameter is specified. These arguments must be JSON-serializable. - files
string[] optional
The path of the JS or CSS files to inject, relative to the extension's root directory. Exactly one of
files
andfunc
must be specified. - injectImmediately
boolean optional
Chrome 102+Whether the injection should be triggered in the target as soon as possible. Note that this is not a guarantee that injection will occur prior to page load, as the page may have already loaded by the time the script reaches the target.
- target
Details specifying the target into which to inject the script.
- world
ExecutionWorld optional
Chrome 95+The JavaScript "world" to run the script in. Defaults to
ISOLATED
. - func
function optional
Chrome 92+A JavaScript function to inject. This function will be serialized, and then deserialized for injection. This means that any bound parameters and execution context will be lost. Exactly one of
files
andfunc
must be specified.The
func
function looks like:() => {...}
StyleOrigin
The origin for a style change. See style origins for more info.
Type
"AUTHOR" "USER"
Methods
executeScript
chrome.scripting.executeScript(
injection: ScriptInjection,
callback?: function,
)
Injects a script into a target context. The script will be run at document_idle
. If the script evaluates to a promise, the browser will wait for the promise to settle and return the resulting value.
Parameters
- injection
The details of the script which to inject.
- callback
function optional
The
callback
parameter looks like:(results: InjectionResult[]) => void
- results
Returns
Promise<InjectionResult[]>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
getRegisteredContentScripts
chrome.scripting.getRegisteredContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
Returns all dynamically registered content scripts for this extension that match the given filter.
Parameters
- filter
ContentScriptFilter optional
An object to filter the extension's dynamically registered scripts.
- callback
function optional
The
callback
parameter looks like:(scripts: RegisteredContentScript[]) => void
- scripts
Returns
Promise<RegisteredContentScript[]>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
insertCSS
chrome.scripting.insertCSS(
injection: CSSInjection,
callback?: function,
)
Inserts a CSS stylesheet into a target context. If multiple frames are specified, unsuccessful injections are ignored.
Parameters
- injection
The details of the styles to insert.
- callback
function optional
The
callback
parameter looks like:() => void
Returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
registerContentScripts
chrome.scripting.registerContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
Registers one or more content scripts for this extension.
Parameters
- scripts
Contains a list of scripts to be registered. If there are errors during script parsing/file validation, or if the IDs specified already exist, then no scripts are registered.
- callback
function optional
The
callback
parameter looks like:() => void
Returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
removeCSS
chrome.scripting.removeCSS(
injection: CSSInjection,
callback?: function,
)
Removes a CSS stylesheet that was previously inserted by this extension from a target context.
Parameters
- injection
The details of the styles to remove. Note that the
css
,files
, andorigin
properties must exactly match the stylesheet inserted throughinsertCSS
. Attempting to remove a non-existent stylesheet is a no-op. - callback
function optional
The
callback
parameter looks like:() => void
Returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
unregisterContentScripts
chrome.scripting.unregisterContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
Unregisters content scripts for this extension.
Parameters
- filter
ContentScriptFilter optional
If specified, only unregisters dynamic content scripts which match the filter. Otherwise, all of the extension's dynamic content scripts are unregistered.
- callback
function optional
The
callback
parameter looks like:() => void
Returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
updateContentScripts
chrome.scripting.updateContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
Updates one or more content scripts for this extension.
Parameters
- scripts
Contains a list of scripts to be updated. A property is only updated for the existing script if it is specified in this object. If there are errors during script parsing/file validation, or if the IDs specified do not correspond to a fully registered script, then no scripts are updated.
- callback
function optional
The
callback
parameter looks like:() => void
Returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.