

Browser Extensions
==================



Extensions, or add-ons, can modify and enhance the capability of a browser. Extensions for Firefox are built using the WebExtensions API cross-browser technology.

 The technology for extensions in Firefox is, to a large extent, compatible with the [extension API](https://developer.chrome.com/docs/extensions/reference/) supported by Chromium-based browsers (such as Google Chrome, Microsoft Edge, Opera, Vivaldi). In most cases, extensions written for Chromium-based browsers run in Firefox with [just a few changes](https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/).



Key resources
-------------



 Guides  Whether you're just beginning or looking for more advanced advice, learn about how extensions work and use the WebExtensions API from our extensive range of [tutorials and guides](what_are_webextensions).

  References  Get comprehensive details about the methods, properties, types, and events of the [WebExtensions APIs](browser_support_for_javascript_apis) and full details about the [manifest keys](manifest.json).

  Firefox workflow  Discover how to build and publish extensions for Firefox: get the lowdown on developer tools, publication and distribution, and porting on [Extension Workshop](https://extensionworkshop.com/).

    **Note:** If you have ideas or questions or need help, you can reach us on the [community forum](https://discourse.mozilla.org/c/add-ons/35) or in the [Add-ons Room](https://matrix.to/#/!CuzZVoCbeoDHsxMCVJ:mozilla.org?via=mozilla.org&via=matrix.org&via=humanoids.be) on [Matrix](https://wiki.mozilla.org/Matrix).

 
Get started
-----------


Discover [what extensions can do](what_are_webextensions) before building [your first extension.](your_first_webextension) Learn about the [anatomy of an extension](anatomy_of_a_webextension) and get an overview of the [extension development and publication workflow, Firefox style](firefox_workflow_overview). Explore a little deeper with a comprehensive selection of [example extensions](examples) that you can run right in Firefox.

Concepts
--------


Get detailed information on the concept that underpin extensions [from an overview of the JavaScript API](api), through [content scripts,](content_scripts) [match patterns](match_patterns), [working with files](working_with_files), <internationalization>, and [content security policy](content_security_policy), to more advanced subjects such as [native messaging](native_messaging), [using the devtools APIs](extending_the_developer_tools), and [native manifests](native_manifests).

User interface
--------------


Discover all the [user interface](user_interface) components you can use in your extensions, with coding examples and tips.

How to
------


From patterns you'll regularly use such as [work with the Tabs API](working_with_the_tabs_api) and [adding a button to the toolbar](add_a_button_to_the_toolbar) to more advanced topics such as [intercepting HTTP requests](intercept_http_requests) and [working with contextual identities](work_with_contextual_identities), you'll find a range of tutorials to get you started.

Firefox workflow
----------------



When you are ready to create your extension for Firefox or port your Chrome extension, head over to [Extension Workshop](https://extensionworkshop.com/). It has details on:

 * The Firefox workflow, such as [temporarily installing extensions during development](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/), [debugging](https://extensionworkshop.com/documentation/develop/debugging/), [request the right permissions](https://extensionworkshop.com/documentation/develop/request-the-right-permissions/), and more.
* The [web-ext](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/) developer tool.
* [Porting a Google Chrome extension](https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/), [differences between desktop and Android](https://extensionworkshop.com/documentation/develop/differences-between-desktop-and-android-extensions/), and more.
* [Publishing and distribution overview](https://extensionworkshop.com/documentation/publish/), [promoting your extension](https://extensionworkshop.com/documentation/publish/promoting-your-extension/), the [extension lifecycle best practices](https://extensionworkshop.com/documentation/manage/), and more.


Reference
---------


### JavaScript APIs


Get comprehensive details about the methods, properties, types, and events for all the [JavaScript APIs](api). There is also detailed information about the compatibility of each API with the major browsers. Most reference pages also include coding examples and links to the extension examples that use the API.

### Manifest keys


Get full details about the [manifest keys](manifest.json), including all their properties and settings. There's also detailed information on the [compatibility](browser_compatibility_for_manifest.json) of each key with the major browsers.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions>

What are extensions?
====================



 **Note:** If you are already familiar with the basic concepts of browser extensions, skip this section to [see how extension files are put together](anatomy_of_a_webextension). Then, use the [reference documentation](../webextensions#reference) to start building your extension. Visit [Firefox Extension Workshop](https://extensionworkshop.com/?utm_source=developer.mozilla.org&utm_medium=documentation&utm_campaign=your-first-extension) to learn more about the workflow for testing, publishing, and extensions for Firefox.

  An extension adds features and functions to a browser. It's created using familiar web-based technologies — HTML, CSS, and JavaScript. It can take advantage of the same web APIs as JavaScript on a web page, but an extension also has access to its own set of JavaScript APIs. This means that you can do a lot more in an extension than you can with code in a web page. Here are just a few examples of the things you can do:

 **Enhance or complement a website**: Use an add-on to deliver additional in-browser features or information from your website. Allow users to collect details from pages they visit to enhance the service you offer.

  ![Amazon add-on example providing price comparison features] 

 Examples: [Amazon Assistant for Firefox](https://addons.mozilla.org/en-US/firefox/addon/amazon-browser-bar/), [OneNote Web Clipper](https://addons.mozilla.org/en-US/firefox/addon/onenote-clipper/), and [Grammarly for Firefox](https://addons.mozilla.org/en-US/firefox/addon/grammarly-1/).

 **Let users show their personality**: Browser extensions can manipulate the content of web pages; for example, letting users add their favorite logo or picture as a background to every page they visit. Extensions may also enable users to update the look of the Firefox UI, the same way standalone [theme add-ons](https://extensionworkshop.com/documentation/themes/) do.

  ![My Web New Tab add-on showing a Batman theme] 

 Examples: [MyWeb New Tab](https://chrome.google.com/webstore/detail/myweb-new-tab/cnbiadnhebmicjcbpgajglfemclnlagh), [Tabliss](https://addons.mozilla.org/en-US/firefox/addon/tabliss/), and [VivaldiFox](https://addons.mozilla.org/en-US/firefox/addon/vivaldifox/).

 **Add or remove content from web pages**: You might want to help users block intrusive ads from web pages, provide access to a travel guide whenever a country or city is mentioned in a web page, or reformat page content to offer a consistent reading experience. With the ability to access and update both a page's HTML and CSS, extensions can help users see the web the way they want to.

  ![uBlock origin add-on example with blocked tracker statistics] 

 Examples: [uBlock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/), [Reader](https://addons.mozilla.org/en-US/firefox/addon/reader/), and [Toolbox for Google Play Store™](https://addons.mozilla.org/en-US/firefox/addon/toolbox-google-play-store/).

 **Add tools and new browsing features**: Add new features to a taskboard, or generate QR code images from URLs, hyperlinks, or page text. With flexible UI options and the power of the [WebExtensions APIs](index) you can easily add new features to a browser. And, you can enhance almost any website's features or functionality, it doesn't have to be your website.

  ![QR code generator add-on example] 

 Examples: [Swimlanes for Trello](https://addons.mozilla.org/en-US/firefox/addon/swimlanes-for-trello/) and [Tomato Clock](https://addons.mozilla.org/en-US/firefox/addon/tomato-clock/).

 **Games**: Offer traditional computer games with off-line play features, or explore new game possibilities; for example, by incorporating gameplay into everyday browsing.

 Examples: [Solitaire Card Game](https://addons.mozilla.org/en-US/firefox/addon/solitaire-spider-freecell/), and [2048 Prime](https://addons.mozilla.org/en-US/firefox/addon/2048-prime/).

 **Add development tools**: You may provide web development tools as your business or have developed a useful technique or approach to web development that you want to share. Either way, you can enhance the built-in Firefox developer tools by adding a new tab to the developer toolbar.

  ![Axe accessibility testing addon example] 

 Examples: [Web Developer](https://addons.mozilla.org/en-US/firefox/addon/web-developer/), [Web React Developer Tools](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/), and [aXe Developer Tools](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/).

 Extensions for Firefox are built using the [WebExtensions APIs](index), a cross-browser system for developing extensions. To a large extent, the API is compatible with the [extension API](https://developer.chrome.com/docs/extensions/reference/) supported by Google Chrome and Opera. Extensions written for these browsers will in most cases run in Firefox or Microsoft Edge with just a few [changes](https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/). The API is also fully compatible with [multiprocess Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Multiprocess_Firefox).

 If you have ideas or questions, or need help [migrating a legacy add-on to WebExtensions APIs](https://extensionworkshop.com/documentation/develop/porting-a-legacy-firefox-extension/), you can reach us on the [Add-ons Discourse](https://discourse.mozilla.org/c/add-ons/35) or in the [Add-ons room](#) on [Matrix](https://wiki.mozilla.org/Matrix).



What's next?
------------


* Walk through the development of a simple extension in [Your first extension](your_first_webextension).
* Learn about the structure of an extension in [Anatomy of an extension](anatomy_of_a_webextension).
* Try out some example extensions in [Example extensions](examples).


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/What_are_WebExtensions>

Your first extension
====================



 **Note:** If you're familiar with the basic concepts of browser extensions, skip this section to [see how extension files are put together](anatomy_of_a_webextension). Then, use the [reference documentation](../webextensions#reference) to start building your extension. Visit [Firefox Extension Workshop](https://extensionworkshop.com/?utm_source=developer.mozilla.org&utm_medium=documentation&utm_campaign=your-first-extension) to learn more about the workflow for testing, publishing, and extensions for Firefox.

  This article walks through creating an extension for Firefox, from start to finish. The extension adds a red border to any pages loaded from "`mozilla.org`" or any of its subdomains.

 The source code for this example is on GitHub: <https://github.com/mdn/webextensions-examples/tree/master/borderify>.



Writing the extension
---------------------



In a suitable location, such as in the `Documents` directory, create a new directory called `borderify` and navigate to it. You can do this using your computer's file explorer or [command line terminal](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line). Understanding how to use the command line terminal is a handy skill, as it helps with your more advanced extension development. Using the terminal, you create the directory like this:

 
```
mkdir borderify
cd borderify

```

### manifest.json



Using a suitable [text editor](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/Available_text_editors), create a new file called "manifest.json" directly under the "borderify" directory. Give it the following contents:

 
```
{

  "manifest\_version": 2,
  "name": "Borderify",
  "version": "1.0",

  "description": "Adds a red border to all webpages matching mozilla.org.",

  "icons": {
    "48": "icons/border-48.png"
  },

  "content\_scripts": [
    {
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["borderify.js"]
    }
  ]

}

```
 * The first three keys: [`manifest_version`](manifest.json/manifest_version), [`name`](manifest.json/name), and [`version`](manifest.json/version), are mandatory and contain basic metadata for the extension.
* [`description`](manifest.json/description) is optional, but recommended: it's displayed in the Add-ons Manager.
* [`icons`](manifest.json/icons) is optional, but recommended: it allows you to specify an icon for the extension, that will be shown in the Add-ons Manager.

 The most interesting key here is [`content_scripts`](manifest.json/content_scripts), which tells Firefox to load a script into Web pages whose URL matches a specific pattern. In this case, we're asking Firefox to load a script called "borderify.js" into all HTTP or HTTPS pages served from "mozilla.org" or any of its subdomains.

 * [Learn more about content scripts.](content_scripts)
* [Learn more about match patterns](match_patterns).

  **Warning:** [In some situations you need to specify an ID for your extension](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/#when_do_you_need_an_add-on_id). If you do need to specify an add-on ID, include the [`browser_specific_settings`](manifest.json/browser_specific_settings) key in `manifest.json` and set its `gecko.id` property:

 
```
"browser\_specific\_settings": {
  "gecko": {
    "id": "borderify@example.com"
  }
}

```
 
### icons/border-48.png



The extension should have an icon. This will be shown next to the extension's listing in the Add-ons Manager. Our manifest.json promised that we would have an icon at "icons/border-48.png".

 Create the "icons" directory directly under the "borderify" directory. Save an icon there named "border-48.png". You could use [the one from our example](https://raw.githubusercontent.com/mdn/webextensions-examples/master/borderify/icons/border-48.png), which is taken from the Google Material Design iconset, and is used under the terms of the [Creative Commons Attribution-ShareAlike](https://creativecommons.org/licenses/by-sa/3.0/) license.

 If you choose to supply your own icon, It should be 48x48 pixels. You could also supply a 96x96 pixel icon, for high-resolution displays, and if you do this it will be specified as the `96` property of the `icons` object in manifest.json:

 
```
"icons": {
  "48": "icons/border-48.png",
  "96": "icons/border-96.png"
}

```
 Alternatively, you could supply an SVG file here, and it will be scaled correctly. (Though: if you're using SVG and your icon includes text, you may want to use your SVG editor's "convert to path" tool to flatten the text, so that it scales with a consistent size/position.)

 * [Learn more about specifying icons.](manifest.json/icons)


### borderify.js



Finally, create a file called "borderify.js" directly under the "borderify" directory. Give it this content:

 
```
document.body.style.border = "5px solid red";

```
 This script will be loaded into the pages that match the pattern given in the `content_scripts` manifest.json key. The script has direct access to the document, just like scripts loaded by the page itself.

 * [Learn more about content scripts.](content_scripts)


Trying it out
-------------



First, double check that you have the right files in the right places:

 
```
borderify/
    icons/
        border-48.png
    borderify.js
    manifest.json

```

### Installing



In Firefox: Open the [about:debugging](https://firefox-source-docs.mozilla.org/devtools-user/about_colon_debugging/index.html) page, click the This Firefox option, click the Load Temporary Add-on button, then select any file in your extension's directory.

 The extension now installs, and remains installed until you restart Firefox.

 Alternatively, you can run the extension from the command line using the [web-ext](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/) tool.


### Testing



 **Note:** By default [extensions don't work in private browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing). If you want to test this extension in private browsing open "`about:addons`", click on the extension, and select the Allow radio button for Run in Private Windows.

  Now visit a page under "`https://www.mozilla.org/en-US/`", and you should see the red border round the page.

  ![Border displayed on mozilla.org](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension/border_on_mozilla_org.png) 

  **Note:** Don't try it on "`addons.mozilla.org`", though! Content scripts are currently blocked on that domain.

  Try experimenting a bit. Edit the content script to change the color of the border, or do something else to the page content. Save the content script, then reload the extension's files by clicking the Reload button in "`about:debugging`". You can see the changes right away.

 * [Learn more about loading extensions](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/)


Packaging and publishing
------------------------


For other people to use your extension, you need to package it and submit it to Mozilla for signing. To learn more about that, see ["Publishing your extension"](https://extensionworkshop.com/documentation/publish/package-your-extension/).

What's next?
------------



Now you've had an introduction to the process of developing a WebExtension for Firefox:

 * [write a more complex extension](your_second_webextension)
* [read more about the anatomy of an extension](anatomy_of_a_webextension)
* [explore the extension examples](examples)
* [find out what you need to develop, test, and publish your extension](what_next_)
* [take your learning further](what_next_#continue_your_learning_experience).




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension>

Anatomy of an extension
=======================


An extension consists of a collection of files, packaged for distribution and installation. In this article, we will quickly go through the files that might be present in an extension.


manifest.json
-------------



This is the only file that must be present in every extension. It contains basic metadata such as its name, version, and the permissions it requires. It also provides pointers to other files in the extension.

 The manifest can also contain pointers to several other types of files:

  [Background scripts](#background_scripts_2)  Scripts that respond to browser events.

  Icons  For the extension and any buttons it might define.

  [Sidebars, popups, and options pages](#sidebars_popups_and_options_pages_2)  HTML documents that provide content for various user interface components.

  [Content scripts](#content_scripts_2)  JavaScript included with your extension, that you will inject into web pages.

  [Web-accessible resources](#web_accessible_resources)  Make packaged content accessible to web pages and content scripts.

    ![The components of a web extension. The manifest.JSON must be present in all extensions. It provides pointers to background pages, content scripts, browser actions, page actions, options pages, and web accessible resources. Background pages consist of HTML and JS. Content scripts consist of JS and CSS. The user clicks on an icon to trigger browser actions and page actions and the resulting pop-up consists of HTML, CSS, and JS. Options pages consist of HTML, CSS, and JS.] 

 See the [`manifest.json`](manifest.json) reference page for all the details.

 Along with those already listed in the manifest, an extension may also include additional [Extension pages](user_interface/extension_pages) and supporting files.


Background scripts
------------------



Extensions often need to respond to events that occur in the browser independently of the lifetime of any particular web page or browser window. That is what background scripts are for.

 Background scripts can be persistent or non-persistent. Persistent background scripts load as soon as the extension loads and stay loaded until the extension is disabled or uninstalled. This background script behavior is only available in Manifest V2. Non-persistent background scripts load when needed to respond to an event and unload when they become idle. This background script behavior is an option in Manifest V2 and the only background script behavior available in Manifest V3.

 You can use any of the [WebExtension APIs](api) in the script, if you have requested the necessary [permissions](manifest.json/permissions).

 See the [background scripts](background_scripts) article to learn more.


Sidebars, popups, and options pages
-----------------------------------



Your extension can include various user interface components whose content is defined using an HTML document:

  [Sidebar](user_interface/sidebars)  A pane that is displayed at the left-hand side of the browser window, next to the web page.

  [Popup](user_interface/popups)  A dialog that you can display when the user clicks on a [toolbar button](user_interface/browser_action) or [address bar button](user_interface/page_actions)

  [Options](user_interface/options_pages)  A page that's shown when the user accesses your add-on's preferences in the browser's native add-ons manager.

   For each of these components, you create an HTML file and point to it using a specific property in [`manifest.json`](manifest.json). The HTML file can include CSS and JavaScript files, just like a normal web page.

 All of these are a type of [Extension pages](user_interface/extension_pages). Unlike a normal web page, your JavaScript can use all the same privileged WebExtension APIs as your background script.


Extension pages
---------------



You can also include HTML documents in your extension which are not attached to some predefined user interface component. Unlike the documents you might provide for sidebars, popups, or options pages, these don't have an entry in `manifest.json`. However, they do also get access to all the same privileged WebExtension APIs as your background script.

 You'd typically load a page like this using [`windows.create()`](api/windows/create) or [`tabs.create()`](api/tabs/create).

 See [Extension pages](user_interface/extension_pages) to learn more.


Content scripts
---------------



Use content scripts to access and manipulate web pages. Content scripts are loaded into web pages and run in the context of that particular page.

 Content scripts are extension-provided scripts which run in the context of a web page; this differs from scripts which are loaded by the page itself, including those which are provided in [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) elements within the page.

 Content scripts can see and manipulate the page's DOM, just like normal scripts loaded by the page.

 Unlike normal page scripts, content scripts can:

 * Make cross-domain XHR requests.
* Use a small subset of the [WebExtension APIs](api).
* [Exchange messages with their background scripts](content_scripts#communicating_with_background_scripts) and can in this way indirectly access all the WebExtension APIs.

 Content scripts cannot directly access normal page scripts but can exchange messages with them using the standard [`window.postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API.

 Usually, when we talk about content scripts, we are referring to JavaScript, but you can inject CSS into web pages using the same mechanism.

 See the [content scripts](content_scripts) article to learn more.


Web accessible resources
------------------------



Web accessible resources are resources—such as images, HTML, CSS, and JavaScript—that you include in the extension and want to make accessible to content scripts and page scripts. Resources which are made web-accessible can be referenced by page scripts and content scripts using a special URI scheme.

 For example, if a content script wants to insert some images into web pages, you could include them in the extension and make them web accessible. Then the content script could create and append [`img`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) tags which reference the images via the `src` attribute.

 To learn more, see the documentation for the [`"web_accessible_resources"`](manifest.json/web_accessible_resources) `manifest.json` key.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension>

manifest.json
=============



 **Note:** This article describes manifest.json for web extensions. If you are looking for information about the manifest.json in PWAs, check out the [Web App Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) article.

  The `manifest.json` file is the only file that every extension using WebExtension APIs must contain.

 Using `manifest.json`, you specify basic metadata about your extension such as the name and version, and can also specify aspects of your extension's functionality (such as background scripts, content scripts, and browser actions).

 It is a [JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON)-formatted file, with one exception: it is allowed to contain "`//`"-style comments.



List of manifest.json keys
--------------------------



These are the `manifest.json` keys; these keys are available in Manifest V2 and above unless otherwise noted:

 * [action](manifest.json/action) (Manifest V3 and above)
* [author](manifest.json/author)
* [background](manifest.json/background)
* [browser\_action](manifest.json/browser_action) (Manifest V2 only)
* [browser\_specific\_settings](manifest.json/browser_specific_settings)
* [chrome\_settings\_overrides](manifest.json/chrome_settings_overrides)
* [chrome\_url\_overrides](manifest.json/chrome_url_overrides)
* [commands](manifest.json/commands)
* [content\_scripts](manifest.json/content_scripts)
* [content\_security\_policy](manifest.json/content_security_policy)
* [declarative\_net\_request](manifest.json/declarative_net_request)
* [default\_locale](manifest.json/default_locale)
* [description](manifest.json/description)
* [developer](manifest.json/developer)
* [devtools\_page](manifest.json/devtools_page)
* [dictionaries](manifest.json/dictionaries)
* [externally\_connectable](manifest.json/externally_connectable)
* [homepage\_url](manifest.json/homepage_url)
* [host\_permissions](manifest.json/host_permissions) (Manifest V3 and above)
* [icons](manifest.json/icons)
* [incognito](manifest.json/incognito)
* [manifest\_version](manifest.json/manifest_version)
* [name](manifest.json/name)
* [offline\_enabled](manifest.json/offline_enabled)
* [omnibox](manifest.json/omnibox)
* [optional\_permissions](manifest.json/optional_permissions)
* [options\_page](manifest.json/options_page)
* [options\_ui](manifest.json/options_ui)
* [page\_action](manifest.json/page_action) (Manifest V2 only in Chrome)
* [permissions](manifest.json/permissions)
* [protocol\_handlers](manifest.json/protocol_handlers)
* [short\_name](manifest.json/short_name)
* [sidebar\_action](manifest.json/sidebar_action)
* [storage](manifest.json/storage)
* [theme](manifest.json/theme)
* [theme\_experiment](manifest.json/theme_experiment)
* [user\_scripts](manifest.json/user_scripts) (Manifest V2 only)
* [version](manifest.json/version)
* [version\_name](manifest.json/version_name)
* [web\_accessible\_resources](manifest.json/web_accessible_resources)


### Notes about manifest.json keys


* `"manifest_version"`, `"version"`, and `"name"` are the only mandatory keys.
* `"default_locale"` must be present if the "`_locales`" directory is present, and must be absent otherwise.
* `"browser_specific_settings"` is not supported in Google Chrome.
### Accessing manifest.json keys at runtime



You can access your extension's manifest from the extension's JavaScript using the [`runtime.getManifest()`](api/runtime/getmanifest) function:

 
```
browser.runtime.getManifest().version;

```

Example
-------



The block below shows the basic syntax for some common manifest keys.

  **Note:** This is not intended to be used as a copy-paste-ready example. Selecting the keys you'll need depends on the extension you are developing.

  For complete example extensions, see [Example extensions](examples).

 
```
{
  "browser\_specific\_settings": {
    "gecko": {
      "id": "addon@example.com",
      "strict\_min\_version": "42.0"
    }
  },

  "background": {
    "scripts": ["jquery.js", "my-background.js"],
  },

  "browser\_action": {
    "default\_icon": {
      "19": "button/geo-19.png",
      "38": "button/geo-38.png"
    },
    "default\_title": "Whereami?",
    "default\_popup": "popup/geo.html"
  },

  "commands": {
    "toggle-feature": {
      "suggested\_key": {
        "default": "Ctrl+Shift+Y",
        "linux": "Ctrl+Shift+U"
      },
      "description": "Send a 'toggle-feature' event"
    }
  },

  "content\_security\_policy": "script-src 'self' https://example.com; object-src 'self'",

  "content\_scripts": [
    {
      "exclude\_matches": ["\*://developer.mozilla.org/\*"],
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["borderify.js"]
    }
  ],

  "default\_locale": "en",

  "description": "…",

  "icons": {
    "48": "icon.png",
    "96": "icon@2x.png"
  },

  "manifest\_version": 2,

  "name": "…",

  "page\_action": {
    "default\_icon": {
      "19": "button/geo-19.png",
      "38": "button/geo-38.png"
    },
    "default\_title": "Whereami?",
    "default\_popup": "popup/geo.html"
  },

  "permissions": ["webNavigation"],

  "version": "0.1",

  "user\_scripts": {
    "api\_script": "apiscript.js",
  },

  "web\_accessible\_resources": ["images/my-image.png"]
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `action` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109 | ? | 15.4 | ? |
| `author` | Yes | 14This property is required. | 52 | ? | Yes | 14Not displayed in Safari Extensions settings. | ? | ? | 52 | ? | 15Not displayed in Safari Extensions settings. | ? |
| `background` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `browser_action` | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14Available for use in Manifest V2 only. | 48Available for use in Manifest V2 only. | ? | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? | ? | 55Available for use in Manifest V2 only. | ? | 15["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? |
| `browser_specific_settings` | No | 15–79 | 42Before Firefox 48, this property was required. | ? | No | 14Supports `strict_min_version` and `strict_max_version` in a `safari` block. | ? | ? | 42Before Firefox 48, this property was required. | ? | 15Supports `strict_min_version` and `strict_max_version` in a `safari` block. | ? |
| `chrome_settings_overrides` | Yes | 79 | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `chrome_url_overrides` | Yes | 79 | 54 | ? | No | 1514.1 | ? | ? | No | ? | 15 | ? |
| `commands` | Yes | 79 | 48 | ? | Yes | 14Changing the keyboard shortcut for a command is not supported. | ? | ? | No | ? | 15Changing the keyboard shortcut for a command is not supported. | ? |
| `content_scripts` | YesContent scripts are not applied to tabs already open when the extension is loaded. | 14 | 48 | ? | YesContent scripts are not applied to tabs already open when the extension is loaded. | 14Content scripts are not applied to tabs until the user grants permission via the extension's access popover in the toolbar. | ? | ? | 48 | ? | 15Content scripts are not applied to tabs until the user grants permission via the extension's access alert. | ? |
| `content_security_policy` | YesUntil Chrome 110, the `object-src` directive was required with a secure source. From Chrome 111, the `object-src` directive is optional. | YesUntil Edge 110, the `object-src` directive was required with a secure source. From Edge 111, the `object-src` directive is optional. | 48["Firefox does not support 'http://127.0.0.1' or 'http://localhost' as script sources: they must be served over HTTPS.", "Until Firefox 105, the `object-src` directive was required with a secure source. From Firefox 106, the `object-src` directive is optional."] | ? | YesUntil Opera 96, the `object-src` directive was required with a secure source. From Opera 97, the `object-src` directive is optional. | 14There is no requirement to include the `object-src` directive. | ? | ? | No | ? | 15There is no requirement to include the `object-src` directive. | ? |
| `declarative_net_request` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `default_locale` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `description` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `developer` | No | No | 52 | ? | Yes | No | ? | ? | 52 | ? | No | ? |
| `devtools_page` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `externally_connectable` | Yes | 79 | NoSee [bug 1319168](https://bugzil.la/1319168). | ? | Yes | 15.4Safari only supports the `matches` property. | ? | ? | No | ? | 15.4Safari only supports the `matches` property. | ? |
| `homepage_url` | Yes | 79 | 48 | ? | Yes | 14Not displayed in Safari Extensions settings. | ? | ? | 48 | ? | 15Not displayed in Safari Extensions settings. | ? |
| `host_permissions` | 88Available for use in Manifest V3 or later. | 88Available for use in Manifest V3 or later. | 109Available for use in Manifest V3 or later. | ? | 74Available for use in Manifest V3 or later. | 15.4Available for use in Manifest V3 or later. | ? | ? | 109Available for use in Manifest V3 or later. | ? | 15.4Available for use in Manifest V3 or later. | ? |
| `icons` | Yes | Yes | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `incognito` | Yes | ≤18 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `manifest_version` | 4 | 14 | 48 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `name` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `offline_enabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `omnibox` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `optional_permissions` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `options_page` | Yes | 14 | No | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `options_ui` | 40 | 79 | 48 | ? | 27 | 14 | ? | ? | 57 | ? | 15 | ? |
| `page_action` | Yes["Since Chrome 49, page actions are displayed on the toolbar, rather than in the address bar.", "If an extension defines a page action, it is not allowed to define a browser action as well."] | 14 | 48 | ? | YesIf an extension defines a page action, it is not allowed to define a browser action as well. | 14If an extension defines a page action, it is not allowed to define a browser action as well. | ? | ? | Yes | ? | 15If an extension defines a page action, it is not allowed to define a browser action as well. | ? |
| `permissions` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `protocol_handlers` | No | No | 54 | ? | No | No | ? | ? | 54 | ? | No | ? |
| `short_name` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `sidebar_action` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `storage` | Yes | 79 | No | ? | No | 14 | ? | ? | No | ? | 15 | ? |
| `theme` | Yes | 79 | 55 | ? | No | No | ? | ? | Yes | ? | No | ? |
| `theme_experiment` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `user_scripts` | Yes | 79 | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |
| `version` | YesValid Chrome versions are a subset of valid Firefox versions. | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `version_name` | Yes | 79 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `web_accessible_resources` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


For a full overview of all manifest keys and their sub-keys, see the [full manifest.json browser compatibility table](browser_compatibility_for_manifest.json).


See also
--------


[`permissions`](api/permissions) JavaScript API



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json>

Working with files
==================



Your browser extension may need to work with files to deliver its full functionality. This article looks at the five mechanisms you have for handling files:

 * Downloading files to the user's selected download folder.
* Opening files using a file picker on a web page.
* Opening files using drag and drop onto a web page.
* Storing files or blobs locally with IndexedDB using the idb-file-storage library.
* Passing files to a native application on the user's computer.

 For each of these mechanisms, we introduce their use with references to the relevant API documentation, guides, and any examples that show how to use the API.



Download files using the downloads API
--------------------------------------



This mechanism enables you to get a file from your website (or any location you can define as a URL) to the user's computer. The key method is [`downloads.download()`](api/downloads/download), which in its simplest form accepts a URL and downloads the file from that URL to the user's default downloads folder:

 
```
browser.downloads.download({url: "https://example.org/image.png"})

```
 You can let the user download to a location of their choice by specifying the `saveAs` parameter.

  **Note:** Using [URL.createObjectURL()](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL) you can also download files and blobs defined in your JavaScript, which can include local content retrieved from IndexedDB.

  The downloads API also provides features to cancel, pause, resume, erase, and remove downloads; search for downloaded files in the download manager; show downloaded files in the computer's file manager; and open a file in an associated application.

 To use this API, you need to have the `"downloads"` [API permission](https://developer.mozilla.org/en-US/docs/Web/API/Permissions#api_permissions) specified in your [`manifest.json`](manifest.json) file.

  Example: [Latest download](https://github.com/mdn/webextensions-examples/tree/master/latest-download) API reference: [downloads API](api/downloads) 


Open files in an extension using a file picker
----------------------------------------------



If you want to work with a file from the user's computer one option is to let the user select a file using the computer's file browser. Either create a new page or inject code into an existing page to use the `file` type of the HTML `input` element to offer the user a file picker. Once the user has picked a file or files, the script associated with the page can access the content of the file using the [DOM File API](https://developer.mozilla.org/en-US/docs/Web/API/File), in the same way a web application does.

  Example: [Imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify) Guide: [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications) API references: [HTML input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file) | [DOM File API](https://developer.mozilla.org/en-US/docs/Web/API/File) 

  **Note:** If you want to access or process all the files in a selected folder, you can do so using `<input type="file" webkitdirectory="true"/>` to select the folder and return all the files it contains.

 
Open files in an extension using drag and drop
----------------------------------------------



The Web Drag and Drop API offers an alternative to using a file picker. To use this method, establish a 'drop zone' that fits with your UI, then add listeners for the [`dragenter`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragenter_event), [`dragover`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragover_event), and [`drop`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event) events to the element. In the handler for the drop event, your code can access any file dropped by the user from the object offered by the `dataTransfer` property using [`DataTransfer.files`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/files). Your code can then access and manipulate the files using the [DOM File API](https://developer.mozilla.org/en-US/docs/Web/API/File).

  Example: [Imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify) Guides: [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications) | [File drag and drop](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop) API references: [DOM File API](https://developer.mozilla.org/en-US/docs/Web/API/File) 


Store files data locally using the IndexedDB file storage library
-----------------------------------------------------------------



If your extension needs to save files locally, the [idb-file-storage library](https://www.npmjs.com/package/idb-file-storage) provides a simple Promise-based wrapper to the [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) to aid the storage and retrieval of files and blobs.

 The key features of the library are:

  [getFileStorage](https://rpl.github.io/idb-file-storage/function/index.html#static-function-getFileStorage)  Returns an `IDBFileStorage` instance, creating the named storage if it does not exist.

  [IDBFileStorage](https://rpl.github.io/idb-file-storage/class/src/idb-file-storage.js~IDBFileStorage.html)  Provides the methods to save and retrieve files, such as:

 * list to obtain an optionally filtered list of file in the database.
* put to add a file or blob to the database.
* get to retrieve a file or blob from the database.
* remove to delete a file or blob from the database.

   The [Store Collected Images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images/webextension-plain) example illustrates how to use most of these features.

 The Store Collected Images example lets users add images to a collection using an option on the image context menu. Selected images are collected in a popup and can be saved to a named collection. A toolbar button ([`browserAction`](api/browseraction)) opens a navigate collection page, on which the user can view and delete saved images, with a filter option to narrow choices. [See the example in action](https://www.youtube.com/watch?v=t6aVqMMe2Rc&ab_channel=LucaGreco).

 The workings of the library can be understood by viewing [image-store.js](https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/utils/image-store.js) in /utils/:


### Creating the store and saving the images




```
async function saveCollectedBlobs(collectionName, collectedBlobs) {
 const storedImages = await getFileStorage({name: "stored-images"});

 for (const item of collectedBlobs) {
    await storedImages.put(`${collectionName}/${item.uuid}`, item.blob);
 }
}

```
 `saveCollectedBlobs` is called when the user clicks save in the popup and has provided a name for the image collection.

 First, `getFileStorage` creates, if it does not exist already, or retrieves the IndexedDB database `"stored-images"` to the object `storedImages`. `storedImages.put()` then adds each collected image to the database, under the collection name, using the blob's unique id (the file name).

 If the image being stored has the same name as one already in the database, it is overwritten. If you want to avoid this, query the database first using `imagesStore.list()` with a filter for the file name; and, if the list returns a file, add a suitable suffix to the name of the new image to store a separate item.


### Retrieving stored images for display




```
export async function loadStoredImages(filter) {
 const imagesStore = await getFileStorage({name: "stored-images"});
 let listOptions = filter ? {includes: filter} : undefined;
 const imagesList = await imagesStore.list(listOptions);
 let storedImages = [];
 for (const storedName of imagesList) {
    const blob = await imagesStore.get(storedName);
    storedImages.push({storedName, blobUrl: URL.createObjectURL(blob)});
 }
 return storedImages;
}

```
 `loadStoredImages()` is called when the user clicks view or reload in the navigate collection page. `getFileStorage()` opens the `"stored-images"` database, then `imagesStore.list()` gets a filtered list of the stored images. This list is then used to retrieve images with `imagesStore.get()` and build a list to return to the UI.

 Note the use of [`URL.createObjectURL(blob)`](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL) to create a URL that references the image blob. This URL is then used in the UI ([navigate-collection.js](https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/navigate-collection.js)[collection.js](https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/navigate-collection.js)) to display the image.


### Delete collected images




```
async function removeStoredImages(storedImages) {
 const imagesStore = await getFileStorage({name: "stored-images"});
 for (const storedImage of storedImages) {
    URL.revokeObjectURL(storedImage.blobUrl);
    await imagesStore.remove(storedImage.storedName);
 }
}

```
 `removeStoredImages()` is called when the user clicks delete in the navigate collection page. Again, `getFileStorage()` opens the `"stored-images"` database then `imagesStore.remove()` removes each image from the filtered list of images.

 Note the use of [`URL.revokeObjectURL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL) to explicitly revoke the blob URL. This enables the garbage collector to free the memory allocated to the URL. If this is not done, the memory will not get returned until the page on which it was created is closed. If the URL was created in an extension's background page, this is not unloaded until the extension is disabled, uninstalled, or reloaded, so holding this memory unnecessarily could affect browser performance. If the URL is created in an extension's page (new tab, popup, or sidebar) the memory is released when the page is closed, but it is still a good practice to revoke the URL when it is no longer needed.

 Once the blob URL has been revoked, any attempt to load it will result in an error. For example, if the blob URL was used as the `SRC` attribute of an `IMG` tag, the image will not load and will not be visible. It is therefore good practice to remove any revoked blob URLs from generated HTML elements when the blob URL is revoked.

  Example: [Store Collected Images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images/webextension-plain) API References: [idb-file-storage library](https://rpl.github.io/idb-file-storage/) 

  **Note:** You can also use the full Web [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) to store data from your extension. This can be useful where you need to store data that isn't handled well by the simple key/value pairs offered by the DOM [Storage API](api/storage).

 
Process files in a local app
----------------------------



Where you have a native app or want to deliver additional native features for file processing, use native messaging to pass a file to a native app for processing.

 You have two options:

  Connection-based messaging  Here you trigger the process with `runtime.connectNative()`, which returns a [`runtime.Port`](api/runtime/port) object. You can then pass a JSON message to the native application using the `postMessage()` function of `Port`. Using the `onMessage.addListener()` function of `Port` you can listen for messages from the native application. The native application is opened if it is not running when `runtime.connectNative()` is called and the application remains running until the extension calls `Port.disconnect()` or the page that connected to it is closed.

  Connectionless messaging  Here you use `runtime.sendNativeMessage()` to send a JSON message to a new, temporary instance of the native application. The browser closes the native application after receiving any message back from the native application.

   To add the file or blob you want the native application to process use [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).

 To use this method the extension must request the `"nativeMessaging"` [permission](manifest.json/permissions) or [optional permission](manifest.json/optional_permissions) in its `manifest.json` file. Where optional permission is used, remember to check that permission has being granted and where necessary request permission from the user with the [`permissions`](api/permissions) API. Reciprocally, the native application must grant permission for the extension by including its ID in the `"allowed_extensions"` field of the app manifest.

  Example: [Native Messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging) (illustrates simple messaging only) Guides: [Native messaging](native_messaging) API references: [runtime API](api/runtime) 




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_files>

Content Security Policy
=======================



Extensions developed with WebExtension APIs have a Content Security Policy (CSP) applied to them by default. This restricts the sources from which they can load code such as [<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) and disallows potentially unsafe practices such as using [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). This article briefly explains what a CSP is, what the default policy is and what it means for an extension, and how an extension can change the default CSP.

 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP) is a mechanism to help prevent websites from inadvertently executing malicious content. A website specifies a CSP using an HTTP header sent from the server. The CSP is mostly concerned with specifying legitimate sources of various types of content, such as scripts or embedded plugins. For example, a website can use it to specify that the browser should only execute JavaScript served from the website itself, and not from any other sources. A CSP can also instruct the browser to disallow potentially unsafe practices, such as the use of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval).

 Like websites, extensions can load content from different sources. For example, a browser action's popup is specified as an HTML document, and it can include JavaScript and CSS from different sources, just like a normal web page:

 
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <!--Some HTML content here-->
    <!--
 Include a third-party script.
 See also https://developer.mozilla.org/en-US/docs/Web/Security/Subresource\_Integrity.
 -->
    <script
 src="https://code.jquery.com/jquery-2.2.4.js"
 integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI="
 crossorigin="anonymous"></script>

    <!-- Include my popup's own script-->
    <script src="popup.js"></script>
  </body>
</html>

```
 Compared to a website, extensions have access to additional privileged APIs, so if they are compromised by malicious code, the risks are greater. For this reason:

 * a fairly strict content security policy is applied to extensions by default. See [default content security policy](#default_content_security_policy).
* the extension's author can change the default policy using the `content_security_policy` manifest.json key, but there are restrictions on the policies that are allowed. See [`content_security_policy`](manifest.json/content_security_policy).



Default content security policy
-------------------------------



The default content security policy for extensions using Manifest V2 is:

 
```
"script-src 'self'; object-src 'self';"

```
 While for extensions using Manifest V3, the default content security policy is:

 
```
"script-src 'self'; upgrade-insecure-requests;"

```
 These policies are applied to any extension that has not explicitly set its own content security policy using the [`content_security_policy`](manifest.json/content_security_policy) manifest.json key. It has the following consequences:

 * [You may only load <script> and <object> resources that are local to the extension.](#location_of_script_and_object_resources)
* [The extension is not allowed to evaluate strings as JavaScript.](#eval_and_friends)
* [Inline JavaScript is not executed.](#inline_javascript)
* [WebAssembly cannot be used by default.](#webassembly)
* [Insecure network requests are upgraded in Manifest V3.](#upgrade_insecure_network_requests_in_manifest_v3)


### Location of script and object resources



Under the default CSP, you can only load code that is local to the extension. The CSP limits [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) to secure sources only, which covers [<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) resources, [ES6 modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). In browsers that support obsolete [plugins](https://developer.mozilla.org/en-US/docs/Glossary/Plugin), the [`object-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src) directive is also restricted. For more information on object-src in extensions, see the WECG issue [Remove object-src from the CSP (at least in MV3)](https://github.com/w3c/webextensions/issues/204)).

 For example, consider a line like this in an extension's document:

 
```
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>

```
 This doesn't load the requested resource: it fails silently, and any object that you expect to be present from the resource is not found. There are two main solutions to this:

 * download the resource, package it in your extension, and refer to this version of the resource.
* allow the remote origin you need using the [`content_security_policy`](manifest.json/content_security_policy) key or, in Manifest V3, the `content_scripts` property.


### eval() and friends



Under the default CSP, extensions cannot evaluate strings as JavaScript. This means that the following are not permitted:

 
```
eval("console.log('some output');");

```
 
```
setTimeout("alert('Hello World!');", 500);

```
 
```
const f = new Function("console.log('foo');");

```

### Inline JavaScript



Under the default CSP, inline JavaScript is not executed. This disallows both JavaScript placed directly in `<script>` tags and inline event handlers, meaning that the following are not permitted:

 
```
<script>
 console.log("foo");
</script>

```
 
```
<div onclick="console.log('click')">Click me!</div>

```
 If you are currently using code like `<body onload="main()">` to run your script when the page has loaded, listen for [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) or [load](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event) instead.


### WebAssembly



Extensions wishing to use [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) require `'wasm-unsafe-eval'` to be specified in the `script-src` directive.

 From Firefox 102 and Chrome 103, `'wasm-unsafe-eval'` can be included in the [`content_security_policy`](manifest.json/content_security_policy) manifest.json key to enable the use of WebAssembly in extensions.

 Manifest V2 extensions in Firefox can use WebAssembly without `'wasm-unsafe-eval'` in their CSP for backward compatibility. However, this behavior isn't guaranteed, see [Firefox bug 1770909](https://bugzil.la/1770909). Extensions using WebAssembly are therefore encouraged to declare `'wasm-unsafe-eval'` in their CSP.

 For Chrome, extensions cannot use WebAssembly in version 101 or earlier. In 102, extensions can use WebAssembly (the same behavior as Firefox 101 and earlier). From version 103, extensions can use WebAssembly if they include `'wasm-unsafe-eval'` in the `content_security_policy` in the manifest key.


### Upgrade insecure network requests in Manifest V3



Extensions should use `https:` and `wss:` when communicating with external servers. To encourage this as the standard behavior, the default Manifest V3 CSP includes the [`upgrade-insecure-requests`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests) directive. This directive automatically upgrades network requests to `http:` to use `https:`.

 While requests are automatically updated, it is still recommended to use `https:`-URLs in the extension's source code where possible. In particular, entries in the [`host_permissions` section of manifest.json](manifest.json/host_permissions) should start with `https://` or `*://` instead of only `http://`.

 Manifest V3 Extensions that need to make `http:` or `ws:` requests can opt out of this behavior by overriding the default CSP using the [`content_security_policy`](manifest.json/content_security_policy) manifest.json key with a policy that excludes the `upgrade-insecure-requests` directive. However, to comply with the [security requirements](https://extensionworkshop.com/documentation/publish/add-on-policies/#security-compliance-and-blocking) of the Add-on Policies, all user data must be transmitted securely.


CSP for content scripts
-----------------------



 In Manifest V2, content scripts have no CSP. As of Manifest V3, content scripts share the default CSP as extensions. It is currently not possible to specify a separate CSP for content scripts ([source](https://bugzil.la/1581611#c10)). 

  The extent to which the CSP controls loads from content scripts varies by browser. In Firefox, JavaScript features such as eval are restricted by the extension CSP. Generally, most DOM-based APIs are subjected to the CSP of the web page. In Chrome, many DOM APIs are covered by the extension CSP instead of the web page's CSP ([crbug 896041](https://crbug.com/896041)). 




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy>

Working with the Tabs API
=========================



Tabs let a user open several web pages in their browser window and then switch between those web pages. With the Tabs API, you can work with and manipulate these tabs to create utilities that provide users with new ways to work with tabs or to deliver the features of your extension.

 In this how-to article we'll look at:

 * Permissions needed to use the Tabs API.
* Discovering more about tabs and their properties using [`tabs.query`](api/tabs/query).
* Creating, duplicating, moving, updating, reloading, and removing tabs.
* Manipulating a tab's zoom level.
* Manipulating a tab's CSS.

 We then conclude by looking at some other, miscellaneous features offered by the API.

  **Note:** There are some Tab API features covered elsewhere. These are the methods you can use to manipulate tab content with scripts ([`tabs.connect`](api/tabs/connect), [`tabs.sendMessage`](api/tabs/sendmessage), and [`tabs.executeScript`](api/tabs/executescript)). If you want more information on these methods, see the Concepts article [Content scripts](content_scripts) and the how-to guide [Modify a web page](modify_a_web_page).

 

Permissions and the Tabs API
----------------------------



For the majority of the Tabs API functions you don't need any permissions; however, there are some exceptions:

 * `"tabs"` permission is needed to access the `Tab.url`, `Tab.title`, and `Tab.favIconUrl` properties of the Tab object. In Firefox, you also need `"tabs"` to perform a [query](api/tabs/query) by URL.
* [Host permission](manifest.json/permissions#host_permissions) is needed for [`tabs.executeScript()`](api/tabs/executescript) or [`tabs.insertCSS()`](api/tabs/insertcss).

 The following is how you might request `"tabs"` permission in your extension's manifest.json file:

 
```
"permissions": [
  "<all\_urls>",
  "tabs"
],

```
 This request gives you use of all Tabs API feature on all website your user visits. There is also an alternative approach for requesting permissions to use [`tabs.executeScript()`](api/tabs/executescript) or [`tabs.insertCSS()`](api/tabs/insertcss) where you don't need host permission, in the form of [`"activeTab"`](manifest.json/permissions#activetab_permission). This permission provides the same rights as `"tabs"` with `<all_urls>`, but with two restrictions:

 * the user must interact with the extension through its browser or page action, context menu, or shortcut key.
* it only grants permission within the active tab.

 The benefit of this approach is the user won't get a permissions warning saying your extension can "Access your data for all websites". This is because `<all_urls>` permission gives an extension the ability to execute scripts in any tab, any time it likes, whereas [`"activeTab"`](manifest.json/permissions#activetab_permission) is limited to allowing the extension to perform a user requested action in the current tab.


Discovering more about tabs and their properties
------------------------------------------------



There will be occasions when you want to get a list of all the tabs in all the browser windows. Other times you might want to find a subset of tabs that match some specific criteria, such as those opened from a specific tab or displaying pages from a particular domain. And once you have your list of tabs, you'll probably want to know more about their properties.

 This is where [`tabs.query()`](api/tabs/query) comes in. Used alone to get all tabs or taking the `queryInfo` object—to specify query criteria such as whether the tab is active, in the current window, or one or more of 17 criteria—[`tabs.query()`](api/tabs/query) returns an array of [`tabs.Tab`](api/tabs/tab) objects containing information about the tabs.

 Where you want information about the current tab only, you can get a [`tabs.Tab`](api/tabs/tab) object for that tab using [`tabs.getCurrent()`](api/tabs/getcurrent). If you have a tab's ID, you can get its [`tabs.Tab`](api/tabs/tab) object using [`tabs.get()`](api/tabs/get).


### How to example



To see how [`tabs.query()`](api/tabs/query) and [`tabs.Tab`](api/tabs/tab) are used, let's walk through how the [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs) example adds the list of "switch to tabs" to its toolbar button popup.

  ![The tabs toolbar menu showing the switch to tap area] 

  manifest.json  Here is the [`manifest.json`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/manifest.json):

 
```
{
  "browser\_action": {
    "browser\_style": true,
    "default\_title": "Tabs, tabs, tabs",
    "default\_popup": "tabs.html"
  },
  "description": "A list of methods you can perform on a tab.",
  "homepage\_url": "https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs",
  "manifest\_version": 2,
  "name": "Tabs, tabs, tabs",
  "permissions": [
    "tabs"
  ],
  "version": "1.0"
}

```
  **Note:**

 * **`tabs.html` is defined as the `default_popup` in `browser_action`.** It is displayed whenever the user clicks the extension's toolbar icon.
* **Permissions includes tabs.** This is needed to support the tab list feature, as the extension reads the title of the tabs for display in the popup.

   tabs.html  `tabs.html` defines the content of the extension's popup:

 
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="tabs.css" />
  </head>

  <body>
    <div class="panel">
      <div class="panel-section panel-section-header">
        <div class="text-section-header">Tabs-tabs-tabs</div>
      </div>

      <a href="#" id="tabs-move-beginning">
        Move active tab to the beginning of the window
      </a>
      <br />

      <!-- Define the other menu items -->

      <div class="switch-tabs">
        <p>Switch to tab</p>
        <div id="tabs-list"></div>
      </div>
    </div>

    <script src="tabs.js"></script>
  </body>
</html>

```
 This does the following:

 1. The menu items are declared.
2. An empty `div` with the ID `tabs-list` is declared to contain the list of tabs.
3. `tabs.js` is called.

  tabs.js  In [`tabs.js`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/tabs.js), we'll see how the list of tabs is built and added to the popup.

   #### Creating the popup

 First, an event handler is added to execute `listTabs()` when `tabs.html` is loaded:

 
```
document.addEventListener("DOMContentLoaded", listTabs);

```
 The first thing that `listTabs()` does is to call `getCurrentWindowTabs()`. This is where [`tabs.query()`](api/tabs/query) is used to get a [`tabs.Tab`](api/tabs/tab) object for the tabs in the current window:

 
```
function getCurrentWindowTabs() {
  return browser.tabs.query({ currentWindow: true });
}

```
 Now, `listTabs()` is ready to create the content for the popup.

 To start with:

 1. Grab the `<div id="tabs-list">` element.
2. Create a document fragment (into which the list will be built).
3. Set counters.
4. Clear the content of the `<div id="tabs-list">` element.

 
```
function listTabs() {
 getCurrentWindowTabs().then((tabs) => {
    const tabsList = document.getElementById('tabs-list');
    const currentTabs = document.createDocumentFragment();
    const limit = 5;
    let counter = 0;

    tabsList.textContent = '';

```
 Next, we'll create the links for each tab:

 1. Loops through the first 5 items from the [`tabs.Tab`](api/tabs/tab) object.
2. For each item, add a hyperlink to the document fragment.
	* The link's label—that is, its text—is set using the tab's `title` (or the `id`, if it has no `title`).
	* The link's address is set using the tab's `id`.

 
```
for (const tab of tabs) {
  if (!tab.active && counter <= limit) {
    const tabLink = document.createElement("a");

    tabLink.textContent = tab.title || tab.id;

    tabLink.setAttribute("href", tab.id);
    tabLink.classList.add("switch-tabs");
    currentTabs.appendChild(tabLink);
  }

  counter += 1;
}

```
 Finally, the document fragment is written to the `<div id="tabs-list">` element:

 
```
    tabsList.appendChild(currentTabs);
  });
}

```
 #### Working with the active tab

 Another related example feature is the "Alert active tab" info option that dumps all the [`tabs.Tab`](api/tabs/tab) object properties for the active tab into an alert:

 
```
else if (e.target.id === "tabs-alertinfo") {
  callOnActiveTab((tab) => {
    let props = "";
    for (const item in tab) {
      props += `${ item } = ${ tab[item] } \n`;
    }
    alert(props);
  });
}

```
 Where `callOnActiveTab()` finds the active tab object by looping through the [`tabs.Tab`](api/tabs/tab) objects looking for the item with active set:

 
```
document.addEventListener("click", (e) => {
  function callOnActiveTab(callback) {
    getCurrentWindowTabs().then((tabs) => {
      for (const tab of tabs) {
        if (tab.active) {
          callback(tab, tabs);
        }
      }
    });
  }
}

```

Creating, duplicating, moving, updating, reloading, and removing tabs
---------------------------------------------------------------------



Having gathered information about the tabs you'll most likely want to do something with them—either to offer users features for manipulating and managing tabs or to implement functionality in your extension.

 The following functions are available:

 * create a new tab ([`tabs.create()`](api/tabs/create)).
* duplicate a tab ([`tabs.duplicate()`](api/tabs/duplicate)).
* remove a tab ([`tabs.remove()`](api/tabs/remove)).
* move a tab ([`tabs.move()`](api/tabs/move)).
* update the tab's URL—effectively browse to a new page—([`tabs.update()`](api/tabs/update)).
* reload the tab's page ([`tabs.reload()`](api/tabs/reload)).

  **Note:** These functions all require the ID (or IDs) of the tab they are manipulating:

 * [`tabs.duplicate()`](api/tabs/duplicate)
* [`tabs.remove()`](api/tabs/remove)
* [`tabs.move()`](api/tabs/move)

 Whereas the following functions will act on the active tab (if no tab `id` is provided):

 * [`tabs.update()`](api/tabs/update)
* [`tabs.reload()`](api/tabs/reload)

 
### How to example



The [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs) example exercises all of these features except for updating a tab's URL The way in which these APIs are used is similar, so we'll look at one of the more involved implementations, that of the "Move active tab to the beginning of the window list" option.

 But first, here is a demonstration of the feature in action:


  manifest.json  None of the functions require a permission to operate, so there are no features in the [manifest.json](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/manifest.json) file that need to be highlighted.

  tabs.html  [`tabs.html`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/tabs.html) defines the "menu" displayed in the popup, which includes the "Move active tab to the beginning of the window list" option, with a series of `<a>` tags grouped by a visual separator. Each menu item is given an `id`, which is used in `tabs.js` to determine which menu item is being requested.

 
```
<a href="#" id="tabs-move-beginning">
  Move active tab to the beginning of the window
</a>
<br />
<a href="#" id="tabs-move-end">Move active tab to the end of the window</a>
<br />

<div class="panel-section-separator"></div>

<a href="#" id="tabs-duplicate">Duplicate active tab</a><br />
<a href="#" id="tabs-reload">Reload active tab</a><br />
<a href="#" id="tabs-alertinfo">Alert active tab info</a><br />

```
  tabs.js  To implement the "menu" defined in `tabs.html`, [`tabs.js`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/tabs.js) includes a listener for clicks in `tabs.html`:

 
```
document.addEventListener("click", (e) => {
  function callOnActiveTab(callback) {
    getCurrentWindowTabs().then((tabs) => {
      for (const tab of tabs) {
        if (tab.active) {
          callback(tab, tabs);
        }
      }
    });
  }
});

```
 A series of `if` statements then look to match the `id` of the item clicked.

 This code snippet is for the "Move active tab to the beginning of the window list" option:

 
```
if (e.target.id === "tabs-move-beginning") {
  callOnActiveTab((tab, tabs) => {
    let index = 0;
    if (!tab.pinned) {
      index = firstUnpinnedTab(tabs);
    }
    console.log(`moving ${tab.id} to ${index}`);
    browser.tabs.move([tab.id], { index });
  });
}

```
 It's worth noting the use of `console.log()`. This enables you to output information to the [debugger](https://extensionworkshop.com/documentation/develop/debugging/) console, which can be useful when resolving issues found during development.

  ![Example of the console.log output, from the move tabs feature, in the debugging console] 

 The move code first calls `callOnActiveTab()` which in turn calls `getCurrentWindowTabs()` to get a [`tabs.Tab`](api/tabs/tab) object containing the active window's tabs. It then loops through the object to find and return the active tab object:

 
```
function callOnActiveTab(callback) {
  getCurrentWindowTabs().then((tabs) => {
    for (const tab of tabs) {
      if (tab.active) {
        callback(tab, tabs);
      }
    }
  });
}

```
   #### Pinned tabs

 A feature of tabs is that the user can *pin* tabs in a window. Pinned tabs are placed at the start of the tab list and cannot be moved. This means that the earliest position a tab can move to is the first position after any pinned tabs. So, `firstUnpinnedTab()` is called to find the position of the first unpinned tab by looping through the `tabs` object:

 
```
function firstUnpinnedTab(tabs) {
  for (const tab of tabs) {
    if (!tab.pinned) {
      return tab.index;
    }
  }
}

```
 We now have everything needed to move the tab: the active tab object from which we can get the tab `id` and the position the tab is to be moved to. So, we can implement the move:

 
```
browser.tabs.move([tab.id], { index });

```
 The remaining functions to duplicate, reload, create, and remove tabs are implemented similarly.


Manipulating a tab's zoom level
-------------------------------



The next set of functions enable you to get ([`tabs.getZoom`](api/tabs/getzoom)) and set ([`tabs.setZoom`](api/tabs/setzoom)) the zoom level within a tab. You can also retrieve the zoom settings ([`tabs.getZoomSettings`](api/tabs/getzoomsettings)) but, at the time of writing, the ability to set the settings ([`tabs.setZoomSettings`](api/tabs/setzoomsettings)) wasn't available in Firefox.

 The level of zoom can be between 30% and 500% (represented as decimals `0.3` to `5`).

 In Firefox the default zoom settings are:

 * **default zoom level:** 100%.
* **zoom mode:** automatic (so the browser manages how zoom levels are set).
* **scope of zoom changes:** `"per-origin"`, meaning that when you visit a site again, it takes the zoom level set in your last visit.


### How to example



The [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs) example includes three demonstrations of the zoom feature: zoom in, zoom out, and reset zoom. Here is the feature in action:


 Let's take a look at how the zoom in is implemented.

  manifest.json  None of the zoom functions require permissions, so there are no features in the [manifest.json](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/manifest.json) file that need to be highlighted.

  tabs.html  We have already discussed how the [`tabs.html`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/tabs.html) defines the options for this extension, nothing new or unique is done to provide the zoom options.

  tabs.js  [`tabs.js`](https://github.com/mdn/webextensions-examples/blob/master/tabs-tabs-tabs/tabs.js) starts by defining several constants used in the zoom code:

 
```
const ZOOM\_INCREMENT = 0.2;
const MAX\_ZOOM = 5;
const MIN\_ZOOM = 0.3;
const DEFAULT\_ZOOM = 1;

```
 It then uses the same listener we discussed earlier so it can act on clicks in `tabs.html`.

 For the zoom in feature, this runs:

 
```
  else if (e.target.id === "tabs-add-zoom") {
    callOnActiveTab((tab) => {
      browser.tabs.getZoom(tab.id).then((zoomFactor) => {
        //the maximum zoomFactor is 5, it can't go higher
        if (zoomFactor >= MAX\_ZOOM) {
          alert("Tab zoom factor is already at max!");
        } else {
          let newZoomFactor = zoomFactor + ZOOM\_INCREMENT;
          //if the newZoomFactor is set to higher than the max accepted
          //it won't change, and will never alert that it's at maximum
          newZoomFactor = newZoomFactor > MAX\_ZOOM ? MAX\_ZOOM : newZoomFactor;
          browser.tabs.setZoom(tab.id, newZoomFactor);
        }
      });
    });
  }

```
 This code uses `callOnActiveTab()` to get the details of the active tab, then [`tabs.getZoom`](api/tabs/getzoom) gets the tab's current zoom factor. The current zoom is compared to the defined maximum (`MAX_ZOOM`) and an alert issued if the tab is already at the maximum zoom. Otherwise, the zoom level is incremented but limited to the maximum zoom, then the zoom is set with [`tabs.getZoom`](api/tabs/getzoom).

  
Manipulating a tab's CSS
------------------------



Another significant capability offered by the Tabs API is the ability to manipulate the CSS within a tab—add new CSS to a tab ([`tabs.insertCSS()`](api/tabs/insertcss)) or remove CSS from a tab ([`tabs.removeCSS()`](api/tabs/removecss)).

 This can be useful, for example, if you want to highlight certain page elements or change the default layout of the page.


### How to example



The [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css) example uses these features to add a red border to the web page in the active tab. Here is the feature in action:


 Let's walk through how it's set up.

  manifest.json  The [`manifest.json`](https://github.com/mdn/webextensions-examples/blob/master/apply-css/manifest.json) requests permissions required to use the CSS features. You need either:

 * `"tabs"` permission and [host permission](manifest.json/permissions#host_permissions); or,
* `"activeTab"` permission.

 The latter is the most useful, as it allows an extension to use [`tabs.insertCSS()`](api/tabs/insertcss) and [`tabs.removeCSS()`](api/tabs/removecss) in the active tab when run from the extension's browser or page action, context menu, or a shortcut.

 
```
{
  "description": "Adds a page action to toggle applying CSS to pages.",

  "manifest\_version": 2,
  "name": "apply-css",
  "version": "1.0",
  "homepage\_url": "https://github.com/mdn/webextensions-examples/tree/master/apply-css",

  "background": {
    "scripts": ["background.js"]
  },

  "page\_action": {
    "default\_icon": "icons/off.svg",
    "browser\_style": true
  },

  "permissions": ["activeTab", "tabs"]
}

```
 You will note that `"tabs"` permission is requested in addition to `"activeTab"`. This additional permission is needed to enable the extension's script to access the tab's URL, the importance of which we'll see in a moment.

 The other main features in the manifest.json file are the definition of:

 * **a background script**, which starts running as soon as the extension is loaded.
* **a "page action"**, which defines an icon to be added to the browser's address bar.

  background.js  On startup, [`background.js`](https://github.com/mdn/webextensions-examples/blob/master/apply-css/background.js) sets some constants to define the CSS to be applied, titles for the "page action", and a list of protocols the extension will work in:

 
```
const CSS = "body { border: 20px solid red; }";
const TITLE\_APPLY = "Apply CSS";
const TITLE\_REMOVE = "Remove CSS";
const APPLICABLE\_PROTOCOLS = ["http:", "https:"];

```
 When first loaded, the extension uses [`tabs.query()`](api/tabs/query) to get a list of all the tabs in the current browser window. It then loops through the tabs calling `initializePageAction()`.

 
```
browser.tabs.query({}).then((tabs) => {
  for (const tab of tabs) {
    initializePageAction(tab);
  }
});

```
 `initializePageAction` uses `protocolIsApplicable()` to determine whether the active tab's URL is one the CSS can be applied to:

 
```
function protocolIsApplicable(url) {
  const anchor = document.createElement("a");
  anchor.href = url;
  return APPLICABLE\_PROTOCOLS.includes(anchor.protocol);
}

```
 Then, if the example can act on the tab, `initializePageAction()` sets the tab's `pageAction` (navigation bar) icon and title to use the "off" versions before making the `pageAction` visible:

 
```
function initializePageAction(tab) {
  if (protocolIsApplicable(tab.url)) {
    browser.pageAction.setIcon({ tabId: tab.id, path: "icons/off.svg" });
    browser.pageAction.setTitle({ tabId: tab.id, title: TITLE\_APPLY });
    browser.pageAction.show(tab.id);
  }
}

```
 Next, a listener on `pageAction.onClicked` waits for the `pageAction` icon to be clicked, and calls `toggleCSS` when it is.

 
```
browser.pageAction.onClicked.addListener(toggleCSS);

```
 `toggleCSS()` gets the title of the `pageAction` and then takes the action described:

 * **For "Apply CSS":**
	+ toggles the `pageAction` icon and title to the "remove" versions.
	+ applies the CSS using [`tabs.insertCSS()`](api/tabs/insertcss).
* **For "Remove CSS":**
	+ toggles the `pageAction` icon and title to the "apply" versions.
	+ removes the CSS using [`tabs.removeCSS()`](api/tabs/removecss).

 
```
function toggleCSS(tab) {
  function gotTitle(title) {
    if (title === TITLE\_APPLY) {
      browser.pageAction.setIcon({ tabId: tab.id, path: "icons/on.svg" });
      browser.pageAction.setTitle({ tabId: tab.id, title: TITLE\_REMOVE });
      browser.tabs.insertCSS({ code: CSS });
    } else {
      browser.pageAction.setIcon({ tabId: tab.id, path: "icons/off.svg" });
      browser.pageAction.setTitle({ tabId: tab.id, title: TITLE\_APPLY });
      browser.tabs.removeCSS({ code: CSS });
    }
  }

  browser.pageAction.getTitle({ tabId: tab.id }).then(gotTitle);
}

```
 Finally, to ensure that the `pageAction` is valid after each update to the tab, a listener on [`tabs.onUpdated`](api/tabs/onupdated) calls `initializePageAction()` each time the tab is updated to check that the tab is still using a protocol to which the CSS can be applied.

 
```
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
  initializePageAction(tab);
});

```
  
Some other interesting abilities
--------------------------------



There are a couple of other Tabs API features that don't fit into one of the earlier sections:

 * Capture the visible tab content with [`tabs.captureVisibleTab`](api/tabs/capturevisibletab).
* Detect the primary language of the content in a tab using [`tabs.detectLanguage`](api/tabs/detectlanguage). This could be used, for example, to match the language in your extension's UI with that of the page it's running in.


Learn more
----------



If you want to learn more about the Tabs API, check out:

 * [Tabs API reference](api/tabs)
* [Example extensions](examples) (many of which use the Tabs API)




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API>

Add a button to the toolbar
===========================



Toolbar buttons are one of the main UI components available to extensions. Toolbar buttons live in the main browser toolbar and contain an icon. When the user clicks the icon, one of two things can happen:

 * If you have specified a popup for the icon, the popup is shown. Popups are transient dialogs specified using HTML, CSS, and JavaScript.
* If you have not specified a popup, a click event is generated, which you can listen for in your code and perform some other kind of action in response to.

 With WebExtension APIs, these kinds of buttons are called "browser actions", and are set up like so:

 * The manifest.json key [`browser_action`](manifest.json/browser_action) is used to define the button.
* The JavaScript API [`browserAction`](api/browseraction) is used to listen for clicks and change the button or perform actions via your code.



A simple button
---------------



In this section we'll create an extension that adds a button to the toolbar. When the user clicks the button, we'll open <https://developer.mozilla.org> in a new tab.

 First, create a new directory, "button", and create a file called "manifest.json" inside it with the following contents:

 
```
{
  "description": "Demonstrating toolbar buttons",
  "manifest\_version": 2,
  "name": "button-demo",
  "version": "1.0",

  "background": {
    "scripts": ["background.js"]
  },

  "browser\_action": {
    "default\_icon": {
      "16": "icons/page-16.png",
      "32": "icons/page-32.png"
    }
  }
}

```
 This specifies that we'll have a [background script](anatomy_of_a_webextension#background_scripts) named "background.js", and a browser action (button) whose icons will live in the "icons" directory.

 Next, create the "icons" directory inside the "buttons" directory, and save the two icons shown below inside it:

 **"page-16.png":**

  !["16 pixel icon of a lined sheet of paper"] 

 **"page-32.png":**

  !["32 pixel icon of a lined sheet of paper"] 

  **Note:** These icons are from the [bitsies!](https://www.iconfinder.com/iconsets/bitsies) iconset created by Recep Kütük.

  We have two icons so we can use the bigger one in high-density displays. The browser will take care of selecting the best icon for the current display.

 Next, create "background.js" in the extension's root directory, and give it the following contents:

 
```
function openPage() {
  browser.tabs.create({
    url: "https://developer.mozilla.org",
  });
}

browser.browserAction.onClicked.addListener(openPage);

```
 This listens for the browser action's click event; when the event fires, the `openPage()` function is run, which opens the specified page using the [`tabs`](api/tabs) API.

 At this point the complete extension should look like this:

 
```
button/
    icons/
        page-16.png
        page-32.png
    background.js
    manifest.json

```
 Now [install the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/) and click the button:

  ![The toolbar button added by the extension](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar/toolbar_button.png) 


Adding a popup
--------------



Let's try adding a popup to the button. Replace manifest.json with this:

 
```
{
  "description": "Demonstrating toolbar buttons",
  "manifest\_version": 2,
  "name": "button-demo",
  "version": "1.0",

  "browser\_action": {
    "browser\_style": true,
    "default\_popup": "popup/choose\_page.html",
    "default\_icon": {
      "16": "icons/page-16.png",
      "32": "icons/page-32.png"
    }
  }
}

```
 We've made three changes from the original:

 * We no longer reference "background.js", because now we're going to handle the extension's logic in the popup's script (you are allowed background.js as well as a popup, it's just that we don't need it in this case).
* We've added `"browser_style": true`, which will help the styling of our popup look more like part of the browser.
* Finally, we've added `"default_popup": "popup/choose_page.html"`, which is telling the browser that this browser action is now going to display a popup when clicked, the document for which can be found at "popup/choose\_page.html".

 So now we need to create that popup. Create a directory called "popup" then create a file called "choose\_page.html" inside it. Give it the following contents:

 
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="choose\_page.css" />
  </head>
  <body>
    <div class="page-choice">developer.mozilla.org</div>
    <div class="page-choice">support.mozilla.org</div>
    <div class="page-choice">addons.mozilla.org</div>
    <script src="choose\_page.js"></script>
  </body>
</html>

```
 You can see that this is a normal HTML page containing three [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) elements, each with the name of a Mozilla site inside. It also includes a CSS file and a JavaScript file, which we'll add next.

 Create a file called "choose\_page.css" inside the "popup" directory, and give it these contents:

 
```
html,
body {
  width: 300px;
}

.page-choice {
  width: 100%;
  padding: 4px;
  font-size: 1.5em;
  text-align: center;
  cursor: pointer;
}

.page-choice:hover {
  background-color: #cff2f2;
}

```
 This is just a bit of styling for our popup.

 Next, create a "choose\_page.js" file inside the "popup" directory, and give it these contents:

 
```
document.addEventListener("click", (event) => {
  if (!event.target.classList.contains("page-choice")) {
    return;
  }

  const chosenPage = `https://${event.target.textContent}`;
  browser.tabs.create({
    url: chosenPage,
  });
});

```
 In our JavaScript, we listen for clicks on the popup choices. We first check to see if the click landed on one of the page-choices; if not, we don't do anything else. If the click did land on a page-choice, we construct a URL from it, and open a new tab containing the corresponding page. Note that we can use WebExtension APIs in popup scripts, just as we can in background scripts.

 The extension's final structure should look like this:

 
```
button/
    icons/
        page-16.png
        page-32.png
    popup/
        choose_page.css
        choose_page.html
        choose_page.js
    manifest.json

```
 Now [reload the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/#reloading-a-temporary-extension), click the button again, and try clicking on the choices in the popup:

  ![The toolbar button added by the extension with a popup](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar/toolbar_button_with_popup.png) 


Page actions
------------



[Page actions](user_interface/page_actions) are just like browser actions, except that they are for actions which are relevant only for particular pages, rather than the browser as a whole.

 While browser actions are always shown, page actions are only shown in tabs where they are relevant. Page action buttons are displayed in the URL bar, rather than the browser toolbar.


Learn more
----------


* [`browser_action`](manifest.json/browser_action) manifest key
* [`browserAction`](api/browseraction) API
* Browser action examples:
	+ [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
	+ [Bookmark it!](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
	+ [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
	+ [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button)
* [`page_action`](manifest.json/page_action) manifest key
* [`pageAction`](api/pageaction) API
* Page action examples:
	+ [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar>

Work with contextual identities
===============================



Many people need or want to interact with the web using multiple personas. They may have accounts for web-based work and personal email. They might sign out of their social media accounts before accessing online shopping, to ensure that any tracking scripts on the shopping sites can't pick up their social media activity. To address these requirements, users often end up working with a standard and private browser window or two different browsers.

 To address this need, Firefox includes a feature known as contextual identities, container tabs or account containers. This feature enables the creation of a cookie container for each of the identities the user wants to use in their browser. Tabs can be associated with one of these identities, keeping cookies separate from those of other identities in the browser. The practical upshot of this is that, for example, a user could have a personal and work identity. They can then use the personal identity in one tab, where they sign into their personal web mail, and the work identity in another tab, where they sign into their work web mail.

 For more background on this feature, see:

 * [Put your multiple online personalities in Firefox Multi-Account Containers](https://blog.mozilla.org/en/products/firefox/introducing-firefox-multi-account-containers/)
* [Security/Contextual Identity Project/Containers](https://wiki.mozilla.org/Security/Contextual_Identity_Project/Containers)
* [Firefox support article on containers](https://support.mozilla.org/en-US/kb/containers?redirectlocale=en-US&as=u&redirectslug=containers-experiment&utm_source=inproduct)



APIs for working with contextual identities
-------------------------------------------



To use the contextual identity features in extensions, you'll work with two APIs:

 * [`contextualIdentities`](api/contextualidentities) which enable an extension to add, query, update, and delete contextual identities.
* [`tabs`](api/tabs) or more specifically [`tabs.create`](api/tabs/create) which enables you to create a tab that uses a contextual identity's container (cookies store).


Permissions
-----------


To use the [`contextualIdentities`](api/contextualidentities) API you need to include the "contextualIdentities" [permission](manifest.json/permissions) in your <manifest.json> file. You don't need the "tabs" permission to use [`tabs.create`](api/tabs/create) however; you do need the "cookies" permission to specify the cookie container you want the tab to use.

Example walkthrough
-------------------



The example extension [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities) provides a toolbar button with a popup that lists the identities in the browser. For each identity, the extension provides options to create a new tab using it's cookies container or remove all of the identity's tabs.

 Here is a short video of the extension in action:



### manifest.json



The main features of the [manifest.json](https://github.com/mdn/webextensions-examples/blob/master/contextual-identities/manifest.json) file are:

 * the permissions request: 
```
  "permissions": [
      "contextualIdentities",
      "cookies"
  ],

```
* specification of the toolbar button (browseAction) that provides access to the extension's features: 
```
  "browser\_action": {
    "browser\_style": true,
    "default\_title": "Contextual Identities",
    "default\_popup": "context.html",
    "default\_icon": {
      "128": "identity.svg"
    }

```


context.html
------------



A popup on the toolbar button provides the extension's user interface. [context.html](https://github.com/mdn/webextensions-examples/blob/master/contextual-identities/context.html) implements this popup, but it's just a shell into which the context.js script writes the list of contextual identities and their related options.

 
```
<body>
  <div class="panel">
    <div id="identity-list"></div>
  </div>
  <script src="context.js"></script>
</body>

```

context.js
----------



All the features of the extension are implemented through [context.js](https://github.com/mdn/webextensions-examples/blob/master/contextual-identities/context.js), which is invoked whenever the toolbar popup is displayed.

 The script first gets the 'identity-list' div from context.html.

 
```
let div = document.getElementById("identity-list");

```
 It then checks whether the contextual identities feature is turned on in the browser. If it's not on, information on how to activate it is added to the popup.

 
```
if (browser.contextualIdentities === undefined) {
  div.innerText = 'browser.contextualIdentities not available. Check that the privacy.userContext.enabled pref is set to true, and reload the add-on.';
} else {

```
 Firefox installs with the contextual identity feature turned off, it's turned on when an extension using the contextualIdentities API is installed. However, it's still possible for the user to turn the feature off, using an option on the preferences page (about:preferences), hence the need for the check.

 The script now uses contextualIdentities.query to determine whether there are any contextual identities defined in the browser. If there are none, a message is added to the popup and the script stops.

 
```
  browser.contextualIdentities.query({})
    .then((identities) => {
      if (!identities.length) {
        div.innerText = 'No identities returned from the API.';
        return;
      }

```
 If there are contextual identities present—Firefox comes with four default identities—the script loops through each one adding its name, styled in its chosen color, to the `<div>` element. The function `createOptions()` then adds the options to "create" or "close all" to the `<div>` before it's added to the popup.

 
```
     for (const identity of identities) {
       const row = document.createElement('div');
       const span = document.createElement('span');
       span.className = 'identity';
       span.innerText = identity.name;
       span.style = `color: ${identity.color}`;
       console.log(identity);
       row.appendChild(span);
       createOptions(row, identity);
       div.appendChild(row);
     }
  });
}

function createOptions(node, identity) {
  for (const option of ['Create', 'Close All']) {
    const a = document.createElement('a');
    a.href = '#';
    a.innerText = option;
    a.dataset.action = option.toLowerCase().replace(' ', '-');
    a.dataset.identity = identity.cookieStoreId;
    a.addEventListener('click', eventHandler);
    node.appendChild(a);
  }
}

```
 The script now waits for the user to select an option in the popup.

 
```
function eventHandler(event) {

```
 If the user clicks the option to create a tab for an identity, one is opened using tabs.create by passing the identity's cookie store ID.

 
```
if (event.target.dataset.action === "create") {
  browser.tabs.create({
    url: "about:blank",
    cookieStoreId: event.target.dataset.identity,
  });
}

```
 If the user selects the option to close all tabs for the identity, the script performs a tabs.query for all tabs that are using the identity's cookie store. The script then passes this list of tabs to `tabs.remove`.

 
```
  if (event.target.dataset.action === 'close-all') {
    browser.tabs.query({
      cookieStoreId: event.target.dataset.identity
    }).then((tabs) => {
      browser.tabs.remove(tabs.map((i) => i.id));
    });
  }
  event.preventDefault();
}

```

Learn more
----------



If you want to learn more about the contextualIdentities API, check out:

 * [contextualIdentities API reference](api/contextualidentities).
* [Multi-Account Containers](https://github.com/mozilla/multi-account-containers/#readme) extension source code. This is code for the [Firefox Multi-Account Containers](https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/) extension. This extension provides users with enhanced functionality for contextual identities, such as the ability to long-click the new tab button and then select the identity to use in the new tab. It really showcases the capabilities offered by contextual identities and is well worth a look.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Work_with_contextual_identities>

Browser compatibility for manifest.json
=======================================


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


 **Note:**

 
See also
--------


* [Browser support for JavaScript APIs](browser_support_for_javascript_apis)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_compatibility_for_manifest.json>

Browser support for JavaScript APIs
===================================


action
------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


alarms
------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


bookmarks
---------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


browserAction
-------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


browserSettings
---------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


browsingData
------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


captivePortal
-------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


clipboard
---------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


commands
--------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


contentScripts
--------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


contextualIdentities
--------------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


cookies
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


declarativeNetRequest
---------------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


devtools
--------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


dns
---


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


dom
---


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


downloads
---------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


events
------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


extension
---------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


extensionTypes
--------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


find
----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


history
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


i18n
----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


identity
--------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


idle
----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


management
----------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


menus
-----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


notifications
-------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


omnibox
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


pageAction
----------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


permissions
-----------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


pkcs11
------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


privacy
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


proxy
-----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


runtime
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


scripting
---------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


search
------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


sessions
--------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


sidebarAction
-------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


storage
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


tabs
----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


theme
-----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


topSites
--------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


types
-----


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


userScripts
-----------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


webNavigation
-------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


webRequest
----------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


windows
-------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


 **Note:** Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 
See also
--------


* [Browser compatibility for manifest.json](browser_compatibility_for_manifest.json)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs>

Firefox workflow overview
=========================





|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| Firefox workflow prepare step graphic | Firefox workflow code step graphic | Firefox workflow publish step graphic | Firefox workflow enhance step graphic | Firefox workflow retire step graphic |
| * Choose a Firefox version for web extension development
* Choose your IDE or code editor
* [Install web-ext](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/)
* Get familiar with the [add-on policies and developer agreement](https://extensionworkshop.com/documentation/publish/add-on-policies/)
 | * [Code your extension](your_first_webextension)
* Run your extension with [web-ext run](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/#testing_out_an_extension) or [about: debugging](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/))
* [Test persistent and restart features](https://extensionworkshop.com/documentation/develop/testing-persistent-and-restart-features/)
* Debug with the [Addon Debugging Window](https://firefox-source-docs.mozilla.org/devtools-user/browser_toolbox/index.html)
 | * Package your extension with [web-ext build](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/#packaging_your_extension)
* Create an [addons.mozilla.org](https://addons.mozilla.org) account
* [Submit your extension](https://extensionworkshop.com/documentation/publish/submitting-an-add-on/)
* [Submit your source code](https://extensionworkshop.com/documentation/publish/source-code-submission/) (if required)
* [Create an appealing listing](https://extensionworkshop.com/documentation/develop/create-an-appealing-listing/)
 | * Responded to Mozilla extension review
* Promote your extension
* [Nominate your extension to be featured](https://extensionworkshop.com/documentation/publish/recommended-extensions/)
* Update and improve your extension
 | * [Retire your extension](https://extensionworkshop.com/documentation/manage/retiring-your-extension/)
 |

 \* Or distribute your extension for [sideloading](https://extensionworkshop.com/documentation/publish/distribute-sideloading/), [desktop apps](https://extensionworkshop.com/documentation/publish/distribute-for-desktop-apps/), or [in an enterprise](https://extensionworkshop.com/documentation/enterprise/).

 **Have an extension you want to bring to Firefox?** We provide advice, guidelines, and tools to help making make porting straightforward. To get started, visit [Porting a Google Chrome extension](https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/).




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Firefox_workflow_overview>

JavaScript APIs
===============



JavaScript APIs for WebExtensions can be used inside the extension's [background scripts](anatomy_of_a_webextension#background_scripts) and in any other documents bundled with the extension, including [browser action](user_interface/browser_action) or [page action](user_interface/page_actions) popups, [sidebars](user_interface/sidebars), [options pages](user_interface/options_pages), or [new tab pages](manifest.json/chrome_url_overrides). A few of these APIs can also be accessed by an extension's [content scripts](anatomy_of_a_webextension#content_scripts). (See the [list in the content script guide](content_scripts#webextension_apis).)

 To use the more powerful APIs, you need to [request permission](manifest.json/permissions) in your extension's `manifest.json`.

 You can access the APIs using the `browser` namespace:

 
```
function logTabs(tabs) {
  console.log(tabs)
}

browser.tabs.query({currentWindow: true}, logTabs)

```
 Many of the APIs are asynchronous, returning a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise):

 
```
function logCookie(c) {
  console.log(c)
}

function logError(e) {
  console.error(e)
}

let setCookie = browser.cookies.set(
  {url: "https://developer.mozilla.org/"}
);
setCookie.then(logCookie, logError)

```


Browser API differences
-----------------------



Note that this is different from Google Chrome's extension system, which uses the `chrome` namespace instead of `browser`, and which uses callbacks instead of promises for asynchronous functions. As a porting aid, the Firefox implementation of WebExtensions APIs supports `chrome` and callbacks as well as `browser` and promises. Mozilla has also written a polyfill which enables code that uses `browser` and promises to work unchanged in Chrome: <https://github.com/mozilla/webextension-polyfill>.

 Firefox also implements these APIs under the `chrome` namespace using callbacks. This allows code written for Chrome to run largely unchanged in Firefox for the APIs documented here.

 Microsoft Edge uses the `browser` namespace, but doesn't yet support promise-based asynchronous APIs. In Edge, for the time being, asynchronous APIs must use callbacks.

 Not all browsers support all the APIs: for the details, see [Browser support for JavaScript APIs](browser_support_for_javascript_apis) and [Chrome incompatibilities](chrome_incompatibilities).


Examples
--------



Throughout the JavaScript API listings, short code examples illustrate how the API is used. You can experiment with most of these examples using the console in the [Toolbox](https://extensionworkshop.com/documentation/develop/debugging/#developer-tools-toolbox). However, you need Toolbox running in the context of a web extension. To do this, open `about:debugging` then **This Firefox**, click **Inspect** against any installed or temporary extension, and open **Console**. You can then paste and run the example code in the console.

 For example, here is the first code example on this page running in the Toolbox console in Firefox Developer Edition:

  ![Illustration of a snippet of web extension code run from the console in the Toolbox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/javascript_exercised_in_console.jpg) 


JavaScript API listing
----------------------



See below for a complete list of JavaScript APIs:



[action](api/action)
Adds a button to the browser's toolbar.


[alarms](api/alarms)
Schedule code to run at a specific time in the future. This is like [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) and [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval), except that those functions don't work with background pages that are loaded on demand.


[bookmarks](api/bookmarks)
The [WebExtensions](index) `bookmarks` API lets an extension interact with and manipulate the browser's bookmarking system. You can use it to bookmark pages, retrieve existing bookmarks, and edit, remove, and organize bookmarks.


[browserAction](api/browseraction)
Adds a button to the browser's toolbar.


[browserSettings](api/browsersettings)
Enables an extension to modify certain global browser settings. Each property of this API is a `types.BrowserSetting` object, providing the ability to modify a particular setting.


[browsingData](api/browsingdata)
Enables extensions to clear the data that is accumulated while the user is browsing.


[captivePortal](api/captiveportal)
Determine the captive portal state of the user's connection. A captive portal is a web page displayed when a user first connects to a Wi-Fi network. The user provides information or acts on the captive portal web page to gain broader access to network resources, such as accepting terms and conditions or making a payment.


[clipboard](api/clipboard)
The WebExtension `clipboard` API (which is different from the [standard Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)) enables an extension to copy items to the system clipboard. Currently the WebExtension `clipboard` API only supports copying images, but it's intended to support copying text and HTML in the future.


[commands](api/commands)
Listen for the user executing commands that you have registered using the [`commands` manifest.json key](manifest.json/commands).


[contentScripts](api/contentscripts)
Use this API to register content scripts. Registering a content script instructs the browser to insert the given content scripts into pages that match the given URL patterns.


[contextualIdentities](api/contextualidentities)
Work with contextual identities: list, create, remove, and update contextual identities.


[cookies](api/cookies)
Enables extensions to get and set cookies, and be notified when they change.


[declarativeNetRequest](api/declarativenetrequest)
This API enables extensions to obtain information about and modify declarative rules that block or modify network requests. The use of declarative rules means that extensions don't intercept and view the content of requests, providing more privacy.


[devtools](api/devtools)
Enables extensions to interact with the browser's Developer Tools. You can use this API to create Developer Tools pages, interact with the window that is being inspected, inspect the page network usage.


[dns](api/dns)
Enables an extension to resolve domain names.


[dom](api/dom)
Access special extension only DOM features.


[downloads](api/downloads)
Enables extensions to interact with the browser's download manager. You can use this API module to download files, cancel, pause, resume downloads, and show downloaded files in the file manager.


[events](api/events)
Common types used by APIs that dispatch events.


[extension](api/extension)
Utilities related to your extension. Get URLs to resources packages with your extension. Get the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for your extension's pages. Get the values for various settings.


[extensionTypes](api/extensiontypes)
Some common types used in other WebExtension APIs.


[find](api/find)
Finds text in a web page, and highlights matches.


[history](api/history)
Use the `history` API to interact with the browser history.


[i18n](api/i18n)
Functions to internationalize your extension. You can use these APIs to get localized strings from locale files packaged with your extension, find out the browser's current language, and find out the value of its [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#the_accept-language_header).


[identity](api/identity)
Use the identity API to get an [OAuth2](https://oauth.net/2/) authorization code or access token, which an extension can then use to access user data from a service that supports OAuth2 access (such as Google or Facebook).


[idle](api/idle)
Find out when the user's system is idle, locked, or active.


[management](api/management)
Get information about installed add-ons.


[menus](api/menus)
Add items to the browser's menu system.


[notifications](api/notifications)
Display notifications to the user, using the underlying operating system's notification mechanism. Because this API uses the operating system's notification mechanism, the details of how notifications appear and behave may differ according to the operating system and the user's settings.


[omnibox](api/omnibox)
Enables extensions to implement customized behavior when the user types into the browser's address bar.


[pageAction](api/pageaction)
A [page action](user_interface/page_actions) is a clickable icon inside the browser's address bar.


[permissions](api/permissions)
Enables extensions to request extra permissions at runtime, after they have been installed.


[pkcs11](api/pkcs11)
The `pkcs11` API enables an extension to enumerate [PKCS #11](https://en.wikipedia.org/wiki/PKCS_11) security modules and to make them accessible to the browser as sources of keys and certificates.


[privacy](api/privacy)
Access and modify various privacy-related browser settings.


[proxy](api/proxy)
Use the proxy API to proxy web requests. You can use the `proxy.onRequest` event listener to intercept web requests, and return an object that describes whether and how to proxy them.


[runtime](api/runtime)
This module provides information about your extension and the environment it's running in.


[scripting](api/scripting)
Inserts JavaScript and CSS into websites. This API offers two approaches to inserting content:


[search](api/search)
Use the search API to retrieve the installed search engines and execute searches.


[sessions](api/sessions)
Use the sessions API to list, and restore, tabs and windows that have been closed while the browser has been running.


[sidebarAction](api/sidebaraction)
Gets and sets properties of an extension's sidebar.


[storage](api/storage)
Enables extensions to store and retrieve data, and listen for changes to stored items.


[tabs](api/tabs)
Interact with the browser's tab system.


[theme](api/theme)
Enables browser extensions to update the browser theme.


[topSites](api/topsites)
Use the topSites API to get an array containing pages that the user has visited frequently.


[types](api/types)
Defines the `BrowserSetting` type, which is used to represent a browser setting.


[userScripts](api/userscripts)
Use this API to register user scripts, third-party scripts designed to manipulate webpages or provide new features. Registering a user script instructs the browser to attach the script to pages that match the URL patterns specified during registration.


[webNavigation](api/webnavigation)
Add event listeners for the various stages of a navigation. A navigation consists of a frame in the browser transitioning from one URL to another, usually (but not always) in response to a user action like clicking a link or entering a URL in the location bar.


[webRequest](api/webrequest)
Add event listeners for the various stages of making an HTTP request, which includes websocket requests on `ws://` and `wss://`. The event listener receives detailed information about the request and can modify or cancel the request.


[windows](api/windows)
Interact with browser windows. You can use this API to get information about open windows and to open, modify, and close windows. You can also listen for window open, close, and activate events.





 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API>

Content scripts
===============



A content script is a part of your extension that runs in the context of a particular web page (as opposed to background scripts which are part of the extension, or scripts which are part of the website itself, such as those loaded using the [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) element).

 [Background scripts](background_scripts) can access all the [WebExtension JavaScript APIs](api), but they can't directly access the content of web pages. So if your extension needs to do that, you need content scripts.

 Just like the scripts loaded by normal web pages, content scripts can read and modify the content of their pages using the standard DOM APIs.

 Content scripts can only access [a small subset of the WebExtension APIs](#webextension_apis), but they can [communicate with background scripts](#communicating_with_background_scripts) using a messaging system, and thereby indirectly access the WebExtension APIs.

  **Note:** Content scripts are only executed if the extension is granted [host permissions](manifest.json/permissions#host_permissions) for the domain.

 However, [restricted domains](#restricted_domains) can never be accessed, regardless of the granted permissions.

 Starting with Manifest V3, host permissions are not automatically granted at install time. Users may opt in or out of host permissions after installing the extension.

 

Loading content scripts
-----------------------



You can load a content script into a web page in one of three ways:

 1. At install time, into pages that match URL patterns.  Using the [`content_scripts`](manifest.json/content_scripts) key in your `manifest.json`, you can ask the browser to load a content script whenever the browser loads a page whose URL [matches a given pattern](match_patterns).
2. At runtime, into pages that match URL patterns.  Using the [`contentScripts`](api/contentscripts) API, you can ask the browser to load a content script whenever the browser loads a page whose URL [matches a given pattern](match_patterns). (This is similar to method 1, *except* that you can add and remove content scripts at runtime.)
3. At runtime, into specific tabs.  In Manifest V2, using [`tabs.executeScript()`](api/tabs/executescript), or Manifest V3, using [`scripting.executeScript()`](api/scripting/executescript), you can load a content script into a specific tab whenever you want. (For example, in response to the user clicking on a [browser action](user_interface/browser_action).)

 There is only one global scope *per frame, per extension*. This means that variables from one content script can directly be accessed by another content script, regardless of how the content script was loaded.

 Using methods (1) and (2), you can only load scripts into pages whose URLs can be represented using a [match pattern](match_patterns).

 Using method (3), you can also load scripts into pages packaged with your extension, but you can't load scripts into privileged browser pages (like "`about:debugging`" or "`about:addons`").

   **Note:** [Dynamic JS module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#dynamic_module_loading) are now working in content scripts. For more details, see [Firefox bug 1536094](https://bugzil.la/1536094). Only URLs with the *moz-extension* scheme are allowed, which excludes data URLs ([Firefox bug 1587336](https://bugzil.la/1587336)). 

 
Restricted domains
------------------



Even with the right [host permissions](manifest.json/permissions#host_permissions), extensions cannot access some domains. Content scripts are blocked from executing on these domains, for example, to protect the user from an extension escalating privileges through special pages.

 In Firefox, this includes the following domains:

 * accounts-static.cdn.mozilla.net
* accounts.firefox.com
* addons.cdn.mozilla.net
* addons.mozilla.org
* api.accounts.firefox.com
* content.cdn.mozilla.net
* discovery.addons.mozilla.org
* install.mozilla.org
* oauth.accounts.firefox.com
* profile.accounts.firefox.com
* support.mozilla.org
* sync.services.mozilla.com

 Other browsers have similar restrictions over the websites extensions can be installed from. For example, access to chrome.google.com is restricted in Chrome.

  **Note:** Because these restrictions include addons.mozilla.org, users who try to use your extension immediately after installation may find that it doesn't work. To avoid this, you should add an appropriate warning or an [onboarding page](https://extensionworkshop.com/documentation/develop/onboard-upboard-offboard-users/) to move users away from `addons.mozilla.org`.

  The set of domains can be restricted further through enterprise policies: Firefox recognizes the `restricted_domains` policy as documented at [ExtensionSettings in mozilla/policy-templates](https://github.com/mozilla/policy-templates/blob/master/README.md#extensionsettings). Chrome's `runtime_blocked_hosts` policy is documented at [Configure ExtensionSettings policy](https://support.google.com/chrome/a/answer/9867568).


Content script environment
--------------------------


### DOM access



Content scripts can access and modify the page's DOM, just like normal page scripts can. They can also see any changes that were made to the DOM by page scripts.

 However, content scripts get a "clean" view of the DOM. This means:

 * Content scripts cannot see JavaScript variables defined by page scripts.
* If a page script redefines a built-in DOM property, the content script sees the original version of the property, not the redefined version.

 As noted at ["Content script environment" at Chrome incompatibilities](chrome_incompatibilities#content_script_environment), the behavior differs across browsers:

 * In Firefox, this behavior is called [Xray vision](sharing_objects_with_page_scripts#xray_vision_in_firefox). Content scripts may encounter JavaScript objects from its own global scope or Xray-wrapped versions from the web page.
* In Chrome this behavior is enforced through an [isolated world](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md#world), which uses a fundamentally different approach.

 Consider a web page like this:

 
```
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  </head>

  <body>
    <script src="page-scripts/page-script.js"></script>
  </body>
</html>

```
 The script `page-script.js` does this:

 
```
// page-script.js

// add a new element to the DOM
let p = document.createElement("p");
p.textContent = "This paragraph was added by a page script.";
p.setAttribute("id", "page-script-para");
document.body.appendChild(p);

// define a new property on the window
window.foo = "This global variable was added by a page script";

// redefine the built-in window.confirm() function
window.confirm = () => {
  alert("The page script has also redefined 'confirm'");
}

```
 Now an extension injects a content script into the page:

 
```
// content-script.js

// can access and modify the DOM
let pageScriptPara = document.getElementById("page-script-para");
pageScriptPara.style.backgroundColor = "blue";

// can't see properties added by page-script.js
console.log(window.foo);  // undefined

// sees the original form of redefined properties
window.confirm("Are you sure?"); // calls the original window.confirm()

```
 The same is true in reverse; page scripts cannot see JavaScript properties added by content scripts.

 This means that content scripts can rely on DOM properties behaving predictably, without worrying about its variables clashing with variables from the page script.

 One practical consequence of this behavior is that a content script doesn't have access to any JavaScript libraries loaded by the page. So, for example, if the page includes jQuery, the content script can't see it.

 If a content script needs to use a JavaScript library, then the library itself should be injected as a content script *alongside* the content script that wants to use it:

 
```
"content\_scripts": [
  {
    "matches": ["\*://\*.mozilla.org/\*"],
    "js": ["jquery.js", "content-script.js"]
  }
]

```
  **Note:** Firefox *does* provide some APIs that enable content scripts to access JavaScript objects created by page scripts, and to expose their own JavaScript objects to page scripts.

 See [Sharing objects with page scripts](sharing_objects_with_page_scripts) for more details.

 
### WebExtension APIs



In addition to the standard DOM APIs, content scripts can use the following WebExtension APIs:

 **From [`extension`](api/extension):**

 * [`getURL()`](api/extension/geturl)
* [`inIncognitoContext`](api/extension/inincognitocontext)

 **From [`runtime`](api/runtime):**

 * [`connect()`](api/runtime/connect)
* [`getManifest()`](api/runtime/getmanifest)
* [`getURL()`](api/runtime/geturl)
* [`onConnect`](api/runtime/onconnect)
* [`onMessage`](api/runtime/onmessage)
* [`sendMessage()`](api/runtime/sendmessage)

 **From [`i18n`](api/i18n):**

 * [`getMessage()`](api/i18n/getmessage)
* [`getAcceptLanguages()`](api/i18n/getacceptlanguages)
* [`getUILanguage()`](api/i18n/getuilanguage)
* [`detectLanguage()`](api/i18n/detectlanguage)

 **From [`menus`](api/menus):**

 * [`getTargetElement`](api/menus/gettargetelement)

 **Everything from:**

 * [`storage`](api/storage)


### XHR and Fetch



Content scripts can make requests using the normal [`window.XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) and [`window.fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) APIs.

  **Note:** In Firefox in Manifest V2, content script requests (for example, using [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)) happen in the context of an extension, so you must provide an absolute URL to reference page content.

 In Chrome and Firefox in Manifest V3, these requests happen in context of the page, so they are made to a relative URL. For example, `/api` is sent to `https://«current page URL»/api`.

  Content scripts get the same cross-domain privileges as the rest of the extension: so if the extension has requested cross-domain access for a domain using the [`permissions`](manifest.json/permissions) key in `manifest.json`, then its content scripts get access that domain as well.

  **Note:** When using Manifest V3, content scripts can perform cross-origin requests when the destination server opts in using [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS); however, host permissions don't work in content scripts, but they still do in regular extension pages.

  This is accomplished by exposing more privileged XHR and fetch instances in the content script, which has the side effect of not setting the [`Origin`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) and [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) headers like a request from the page itself would; this is often preferable to prevent the request from revealing its cross-origin nature.

  **Note:** In Firefox in Manifest V2, extensions that need to perform requests that behave as if they were sent by the content itself can use `content.XMLHttpRequest` and `content.fetch()` instead.

 For cross-browser extensions, the presence of these methods must be feature-detected.

 This is not possible in Manifest V3, as `content.XMLHttpRequest` and `content.fetch()` are not available.

   **Note:** In Chrome, starting with version 73, and Firefox, starting with version 101 when using Manifest V3, content scripts are subject to the same [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) policy as the page they are running within. Only backend scripts have elevated cross-domain privileges. See [Changes to Cross-Origin Requests in Chrome Extension Content Scripts](https://www.chromium.org/Home/chromium-security/extension-content-script-fetches).

 
Communicating with background scripts
-------------------------------------



Although content scripts can't directly use most of the WebExtension APIs, they can communicate with the extension's background scripts using the messaging APIs, and can therefore indirectly access all the same APIs that the background scripts can.

 There are two basic patterns for communicating between the background scripts and content scripts:

 * You can send **one-off messages** (with an optional response).
* You can set up a **longer-lived connection between the two sides**, and use that connection to exchange messages.


### One-off messages



To send one-off messages, with an optional response, you can use the following APIs:

 

|  | In content script | In background script |
| --- | --- | --- |
| Send a message | `[browser.runtime.sendMessage()](api/runtime/sendmessage)` | `[browser.tabs.sendMessage()](api/tabs/sendmessage)` |
| Receive a message | `[browser.runtime.onMessage](api/runtime/onmessage)` | `[browser.runtime.onMessage](api/runtime/onmessage)` |

 For example, here's a content script that listens for click events in the web page.

 If the click was on a link, it sends a message to the background page with the target URL:

 
```
// content-script.js

window.addEventListener("click", notifyExtension);

function notifyExtension(e) {
  if (e.target.tagName !== "A") {
    return;
  }
  browser.runtime.sendMessage({"url": e.target.href});
}

```
 The background script listens for these messages and displays a notification using the [`notifications`](api/notifications) API:

 
```
// background-script.js

browser.runtime.onMessage.addListener(notify);

function notify(message) {
  browser.notifications.create({
    "type": "basic",
    "iconUrl": browser.extension.getURL("link.png"),
    "title": "You clicked a link!",
    "message": message.url
  });
}

```
 (This example code is lightly adapted from the [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) example on GitHub.)


### Connection-based messaging



Sending one-off messages can get cumbersome if you are exchanging a lot of messages between a background script and a content script. So an alternative pattern is to establish a longer-lived connection between the two contexts, and use this connection to exchange messages.

 Both sides have a [`runtime.Port`](api/runtime/port) object, which they can use to exchange messages.

 To create the connection:

 * One side listens for connections using [`runtime.onConnect`](api/runtime/onconnect)
* The other side calls:
	+ [`tabs.connect()`](api/tabs/connect) (if connecting to a content script)
	+ [`runtime.connect()`](api/runtime/connect) (if connecting to a background script)

 This returns a [`runtime.Port`](api/runtime/port) object.

 * The [`runtime.onConnect`](api/runtime/onconnect) listener gets passed its own [`runtime.Port`](api/runtime/port) object.

 Once each side has a port, the two sides can:

 * Send messages using `runtime.Port.postMessage()`
* Receive messages using `runtime.Port.onMessage()`

 For example, as soon as it loads, the following content script:

 * Connects to the background script
* Stores the `Port` in a variable `myPort`
* Listens for messages on `myPort` (and logs them)
* Uses `myPort` to sends messages to the background script when the user clicks the document

 
```
// content-script.js

let myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({greeting: "they clicked the page!"});
});

```
 The corresponding background script:

 * Listens for connection attempts from the content script
* When receiving a connection attempt:
	+ Stores the port in a variable named `portFromCS`
	+ Sends the content script a message using the port
	+ Starts listening to messages received on the port, and logs them
* Sends messages to the content script, using `portFromCS`, when the user clicks the extension's browser action

 
```
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({greeting: "hi there content script!"});
  portFromCS.onMessage.addListener((m) => {
    portFromCS.postMessage({greeting: `In background script, received message from content script: ${m.greeting}`});
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({greeting: "they clicked the button!"});
});

```
 #### Multiple content scripts

 If you have multiple content scripts communicating at the same time, you might want to store connections to them in an array.

 
```
// background-script.js

let ports = []

function connected(p) {
  ports[p.sender.tab.id] = p
  // …
}

browser.runtime.onConnect.addListener(connected)

browser.browserAction.onClicked.addListener(() => {
  ports.forEach((p) => {
        p.postMessage({greeting: "they clicked the button!"})
    })
});

```

### Choosing between one-off messages and connection-based messaging



The choice between one-off and connection-based messaging depends on how your extension expects to make use of messaging.

 The recommended best practices are:

 * **Use one-off messages when…**
	+ Only one response is expected to a message.
	+ A small number of scripts listen to receive messages ([`runtime.onMessage`](api/runtime/onmessage) calls).
* **Use connection-based messaging when…**
	+ Scripts engage in sessions where multiple messages are exchanged.
	+ The extension needs to know about task progress or if a task is interrupted, or wants to interrupt a task initiated using messaging.


Communicating with the web page
-------------------------------



By default, content scripts don't get access to the objects created by page scripts. However, they can communicate with page scripts using the DOM [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) and [`window.addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) APIs.

 For example:

 
```
// page-script.js

let messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage({
    direction: "from-page-script",
    message: "Message from the page"
  }, "\*");
}

```
 
```
// content-script.js

window.addEventListener("message", (event) => {
  if (
    event.source === window &&
    event?.data?.direction === "from-page-script"
  ) {
    alert(`Content script received message: "${event.data.message}"`);
  }
});

```
 For a complete working example of this, [visit the demo page on GitHub](https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html) and follow the instructions.

  **Warning:** Be very careful when interacting with untrusted web content in this manner! Extensions are privileged code which can have powerful capabilities and hostile web pages can easily trick them into accessing those capabilities.

 To give a trivial example, suppose the content script code that receives the message does something like this:

 
```
// content-script.js

window.addEventListener("message", (event) => {
  if (
    event.source === window &&
    event?.data?.direction === "from-page-script"
  ) {
    eval(event.data.message);
  }
});

```
 Now the page script can run any code with all the privileges of the content script.

 
Using `eval()` in content scripts
---------------------------------



 **Note:** `eval()` not available in Manifest V3.

   In Chrome  [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) always runs code in the context of the **content script**, not in the context of the page.

  In Firefox  If you call `eval()`, it runs code in the context of the **content script**.

 If you call `window.eval()`, it runs code in the context of the **page**.

   For example, consider a content script like this:

 
```
// content-script.js

window.eval('window.x = 1;');
eval('window.y = 2');

console.log(`In content script, window.x: ${window.x}`);
console.log(`In content script, window.y: ${window.y}`);

window.postMessage({
  message: "check"
}, "\*");

```
 This code just creates some variables `x` and `y` using `window.eval()` and `eval()`, logs their values, and then messages the page.

 On receiving the message, the page script logs the same variables:

 
```
window.addEventListener("message", (event) => {
  if (event.source === window && event.data && event.data.message === "check") {
    console.log(`In page script, window.x: ${window.x}`);
    console.log(`In page script, window.y: ${window.y}`);
  }
});

```
 In Chrome, this produces output like this:

 
```
In content script, window.x: 1
In content script, window.y: 2
In page script, window.x: undefined
In page script, window.y: undefined

```
 In Firefox, this produces output like this:

 
```
In content script, window.x: undefined
In content script, window.y: 2
In page script, window.x: 1
In page script, window.y: undefined

```
 The same applies to [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout), [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval), and [`Function()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function).

  **Warning:** Be very careful when running code in the context of the page!

 The page's environment is controlled by potentially malicious web pages, which can redefine objects you interact with to behave in unexpected ways:

 
```
// page.js redefines console.log

let original = console.log;

console.log = () => {
  original(true);
}

```
 
```
// content-script.js calls the redefined version

window.eval('console.log(false)');

```
 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts>

Match patterns in extension manifests
=====================================



Match patterns are a way to specify groups of URLs: a match pattern matches a specific set of URLs. They are used in WebExtensions APIs in a few places, most notably to specify which documents to load [content scripts](content_scripts) into, and to specify which URLs to add [`webRequest`](api/webrequest) listeners to.

 APIs that use match patterns usually accept a list of match patterns, and will perform the appropriate action if the URL matches any of the patterns. See, for example, the [`content_scripts`](manifest.json/content_scripts) key in manifest.json.



Match pattern structure
-----------------------



  **Note:** Some browsers don't support certain schemes. Check the [Browser compatibility table](#browser_compatibility) for details. 

  All match patterns are specified as strings. Apart from the special [`<all_urls>`](match_patterns#all_urls) pattern, match patterns consist of three parts: *scheme*, *host*, and *path*. The scheme and host are separated by `://`.

 
```
<scheme>://<host><path>

```

### scheme



The *scheme* component may take one of two forms:

 

| Form | Matches |
| --- | --- |
| `*` |  Only "http" and "https" and in some browsers also ["ws" and "wss"](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API).  |
|  One of `http`, `https`, `ws`, `wss`, `ftp`, `data`, `file`, or `(chrome-)extension`.  | Only the given scheme. |


### host



The *host* component may take one of three forms:

 

| Form | Matches |
| --- | --- |
| `*` | Any host. |
| `*.` followed by part of the hostname. | The given host and any of its subdomains. |
| A complete hostname, without wildcards. | Only the given host. |

 *host* must not include a port number.

 *host* is optional only if the *scheme* is "file".

 Note that the wildcard may only appear at the start.


### path



The *path* component must begin with a `/`.

 After that, it may subsequently contain any combination of the `*` wildcard and any of the characters that are allowed in URL paths or query strings. Unlike *host*, the *path* component may contain the `*` wildcard in the middle or at the end, and the `*` wildcard may appear more than once.

 The value for the *path* matches against the string which is the URL path plus the [URL query string](https://en.wikipedia.org/wiki/Query_string). This includes the `?` between the two, if the query string is present in the URL. For example, if you want to match URLs on any domain where the URL path ends with `foo.bar`, then you need to use an array of Match Patterns like `['*://*/*foo.bar', '*://*/*foo.bar?*']`. The `?*` is needed, rather than just `bar*`, in order to anchor the ending `*` as applying to the URL query string and not some portion of the URL path.

 Neither the [URL fragment identifier](https://en.wikipedia.org/wiki/Fragment_identifier), nor the `#` which precedes it, are considered as part of the *path*.

  **Note:** The path pattern string should not include a port number. Adding a port, as in: `http://localhost:1234/*` causes the match pattern to be ignored. However, `http://localhost:1234` will match with `http://localhost/*`.

 
### <all\_urls>


The special value `<all_urls>` matches all URLs under any of the supported schemes: that is "http", "https", "ws", "wss", "ftp", "data", and "file".

Examples
--------




| Pattern | Example matches | Example non-matches |
| --- | --- | --- |
| `<all_urls>` Match all URLs. | `http://example.org/` `https://a.org/some/path/` `ws://sockets.somewhere.org/` `wss://ws.example.com/stuff/` `ftp://files.somewhere.org/` | `resource://a/b/c/`(unsupported scheme) `ftps://files.somewhere.org/`(unsupported scheme) |
| `*://*/*` Match all HTTP, HTTPS and WebSocket URLs. | `http://example.org/` `https://a.org/some/path/` `ws://sockets.somewhere.org/` `wss://ws.example.com/stuff/` | `ftp://ftp.example.org/`(unmatched scheme) `file:///a/`(unmatched scheme) |
| `*://*.mozilla.org/*`  Match all HTTP, HTTPS and WebSocket URLs that are hosted at "mozilla.org" or one of its subdomains.  | `http://mozilla.org/` `https://mozilla.org/` `http://a.mozilla.org/` `http://a.b.mozilla.org/` `https://b.mozilla.org/path/` `ws://ws.mozilla.org/` `wss://secure.mozilla.org/something` | `ftp://mozilla.org/`(unmatched scheme) `http://mozilla.com/`(unmatched host) `http://firefox.org/`(unmatched host) |
| `*://mozilla.org/`  Match all HTTP, HTTPS and WebSocket URLs that are hosted at exactly "mozilla.org/".  | `http://mozilla.org/` `https://mozilla.org/` `ws://mozilla.org/` `wss://mozilla.org/` | `ftp://mozilla.org/`(unmatched scheme) `http://a.mozilla.org/`(unmatched host) `http://mozilla.org/a`(unmatched path) |
| `ftp://mozilla.org/` Match only "ftp://mozilla.org/". | `ftp://mozilla.org` | `http://mozilla.org/`(unmatched scheme) `ftp://sub.mozilla.org/`(unmatched host) `ftp://mozilla.org/path`(unmatched path) |
| `https://*/path` Match HTTPS URLs on any host, whose path is "path". | `https://mozilla.org/path` `https://a.mozilla.org/path` `https://something.com/path` | `http://mozilla.org/path`(unmatched scheme) `https://mozilla.org/path/`(unmatched path) `https://mozilla.org/a`(unmatched path) `https://mozilla.org/`(unmatched path)  `https://mozilla.org/path?foo=1`(unmatched path due to URL query string)  |
| `https://*/path/`  Match HTTPS URLs on any host, whose path is "path/" and which has no URL query string.  | `https://mozilla.org/path/` `https://a.mozilla.org/path/` `https://something.com/path`/ | `http://mozilla.org/path/`(unmatched scheme) `https://mozilla.org/path`(unmatched path) `https://mozilla.org/a`(unmatched path) `https://mozilla.org/`(unmatched path) `https://mozilla.org/path/?foo=1`(unmatched path due to URL query string) |
| `https://mozilla.org/*`  Match HTTPS URLs only at "mozilla.org", with any URL path and URL query string.  | `https://mozilla.org/` `https://mozilla.org/path` `https://mozilla.org/another` `https://mozilla.org/path/to/doc` `https://mozilla.org/path/to/doc?foo=1` | `http://mozilla.org/path`(unmatched scheme) `https://mozilla.com/path`(unmatched host) |
| `https://mozilla.org/a/b/c/` Match only this URL, or this URL with any URL fragment. | `https://mozilla.org/a/b/c/` `https://mozilla.org/a/b/c/#section1` | Anything else. |
| `https://mozilla.org/*/b/*/`  Match HTTPS URLs hosted on "mozilla.org", whose path contains a component "b" somewhere in the middle. Will match URLs with query strings, if the string ends in a `/`.  | `https://mozilla.org/a/b/c/` `https://mozilla.org/d/b/f/` `https://mozilla.org/a/b/c/d/` `https://mozilla.org/a/b/c/d/#section1` `https://mozilla.org/a/b/c/d/?foo=/` `https://mozilla.org/a?foo=21314&bar=/b/&extra=c/` | `https://mozilla.org/b/*/`(unmatched path) `https://mozilla.org/a/b/`(unmatched path)  `https://mozilla.org/a/b/c/d/?foo=bar`(unmatched path due to URL query string)  |
| `file:///blah/*` Match any FILE URL whose path begins with "blah". | `file:///blah/` `file:///blah/bleh` | `file:///bleh/`(unmatched path) |

### Invalid match patterns




| Invalid pattern | Reason |
| --- | --- |
| `resource://path/` | Unsupported scheme. |
| `https://mozilla.org` | No path. |
| `https://mozilla.*.org/` | "\*" in host must be at the start. |
| `https://*zilla.org/` | "\*" in host must be the only character or be followed by ".". |
| `http*://mozilla.org/` | "\*" in scheme must be the only character. |
| `https://mozilla.org:80/` | Host must not include a port number. |
| `*://*` | Empty path: this should be "`*://*/*`". |
| `file://*` | Empty path: this should be "`file:///*`". |

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `data` | No | No | 48Doesn't support injection of content scripts or stylesheets. | ? | No | No | ? | ? | 48Doesn't support injection of content scripts or stylesheets. | ? | No | ? |
| `file` | Yes | 14 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `ftp` | Yes | 14 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `http` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `https` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `wildcard` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `wildcard_websocket` | No | No | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |
| `ws` | No | No | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |
| `wss` | No | No | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns>

Internationalization
====================



The [WebExtensions](index) API has a rather handy module available for internationalizing extensions — [i18n](api/i18n). In this article we'll explore its features and provide a practical example of how it works. The i18n system for extensions built using WebExtension APIs is similar to common JavaScript libraries for i18n such as [i18n.js](http://i18njs.com/).

  **Note:** The example extension featured in this article — [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) — is available on GitHub. Follow along with the source code as you go through the sections below.

 

Anatomy of an internationalized extension
-----------------------------------------



An internationalized extension can contain the same features as any other extension — [background scripts](anatomy_of_a_webextension#background_scripts), [content scripts](content_scripts), etc. — but it also has some extra parts to allow it to switch between different locales. These are summarized in the following directory tree:

 * extension-root-directory/
	+ \_locales
		- en
			* messages.json
				+ English messages (strings)
		- de
			* messages.json
				+ German messages (strings)
		- etc.
	+ manifest.json
		- locale-dependent metadata
	+ myJavascript.js
		- JavaScript for retrieving browser locale, locale-specific messages, etc.
	+ myStyles.css
		- locale-dependent CSS

 Let's explore each of the new features in turn — each of the below sections represents a step to follow when internationalizing your extension.


Providing localized strings in \_locales
----------------------------------------



 **Note:** You can look up language subtags using the *Find* tool on the [Language subtag lookup page](https://r12a.github.io/app-subtags/). Note that you need to search for the English name of the language.

  Every i18n system requires the provision of strings translated into all the different locales you want to support. In extensions, these are contained within a directory called `_locales`, placed inside the extension root. Each individual locale has its strings (referred to as messages) contained within a file called `messages.json`, which is placed inside a subdirectory of `_locales`, named using the language subtag for that locale's language.

 Note that if the subtag includes a basic language plus a regional variant, then the language and variant are conventionally separated using a hyphen: for example, "en-US". However, in the directories under `_locales`, **the separator must be an underscore**: "en\_US".

 So [for example, in our sample app](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n/_locales) we have directories for "en" (English), "de" (German), "nl" (Dutch), and "ja" (Japanese). Each one of these has a `messages.json` file inside it.

 Let's now look at the structure of one of these files ([\_locales/en/messages.json](https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/_locales/en/messages.json)):

 
```
{
  "extensionName": {
    "message": "Notify link clicks i18n",
    "description": "Name of the extension."
  },

  "extensionDescription": {
    "message": "Shows a notification when the user clicks on links.",
    "description": "Description of the extension."
  },

  "notificationTitle": {
    "message": "Click notification",
    "description": "Title of the click notification."
  },

  "notificationContent": {
    "message": "You clicked $URL$.",
    "description": "Tells the user which link they clicked.",
    "placeholders": {
      "url" : {
        "content" : "$1",
        "example" : "https://developer.mozilla.org"
      }
    }
  }
}

```
 This file is standard JSON — each one of its members is an object with a name, which contains a `message` and a `description`. All of these items are strings; `$URL$` is a placeholder, which is replaced with a substring at the time the `notificationContent` member is called by the extension. You'll learn how to do this in the [Retrieving message strings from JavaScript](#retrieving_message_strings_from_javascript) section.

  **Note:** You can find much more information about the contents of `messages.json` files in our [Locale-Specific Message reference](api/i18n/locale-specific_message_reference).

 
Internationalizing manifest.json
--------------------------------


There are a couple of different tasks to carry out to internationalize your manifest.json.

### Retrieving localized strings in manifests



Your [manifest.json](https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/manifest.json) includes strings that are displayed to the user, such as the extension's name and description. If you internationalize these strings and put the appropriate translations of them in messages.json, then the correct translation of the string will be displayed to the user, based on the current locale, like so.

 To internationalize strings, specify them like this:

 
```
"name": "\_\_MSG\_extensionName\_\_",
"description": "\_\_MSG\_extensionDescription\_\_",

```
 Here, we are retrieving message strings dependent on the browser's locale, rather than just including static strings.

 To call a message string like this, you need to specify it like this:

 1. Two underscores, followed by
2. The string "MSG", followed by
3. One underscore, followed by
4. The name of the message you want to call as defined in `messages.json`, followed by
5. Two underscores

 
```
__MSG_ + messageName + __

```

### Specifying a default locale



Another field you should specify in your manifest.json is [default\_locale](manifest.json/default_locale):

 
```
"default\_locale": "en"

```
 This specifies a default locale to use if the extension doesn't include a localized string for the browser's current locale. Any message strings that are not available in the browser locale are taken from the default locale instead. There are some more details to be aware of in terms of how the browser selects strings — see [Localized string selection](#localized_string_selection).


Locale-dependent CSS
--------------------



Note that you can also retrieve localized strings from CSS files in the extension. For example, you might want to construct a locale-dependent CSS rule, like this:

 
```
header {
  background-image: url(../images/\_\_MSG\_extensionName\_\_/header.png);
}

```
 This is useful, although you might be better off handling such a situation using [Predefined messages](#predefined_messages).


Retrieving message strings from JavaScript
------------------------------------------



So, you've got your message strings set up, and your manifest. Now you just need to start calling your message strings from JavaScript so your extension can talk the right language as much as possible. The actual [i18n API](api/i18n) is pretty simple, containing just four main methods:

 * You'll probably use [`i18n.getMessage()`](api/i18n/getmessage) most often — this is the method you use to retrieve a specific language string, as mentioned above. We'll see specific usage examples of this below.
* The [`i18n.getAcceptLanguages()`](api/i18n/getacceptlanguages) and [`i18n.getUILanguage()`](api/i18n/getuilanguage) methods could be used if you needed to customize the UI depending on the locale — perhaps you might want to show preferences specific to the users' preferred languages higher up in a prefs list, or display cultural information relevant only to a certain language, or format displayed dates appropriately according to the browser locale.
* The [`i18n.detectLanguage()`](api/i18n/detectlanguage) method could be used to detect the language of user-submitted content, and format it appropriately.

 In our [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) example, the [background script](https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/background-script.js) contains the following lines:

 
```
let title = browser.i18n.getMessage("notificationTitle");
let content = browser.i18n.getMessage("notificationContent", message.url);

```
 The first one just retrieves the `notificationTitle message` field from the available `messages.json` file most appropriate for the browser's current locale. The second one is similar, but it is being passed a URL as a second parameter. What gives? This is how you specify the content to replace the `$URL$` placeholder we see in the `notificationContent message` field:

 
```
"notificationContent": {
  "message": "You clicked $URL$.",
  "description": "Tells the user which link they clicked.",
  "placeholders": {
    "url" : {
      "content" : "$1",
      "example" : "https://developer.mozilla.org"
    }
  }
}

```
 The `"placeholders"` member defines all the placeholders, and where they are retrieved from. The `"url"` placeholder specifies that its content is taken from $1, which is the first value given inside the second parameter of `getMessage()`. Since the placeholder is called `"url"`, we use `$URL$` to call it inside the actual message string (so for `"name"` you'd use `$NAME$`, etc.) If you have multiple placeholders, you can provide them inside an array that is given to [`i18n.getMessage()`](api/i18n/getmessage) as the second parameter — `[a, b, c]` will be available as `$1`, `$2`, and `$3`, and so on, inside `messages.json`.

 Let's run through an example: the original `notificationContent` message string in the `en/messages.json` file is

 
```
You clicked $URL$.

```
 Let's say the link clicked on points to `https://developer.mozilla.org`. After the [`i18n.getMessage()`](api/i18n/getmessage) call, the contents of the second parameter are made available in messages.json as `$1`, which replaces the `$URL$` placeholder as defined in the `"url"` placeholder. So the final message string is

 
```
You clicked https://developer.mozilla.org.

```

### Direct placeholder usage



It is possible to insert your variables (`$1`, `$2`, `$3`, etc.) directly into the message strings, for example we could rewrite the above `"notificationContent"` member like this:

 
```
"notificationContent": {
  "message": "You clicked $1.",
  "description": "Tells the user which link they clicked."
}

```
 This may seem quicker and less complex, but the other way (using `"placeholders"`) is seen as best practice. This is because having the placeholder name (e.g. `"url"`) and example helps you to remember what the placeholder is for — a week after you write your code, you'll probably forget what `$1` – `$8` refer to, but you'll be more likely to know what your placeholder names refer to.


### Hardcoded substitution



It is also possible to include hardcoded strings in placeholders, so that the same value is used every time, instead of getting the value from a variable in your code. For example:

 
```
"mdn\_banner": {
  "message": "For more information on web technologies, go to $MDN$.",
  "description": "Tell the user about MDN",
  "placeholders": {
    "mdn": {
      "content": "https://developer.mozilla.org/"
    }
  }
}

```
 In this case we are just hardcoding the placeholder content, rather than getting it from a variable value like `$1`. This can sometimes be useful when your message file is very complex, and you want to split up different values to make the strings more readable in the file, plus then these values could be accessed programmatically.

 In addition, you can use such substitutions to specify parts of the string that you don't want to be translated, such as person or business names.


Localized string selection
--------------------------



Locales can be specified using only a language code, like `fr` or `en`, or they may be further qualified with a region code, like `en_US` or `en_GB`, which describes a regional variant of the same basic language. When you ask the i18n system for a string, it will select a string using the following algorithm:

 1. if there is a `messages.json` file for the exact current locale, and it contains the string, return it.
2. Otherwise, if the current locale is qualified with a region (e.g. `en_US`) and there is a `messages.json` file for the regionless version of that locale (e.g. `en`), and that file contains the string, return it.
3. Otherwise, if there is a `messages.json` file for the `default_locale` defined in the `manifest.json`, and it contains the string, return it.
4. Otherwise return an empty string.

 Take the following example:

 * extension-root-directory/
	+ \_locales
		- en\_GB
			* messages.json
				+ `{ "colorLocalized": { "message": "colour", "description": "Color." }, /* … */ }`en
			* messages.json
				+ `{ "colorLocalized": { "message": "color", "description": "Color." }, /* … */ }`
		- fr
			* messages.json
				+ `{ "colorLocalized": { "message": "couleur", "description": "Color." }, /* … */}`

 Suppose the `default_locale` is set to `fr`, and the browser's current locale is `en_GB`:

 * If the extension calls `getMessage("colorLocalized")`, it will return "colour".
* If "colorLocalized" were not present in `en_GB`, then `getMessage("colorLocalized")`, would return "color", not "couleur".


Predefined messages
-------------------



The i18n module provides us with some predefined messages, which we can call in the same way as we saw earlier in [Retrieving localized strings in manifests](#retrieving_localized_strings_in_manifests) and [Locale-dependent CSS](#locale-dependent_css). For example:

 
```
__MSG_extensionName__

```
 Predefined messages use exactly the same syntax, except with `@@` before the message name, for example

 
```
__MSG_@@ui_locale__

```
 The following table shows the different available predefined messages:

 

| Message name | Description |
| --- | --- |
| `@@extension_id` |  The extension's internally-generated UUID. You might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.  You can't use this message in a manifest file.  Also note that this ID is *not* the add-on ID returned by [`runtime.id`](api/runtime/id), and that can be set using the [browser\_specific\_settings](manifest.json/browser_specific_settings) key in manifest.json. It's the generated UUID that appears in the add-on's URL. This means that you can't use this value as the `extensionId` parameter to [`runtime.sendMessage()`](api/runtime/sendmessage), and can't use it to check against the `id` property of a [`runtime.MessageSender`](api/runtime/messagesender) object.  |
| `@@ui_locale` |  The current locale; you might use this string to construct locale-specific URLs.  |
| `@@bidi_dir` |  The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Arabic.  |
| `@@bidi_reversed_dir` |  If the `@@bidi_dir` is "ltr", then this is "rtl"; otherwise, it's "ltr".  |
| `@@bidi_start_edge` |  If the `@@bidi_dir` is "ltr", then this is "left"; otherwise, it's "right".  |
| `@@bidi_end_edge` |  If the `@@bidi_dir` is "ltr", then this is "right"; otherwise, it's "left".  |

 Going back to our earlier example, it would make more sense to write it like this:

 
```
header {
  background-image: url(../images/\_\_MSG\_@@ui\_locale\_\_/header.png);
}

```
 Now we can just store our local specific images in directories that match the different locales we are supporting — en, de, etc. — which makes a lot more sense.

 Let's look at an example of using `@@bidi_*` messages in a CSS file:

 
```
body {
  direction: __MSG_@@bidi\_dir\_\_;
}

div#header {
  margin-bottom: 1.05em;
  overflow: hidden;
  padding-bottom: 1.5em;
  padding-__MSG_@@bidi\_start\_edge\_\_: 0;
  padding-__MSG_@@bidi\_end\_edge\_\_: 1.5em;
  position: relative;
}

```
 For left-to-right languages such as English, the CSS declarations involving the predefined messages above would translate to the following final code lines:

 
```
direction: ltr;
padding-left: 0;
padding-right: 1.5em;

```
 For a right-to-left language like Arabic, you'd get:

 
```
direction: rtl;
padding-right: 0;
padding-left: 1.5em;

```

Testing out your extension
--------------------------



To test your extension's localization, you use [Firefox](https://www.mozilla.org/en-US/firefox/new/) or [Firefox Beta](https://www.mozilla.org/en-US/firefox/channel/desktop/), the Firefox builds in which you can install language packs.

 Then, for each locale supported in the extension you want to test, follow the instructions to [Use Firefox in another language](https://support.mozilla.org/en-US/kb/use-firefox-another-language) to switch the Firefox UI language. (If you know your way around Settings, under Language, use Set Alternatives.)

 Once Firefox is running in your test language, [install the extension temporarily](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/). After installing your extension, in `about:debugging`, if you've set up your extension correctly, you see the extension listed with its icon, name, and description in the chosen language. You can also see the localized extension details in `about:addons`. Now exercise the extension's features to ensure the translations you need are in place.

 If you'd like to try this process out, you can use the [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) extension. Set up Firefox to display one of the languages supported in this example (German, Dutch, or Japanese). Load the extension and go to a website. Click a link to see the translated version of the notification reporting the link's URL.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization>

Extending the developer tools
=============================



 **Note:** This page describes devtools APIs as they exist in Firefox 55. Although the APIs are based on the [Chrome devtools APIs](https://developer.chrome.com/docs/extensions/mv3/devtools/), there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see [Limitations of the devtools APIs](#limitations_of_the_devtools_apis).

  You can use WebExtensions APIs to extend the browser's built-in developer tools. To create a devtools extension, include the "[devtools\_page](manifest.json/devtools_page)" key in <manifest.json>:

 
```
"devtools\_page": "devtools/devtools-page.html"

```
 The value of this key is a URL pointing to an HTML file that's been bundled with your extension. The URL should be relative to the manifest.json file itself.

 The HTML file defines a special page in the extension, called the devtools page.



The devtools page
-----------------



The devtools page is loaded when the browser devtools are opened, and unloaded when it is closed. Note that because the devtools window is associated with a single tab, it's quite possible for more than one devtools window - hence more than one devtools page - to exist at the same time.

 The devtools page doesn't have any visible DOM, but can include JavaScript sources using [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) tags. The sources must be bundled with the extension itself. The sources get access to:

 * The normal DOM APIs accessible through the global [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object
* The same [WebExtension APIs as in Content Scripts](content_scripts#webextension_apis)
* The devtools APIs:
	+ [`devtools.inspectedWindow`](api/devtools/inspectedwindow)
	+ [`devtools.network`](api/devtools/network)
	+ [`devtools.panels`](api/devtools/panels)

 Note that the devtools page does not get access to any other WebExtension APIs, and the background page doesn't get access to the devtools APIs. Instead, the devtools page and the background page must communicate using the `runtime` messaging APIs. Here's an example:

 
```
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>DevTools Extension</title>
  </head>
  <body>
    <script src="devtools.js"></script>
  </body>
</html>

```
 The `devtools.js` file will hold the actual code creating your dev tools extensions.


Creating panels
---------------



The devtools window hosts a number of separate tools - the JavaScript Debugger, Network Monitor, and so on. A row of tabs across the top lets the user switch between the different tools. The window hosting each tool's user interface is called a "panel".

 Using the `devtools.panels.create()` API, you can create your own panel in the devtools window:

 
```
browser.devtools.panels.create(
  "My Panel",                      // title
  "/icons/star.png",               // icon
  "/devtools/panel/panel.html"     // content
).then((newPanel) => {
  newPanel.onShown.addListener(initialisePanel);
  newPanel.onHidden.addListener(unInitialisePanel);
});

```
 This takes three mandatory arguments: the panel's title, icon, and content. It returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which resolves to a `devtools.panels.ExtensionPanel` object representing the new panel.


Interacting with the target window
----------------------------------


The developer tools are always attached to a particular browser tab. This is referred to as the "target" for the developer tools, or the "inspected window". You can interact with the inspected window using the [`devtools.inspectedWindow`](api/devtools/inspectedwindow) API.

### Running code in the target window



The [`devtools.inspectedWindow.eval()`](api/devtools/inspectedwindow/eval) provides one way to run code in the inspected window.

 This is somewhat like using [`tabs.executeScript()`](api/tabs/executescript) to inject a content script, but with one important difference:

 * unlike content scripts, scripts loaded using `devtools.inspectedWindow.eval()` **do not** get [a "clean view of the DOM"](content_scripts#dom_access): that is, they can see changes to the page made by page scripts.

  **Note:** A clean view of the DOM is a security feature, intended to help prevent hostile pages from tricking extensions by redefining the behavior of native DOM functions. This means you need to be very careful using eval(), and should use a normal content script if you can.

  Scripts loaded using `devtools.inspectedWindow.eval()` also don't see any JavaScript variables defined by content scripts.


### Working with content scripts



A devtools document doesn't have direct access to [`tabs.executeScript()`](api/tabs/executescript), so if you need to inject a content script, the devtools document must send a message to the background script asking it to inject the script. The [`devtools.inspectedWindow.tabId`](api/devtools/inspectedwindow/tabid) provides the ID of the target tab: the devtools document can pass this to the background script, and the background script can in turn pass it into [`tabs.executeScript()`](api/tabs/executescript):

 
```
// devtools-panel.js

const scriptToAttach = "document.body.innerHTML = 'Hi from the devtools';";

window.addEventListener("click", () => {
  browser.runtime.sendMessage({
    tabId: browser.devtools.inspectedWindow.tabId,
    script: scriptToAttach
  });
});

```
 
```
// background.js

function handleMessage(request, sender, sendResponse) {
  browser.tabs.executeScript(request.tabId, {
    code: request.script
  });
}

browser.runtime.onMessage.addListener(handleMessage);

```
 If you need to exchange messages between the content scripts running in the target window and a devtools document, it's a good idea to use the [`runtime.connect()`](api/runtime/connect) and [`runtime.onConnect`](api/runtime/onconnect) to set up a connection between the background page and the devtools document. The background page can then maintain a mapping between tab IDs and [`runtime.Port`](api/runtime/port) objects, and use this to route messages between the two scopes.

  ![The background page tab ID is connected to the content script on the content page by a runtime.sendmessage() object. The Port of the background page is connected to the port of the Devtools document by a port.postMessage() object.] 


Limitations of the devtools APIs
--------------------------------


These APIs are based on the Chrome devtools APIs, but many features are still missing, compared with Chrome. This section lists the features that are still not implemented, as of Firefox 54. Note that the devtools APIs are under active development and we expect to add support for most of them in future releases.

### devtools.inspectedWindow



The following are not supported:

 * `inspectedWindow.getResources()`
* `inspectedWindow.onResourceAdded`
* `inspectedWindow.onResourceContentCommitted`

 None of the options to `inspectedWindow.eval()` are supported.

 Scripts injected using `inspectedWindow.eval()` can't use all the Console's command-line helper functions, but `$0` and `inspect()` are both supported (starting from Firefox 55).


### devtools.panels



The following are not supported:

 * `panels.elements`
* `panels.sources`
* `panels.setOpenResourceHandler()`
* `panels.openResource()`
* `panels.ExtensionPanel.createStatusBarButton()`
* `panels.Button`
* `panels.ElementsPanel`
* `panels.SourcesPanel`


Examples
--------



The [webextensions-examples](https://github.com/mdn/webextensions-examples) repo on GitHub, contains several examples of extensions that use devtools panels:

 * [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels) use devtools panels:




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools>

Native manifests
================



Native manifests are specially formatted JSON files that are provisioned on the user's computer by some means outside the extension installation process. For example, a native manifest might be provisioned by a device administrator or by a native application installer.

 There are three different types of native manifest:

 

|  |  |
| --- | --- |
| [Native messaging manifests](#native_messaging_manifests) |  Enable a feature called [native messaging](native_messaging), in which an extension can communicate with a native app installed on the device.  |
| [Managed storage manifests](#managed_storage_manifests) |  Define read-only data that an extension can access using the [`storage.managed`](api/storage/managed) API.  |
| [PKCS #11 manifests](#pkcs_11_manifests) |  Enable an extension to use the [`pkcs11`](api/pkcs11) API to enumerate PKCS #11 security modules and install them in Firefox.  |

 For all native manifests, you need to arrange things so the browser can find the manifest. The section on [manifest location](#manifest_location) describes these rules.



Native messaging manifests
--------------------------



The native messaging manifest contains a single JSON object with the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `name` | String | Name of the native application.  This must match the name passed into [`runtime.connectNative()`](api/runtime/connectnative) or [`runtime.sendNativeMessage()`](api/runtime/sendnativemessage) by the extension.   On MacOS and Linux, it must also match the native messaging manifest's filename (excluding the `.json` extension).   On Windows, it must match the name of the registry key you create, that contains the location of the native messaging manifest.   The name must match the following regular expression: `"^\w+(\.\w+)*$"`. This means that it may only contain (lowercase or uppercase) alphanumeric characters, underscores, and dots. It may not start or end with a dot, and a dot cannot be followed by another dot.  |
| `description` | String | Description of the native application. |
| `path` | String | Path to the native application.  On Windows, this may be relative to the manifest itself. On MacOS and Linux it must be absolute.  |
| `type` | String | Describes the method used to connect the extension with the app.  Currently, only one value can be given here, `"stdio"`, which indicates that messages are received by the app using standard input (`stdin`) and sent using standard output (`stdout`).  |
| `allowed_extensions` | Array of String |  An array of [Add-on ID](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/) values. Each value represents an extension which is allowed to communicate with this native application.   Note that this means you will probably want to include the `[browser\_specific\_settings](manifest.json/browser_specific_settings)` key in your extension's `manifest.json` file, so you can set an explicit ID during development.  |

 For example, here's a manifest for the `ping_pong` native application:

 
```
{
  "name": "ping\_pong",
  "description": "Example host for native messaging",
  "path": "/path/to/native-messaging/app/ping\_pong.py",
  "type": "stdio",
  "allowed\_extensions": [ "ping\_pong@example.org" ]
}

```
 This allows the extension whose ID is `ping_pong@example.org` to connect, by passing the name `ping_pong` into the relevant [`runtime`](api/runtime) API function. The application itself is at `/path/to/native-messaging/app/ping_pong.py`.


Managed storage manifests
-------------------------



The managed storage manifest contains a single JSON object with the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `name` | String |  The ID of the extension that can access this storage, given as the ID you've specified in the extension's `[browser\_specific\_settings](manifest.json/browser_specific_settings)` key.  |
| `description` | String | Human-readable description, ignored by Firefox. |
| `type` | String | This must be `"storage"`. |
| `data` | Object |  A JSON object that may contain any valid JSON values, including strings, numbers, booleans, arrays, or objects. This will become the data in the `browser.storage.managed` storage area.  |

 For example:

 
```
{
  "name": "favourite-color-examples@mozilla.org",
  "description": "ignored",
  "type": "storage",
  "data":
  {
    "color": "management thinks it should be blue!"
  }
}

```
 Given this JSON manifest, the `favourite-color-examples@mozilla.org` extension could access the data using code like this:

 
```
let storageItem = browser.storage.managed.get('color');
storageItem.then((res) => {
  console.log(`Managed color is: ${res.color}`);
});

```

PKCS #11 manifests
------------------



The PKCS #11 manifest is a file containing a JSON object with the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `name` | String | Name of the PKCS #11 module. This must match the name used in the `pkcs11` API.  On MacOS and Linux, it must also match the manifest's filename (excluding the extension).   On Windows, it must match the name of the registry key you create, which contains the location of the manifest.   The name must match the following regular expression: `"^\w+(\.\w+)*$"`. This means that it may only contain lowercase alphanumeric characters, underscores and dots. It may not start or end with a dot, and a dot cannot be followed by another dot.  |
| `description` | String | Description of the module.  This is used to set the friendly name for the module in the browser's UI (for example, the "Security Devices" dialog in Firefox).  |
| `path` | String | Path to the module.  On Windows, this may be relative to the manifest itself. On MacOS and Linux it must be absolute.  |
| `type` | String | This must be `"pkcs11"`. |
| `allowed_extensions` | Array of String |  An array of [Add-on ID](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/) values. Each value represents an extension which is allowed to interact with the module.    **Note:** This means you will probably want to include the `[browser\_specific\_settings](manifest.json/browser_specific_settings)` key in your extension's `manifest.json` file, so you can set an explicit ID during development.   |

 For example:

 
```
{
  "name": "my\_module",
  "description": "My test module",
  "type": "pkcs11",
  "path": "/path/to/libpkcs11testmodule.dylib",
  "allowed\_extensions": ["my-extension@mozilla.org"]
}

```
 Given this JSON manifest, saved as `my_module.json`, the `my-extension@mozilla.org` extension could install the security module at `/path/to/libpkcs11testmodule.dylib` using code like this:

 
```
browser.pkcs11.installModule("my\_module");

```

Manifest location
-----------------



On Linux and macOS, you need to store the manifest in a particular place. On Windows, you need to create a registry key that points to the manifest's location.

 The detailed rules are the same for all the manifest types, except that the penultimate component of the path identifies the type of manifest. The examples below show the form for each of the three different types. In all the examples, `<name>` is the value of the `name` property in the manifest.


### Windows



For global visibility, create a registry key with the following name:

 
```
HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts\<name>

```
 
```
HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\ManagedStorage\<name>

```
 
```
HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\PKCS11Modules\<name>

```
 The key should have a single default value, which is the path to the manifest.

  **Warning:** As of Firefox 64, the 32-bit registry view ([Wow6432Node)](https://en.wikipedia.org/wiki/WoW64#Registry_and_file_system) will be checked first for these keys, followed by the "native" registry view. Use whichever is appropriate for your application.

 **For Firefox 63 and older:** This key should *not* be created under [Wow6432Node](https://en.wikipedia.org/wiki/WoW64#Registry_and_file_system), even if the app is 32-bit. Previous versions of the browser will always look for the key under the "native" view of the registry, not the 32-bit emulation. To ensure that the key is created in the "native" view, you can pass the `KEY_WOW64_64KEY` or `KEY_WOW64_32KEY` flags into `RegCreateKeyEx`. See [Accessing an Alternate Registry View](https://docs.microsoft.com/windows/win32/winprog64/accessing-an-alternate-registry-view).

  For per-user visibility, create a registry key with the following name:

 
```
HKEY_CURRENT_USER\SOFTWARE\Mozilla\NativeMessagingHosts\<name>

```
 
```
HKEY_CURRENT_USER\SOFTWARE\Mozilla\ManagedStorage\<name>

```
 
```
HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\<name>

```
 The key should have a single default value, which is the path to the manifest.


### macOS



For global visibility, store the manifest in:

 
```
/Library/Application Support/Mozilla/NativeMessagingHosts/<name>.json

```
 
```
/Library/Application Support/Mozilla/ManagedStorage/<name>.json

```
 
```
/Library/Application Support/Mozilla/PKCS11Modules/<name>.json

```
 For per-user visibility, store the manifest in:

 
```
~/Library/Application Support/Mozilla/NativeMessagingHosts/<name>.json

```
 
```
~/Library/Application Support/Mozilla/ManagedStorage/<name>.json

```
 
```
~/Library/Application Support/Mozilla/PKCS11Modules/<name>.json

```

### Linux



For global visibility, store the manifest in either:

 
```
/usr/lib/mozilla/native-messaging-hosts/<name>.json

```
 
```
/usr/lib/mozilla/managed-storage/<name>.json

```
 
```
/usr/lib/mozilla/pkcs11-modules/<name>.json

```
 or:

 
```
    /usr/lib64/mozilla/native-messaging-hosts/<name>.json

```
 
```
    /usr/lib64/mozilla/managed-storage/<name>.json

```
 
```
    /usr/lib64/mozilla/pkcs11-modules/<name>.json

```
 For per-user visibility, store the manifest in:

 
```
~/.mozilla/native-messaging-hosts/<name>.json

```
 
```
~/.mozilla/managed-storage/<name>.json

```
 
```
~/.mozilla/pkcs11-modules/<name>.json

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests>

User interface
==============



Extensions that use WebExtension APIs are provided with several user interface options so that their functionality can be made available to the user. A summary of those options is provided below, with a more detailed introduction to each user interface option in this section.

  **Note:** For advice on using these UI components to create a great user experience in your extension, please see the [User experience best practices](https://extensionworkshop.com/documentation/develop/user-experience-best-practices/) article.

  

| UI option | Description | Example |
| --- | --- | --- |
| [Toolbar button](user_interface/browser_action) (browser action)  |  A button on the browser toolbar that dispatches an event to the extension when clicked. By default, the button is visible in all tabs.  | Example showing a toolbar button (browser action). |
|  Toolbar button with a [popup](user_interface/popups) |  A popup on a button in the browser toolbar that opens when the button is clicked. The popup is defined in an HTML document that handles the user interaction.  | Example of the pop-up on a toolbar button |
| [Address bar button](user_interface/page_actions) (page action)  |  A button on the browser address bar that dispatches an event to the extension when clicked. By default, the button is hidden in all tabs.  | Example showing an address bar button (page action)  |
|  Address bar button with a [popup](user_interface/popups) |  A popup on a button in the browser address bar that opens when the button is clicked. The popup is defined in an HTML document that handles the user interaction.  | Example of a popup on the address bar button |
| [Context menu item](user_interface/context_menu_items) |  Menu items, checkboxes, and radio buttons on one or more of the browser's context menus. Also, menus can be structured by adding separators. When menu items are clicked, an event is dispatched to the extension.  | Example of content menu items added by a WebExtension, from the context-menu-demo example |
| [Sidebar](user_interface/sidebars) |  An HTML document displayed next to a web page, with the option for unique content per page. The sidebar is opened when the extension is installed, then obeys the user's sidebar visibility selection. User interaction within the sidebar is handled by its HTML document.  | Example of a sidebar |
| [Options page](user_interface/options_pages) |  A page that enables you to define preferences for your extension that your users can change. The user can access this page from the browser's add-ons manager.  | Example showing the options page content added in the favorite colors example. |
| [Extension page](user_interface/extension_pages) |  Use web pages included in your extension to provide forms, help, or any other content required, within windows or tabs.  | Example of a simple bundled page displayed as a detached panel. |
| [Notification](user_interface/notifications) |  Transient notifications displayed to the user through the underlying operating system's notifications mechanism. Dispatches an event to the extension when the user clicks a notification, or when a notification closes (either automatically or at the user's request).  | Example of an extension triggered system notification |
| [Address bar suggestion](user_interface/omnibox) | Offer custom address bar suggestions when the user enters a keyword. | Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions. |
| [Developer tools panel](user_interface/devtools_panels) |  A tab with an associated HTML document that displays in the browser's developer tools.  | Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions. |

 The following how-to guides provide step-by-step guidance to creating some of these user interface options:

 * [Accessibility guidelines](https://extensionworkshop.com/documentation/develop/build-an-accessible-extension/)
* [Add a button to the toolbar](add_a_button_to_the_toolbar)
* [Browser styles](user_interface/browser_styles)
* [Extending the developer tools](extending_the_developer_tools)
* [Implement a settings page](implement_a_settings_page)




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface>

Intercept HTTP requests
=======================



 To intercept HTTP requests, use the [`webRequest`](api/webrequest) API. This API enables you to add listeners for various stages of making an HTTP request. In the listeners, you can: 

 * Get access to request headers and bodies and response headers.
* Cancel and redirect requests.
* Modify request and response headers.

 This article looks at three different uses for the `webRequest` module:

 * Logging request URLs as they are made.
* Redirecting requests.
* Modifying request headers.



Logging request URLs
--------------------



 To see how you can use `webRequest` to log requests, create a new directory called "requests". In that directory, create a file called "manifest.json" and add: 

 
```
{
  "description": "Demonstrating webRequests",
  "manifest\_version": 2,
  "name": "webRequest-demo",
  "version": "1.0",

  "permissions": [
    "webRequest",
    "<all\_urls>"
  ],

  "background": {
    "scripts": ["background.js"]
  }
}

```
 Next, create a file called "background.js" and add:

 
```
function logURL(requestDetails) {
  console.log(`Loading: ${requestDetails.url}`);
}

browser.webRequest.onBeforeRequest.addListener(
  logURL,
  {urls: ["<all\_urls>"]}
);

```
  You use [`onBeforeRequest`](api/webrequest/onbeforerequest) to call the `logURL()` function just before starting the request. The `logURL()` function grabs the URL of the request from the event object and logs it to the browser console. The `{urls: ["<all_urls>"]}` [pattern](match_patterns) means you intercept HTTP requests to all URLs. 

 To test it:

 * [Install the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/)
* Open the [Browser Console](https://firefox-source-docs.mozilla.org/devtools-user/browser_console/) (use `Ctrl + Shift + J`)
* Enable *Show Content Messages* in the menu: ![Browser console menu: Show Content Messages]
* Open some web pages.

  In the Browser Console, you should see the URLs for any resources the browser requests. For example, this screenshot shows the URLs from loading a Wikipedia page: 

  ![Browser console menu: URLs from extension] 


Redirecting requests
--------------------



Now use `webRequest` to redirect HTTP requests. First, replace "manifest.json" with this:

 
```
{

  "description": "Demonstrating webRequests",
  "manifest\_version": 2,
  "name": "webRequest-demo",
  "version": "1.0",

  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "https://developer.mozilla.org/"
  ],

  "background": {
    "scripts": ["background.js"]
  }

}

```
 The changes here:

 * Add the `webRequestBlocking` [`permission`](manifest.json/permissions). This extra permission is needed when an extension wants to modify a request.
* Replace the `<all_urls>` permission with individual [host permissions](manifest.json/permissions#host_permissions), as this is good practice to minimize the number of requested permissions.

 Next, replace "background.js" with this:

 
```
let pattern = "https://developer.mozilla.org/\*";
const targetUrl = "https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your\_second\_WebExtension/frog.jpg";

function redirect(requestDetails) {
  console.log(`Redirecting: ${requestDetails.url}`);
  if (requestDetails.url === targetUrl) {
    return;
  }
  return {
    redirectUrl: targetUrl
  };
}

browser.webRequest.onBeforeRequest.addListener(
  redirect,
  {urls:[pattern], types:["image"]},
  ["blocking"]
);

```
  Again, you use the [`onBeforeRequest`](api/webrequest/onbeforerequest) event listener to run a function just before each request is made. This function replaces the `redirectUrl` with the target URL specified in the function. In this case, the frog image from the [your second extension tutorial](your_second_webextension). 

  This time you are not intercepting every request: the `{urls:[pattern], types:["image"]}` option specifies that you only intercept requests (1) to URLs residing under "<https://developer.mozilla.org/>" and (2) for image resources. See [`webRequest.RequestFilter`](api/webrequest/requestfilter) for more on this. 

  Also, note that you're passing an option called `"blocking"`: you must pass this whenever you want to modify the request. It makes the listener function block the network request, so the browser waits for the listener to return before continuing. See the [`webRequest.onBeforeRequest`](api/webrequest/onbeforerequest) documentation for more on `"blocking"`. 

 To test it out, open a page on MDN that contains images (for example, [the page listing extension user interface components](user_interface)), [reload the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/#reloading_a_temporary_add-on), and then reload the MDN page. You see something like this:

  ![Images on a page replaced with a frog image](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests/beastify_by_redirect.png) 


Modifying request headers
-------------------------



 Finally, use `webRequest` to modify request headers. In this example, you change the "User-Agent" header so the browser identifies itself as Opera 12.16, but only when visiting pages under "<http://useragentstring.com/>". 

 Update the "manifest.json" to include `http://useragentstring.com/` like this:

 
```
{
  "description": "Demonstrating webRequests",
  "manifest\_version": 2,
  "name": "webRequest-demo",
  "version": "1.0",

  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "http://useragentstring.com/"
  ],

  "background": {
    "scripts": ["background.js"]
  }
}

```
 Replace "background.js" with code like this:

 
```
let targetPage = "http://useragentstring.com/\*";

let ua = "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16";

function rewriteUserAgentHeader(e) {
  e.requestHeaders.forEach((header) => {
    if (header.name.toLowerCase() === "user-agent") {
      header.value = ua;
    }
  });
  return {requestHeaders: e.requestHeaders};
}

browser.webRequest.onBeforeSendHeaders.addListener(
  rewriteUserAgentHeader,
  {urls: [targetPage]},
  ["blocking", "requestHeaders"]
);

```
 You use the [`onBeforeSendHeaders`](api/webrequest/onbeforesendheaders) event listener to run a function just before the request headers are sent.

  The listener function is called only for requests to URLs matching the `targetPage` [pattern](match_patterns). Also, note that you again pass `"blocking"` as an option. You also pass `"requestHeaders"`, meaning the listener is passed an array containing the request headers you expect to send. See [`webRequest.onBeforeSendHeaders`](api/webrequest/onbeforesendheaders) for more information on these options. 

  The listener function looks for the "User-Agent" header in the array of request headers, replaces its value with the value of the `ua` variable, and returns the modified array. This modified array is sent to the server. 

  To test it out, open [useragentstring.com](http://useragentstring.com/) and check that it identifies the browser as Firefox. Then reload the extension, reload [useragentstring.com](http://useragentstring.com/), and see that Firefox is now identified as Opera. 

  ![useragentstring.com showing details of the modified user agent string] 


Learn more
----------


To learn about all the things you can do with the `webRequest` API, see its [reference documentation](api/webrequest).



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests>

Example extensions
==================



To illustrate how to use the WebExtension APIs, we maintain a repository of example extensions at <https://github.com/mdn/webextensions-examples>. This article describes how to run these examples and lists the examples along with the WebExtension APIs they demonstrate.

 These examples work in Firefox Nightly: most work in earlier versions of Firefox, but check the [strict\_min\_version](manifest.json/browser_specific_settings) key in the extension's manifest.json to make sure.

  **Warning:** Some examples work only on specific domains or pages. Details of any restrictions are provided in each example's readme file. None of the examples work in private browsing windows by default, see [Extensions in Private Browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing#w_enabling-or-disabling-extensions-in-private-windows) for details.

  To try these examples, clone the repository then:

 1. load the extension from its source folder using the [Load Temporary Add-on](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/) feature. The extension stays loaded until you restart Firefox.
2. open the extension's source folder at the command-line and use [`web-ext`](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/) to run the extension. The extension stays loaded until you restart Firefox.
3. in Firefox use **File** > **Open File** and find the example in the [`build`](https://github.com/mdn/webextensions-examples/tree/master/build) folder. The `build` folder contains built and signed versions of all the examples. This permanently installs the example.

  **Warning:** Please do not submit these WebExtension examples to addons.mozilla.org (AMO); you do not have to sign the add-on WebExtension examples to run them. Follow the steps above.

  If you want to contribute to the repository, [send us a pull request.](https://github.com/mdn/webextensions-examples/blob/master/CONTRIBUTING.md)




| Name | Description | JavaScript APIs |
| --- | --- | --- |
| [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page) | Displays a sidebar that lets you take notes on web pages. | [`storage.local`](api/storage/local)[`tabs.onActivated`](api/tabs/onactivated)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query)[`tabs.Tab`](api/tabs/tab)[`windows.getCurrent`](api/windows/getcurrent)[`windows​.Window`](#) |
| [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css) | Adds a page action to the toolbar. Click the button to apply a red border using injected CSS. Click the button again to remove the CSS. | [`pageAction.getTitle`](api/pageaction/gettitle)[`pageAction.onClicked`](api/pageaction/onclicked)[`pageAction.setIcon`](api/pageaction/seticon)[`pageAction.setTitle`](api/pageaction/settitle)[`pageAction.show`](api/pageaction/show)[`tabs.insertCSS`](api/tabs/insertcss)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query)[`tabs.removeCSS`](api/tabs/removecss)[`tabs.Tab`](api/tabs/tab) |
| [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify) | Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. | [`extension.getURL`](api/extension/geturl)[`runtime.onMessage`](api/runtime/onmessage)[`tabs.executeScript`](api/tabs/executescript)[`tabs.insertCSS`](api/tabs/insertcss)[`tabs.query`](api/tabs/query)[`tabs.removeCSS`](api/tabs/removecss)[`tabs.sendMessage`](api/tabs/sendmessage)[`tabs.Tab`](api/tabs/tab) |
| [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it) | Adds a bookmark button to the toolbar. Click the button to toggle a bookmark for the current page. | [`bookmarks.create`](api/bookmarks/create)[`bookmarks.onCreated`](api/bookmarks/oncreated)[`bookmarks.onRemoved`](api/bookmarks/onremoved)[`bookmarks.remove`](api/bookmarks/remove)[`bookmarks.search`](api/bookmarks/search)[`browserAction.onClicked`](api/browseraction/onclicked)[`browserAction.setIcon`](api/browseraction/seticon)[`browserAction.setTitle`](api/browseraction/settitle)[`tabs.onActivated`](api/tabs/onactivated)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query)[`tabs.Tab`](api/tabs/tab)[`windows.onFocusChanged`](api/windows/onfocuschanged) |
| [borderify](https://github.com/mdn/webextensions-examples/tree/master/borderify) | Adds a solid red border to all webpages matching mozilla.org. |  |
| [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out) | Show a page action after a period of inactivity. Show cat gifs when the page action is clicked. | [`alarms.clearAll`](api/alarms/clearall)[`alarms.create`](api/alarms/create)[`alarms.onAlarm`](api/alarms/onalarm)[`pageAction.hide`](api/pageaction/hide)[`pageAction.onClicked`](api/pageaction/onclicked)[`pageAction.show`](api/pageaction/show)[`tabs.get`](api/tabs/get)[`tabs.onActivated`](api/tabs/onactivated)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query)[`tabs.update`](api/tabs/update) |
| [commands](https://github.com/mdn/webextensions-examples/tree/master/commands) | Demonstrates using the commands API to set up a keyboard shortcut. The shortcut created is accessed using Ctrl+Shift+U (Command+Shift+U on a Mac). | [`commands.getAll`](api/commands/getall)[`commands.onCommand`](api/commands/oncommand)[`commands.reset`](api/commands/reset)[`commands.update`](api/commands/update)[`tabs.create`](api/tabs/create) |
| [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register) | Illustrates how an extension can register URL-matching content scripts at runtime. | [`contentScripts.register`](api/contentscripts/register)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [context-menu-copy-link-with-types](https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types) | Add a context menu option to links to copy the link to the clipboard, as plain text and as a link in rich HTML. | [`contextMenus.create`](api/menus/create)[`contextMenus.onClicked`](api/menus/onclicked)[`tabs.executeScript`](api/tabs/executescript) |
| [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities) | List, create, and remove contextual identities. | [`contextualIdentities.query`](api/contextualidentities/query)[`tabs.create`](api/tabs/create)[`tabs.query`](api/tabs/query)[`tabs.remove`](api/tabs/remove) |
| [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker) | Allows the user to customize the background color and tiled pattern on sites they visit, and also saves their preferences via a cookie, reapplying them whenever they revisit a site they previously customized. | [`cookies.get`](api/cookies/get)[`cookies.onChanged`](api/cookies/onchanged)[`cookies.remove`](api/cookies/remove)[`cookies.set`](api/cookies/set)[`extension.getURL`](api/extension/geturl)[`runtime.onMessage`](api/runtime/onmessage)[`tabs.onActivated`](api/tabs/onactivated)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query)[`tabs.Tab`](api/tabs/tab)[`tabs.sendMessage`](api/tabs/sendmessage) |
| [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels) | Demonstrates some of the devtools APIs. | [`devtools.inspectedWindow`](api/devtools/inspectedwindow)[`devtools.panels`](api/devtools/panels)[`runtime.getURL`](api/runtime/geturl)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage)[`tabs.executeScript`](api/tabs/executescript) |
| [discogs-search](https://github.com/mdn/webextensions-examples/tree/master/discogs-search) | Demonstrates adding a custom search engine with the chrome\_settings\_overrides key. |  |
| [dynamic-theme](https://github.com/mdn/webextensions-examples/tree/master/dynamic-theme) | Dynamic theme example | [`alarms.create`](api/alarms/create)[`alarms.onAlarm`](api/alarms/onalarm)[`theme.update`](api/theme/update) |
| [emoji-substitution](https://github.com/mdn/webextensions-examples/tree/master/emoji-substitution) | Replaces words with emojis. |  |
| [eslint-example](https://github.com/mdn/webextensions-examples/tree/master/eslint-example) | Demonstrates how to configure an extension with eslint. |  |
| [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers) | Demonstrates how to use export helpers like cloneInto to share objects with page scripts. | [`notifications.create`](api/notifications/create)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour) | An example options page, letting you store your favourite colour. | [`browserAction.onClicked`](api/browseraction/onclicked)[`runtime.openOptionsPage`](api/runtime/openoptionspage)[`storage.managed`](api/storage/managed)[`storage.sync`](api/storage/sync) |
| [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs) | Demonstration of the find API. | [`browserAction.onClicked`](api/browseraction/onclicked)[`extension.getBackgroundPage`](api/extension/getbackgroundpage)[`find.find`](api/find/find)[`find.highlightResults`](api/find/highlightresults)[`runtime.getURL`](api/runtime/geturl)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage)[`tabs.create`](api/tabs/create)[`tabs.query`](api/tabs/query)[`tabs.Tab`](api/tabs/tab) |
| [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search) | Demonstrates how to use the omnibox API. | [`omnibox.onInputChanged`](api/omnibox/oninputchanged)[`omnibox.onInputEntered`](api/omnibox/oninputentered)[`omnibox.setDefaultSuggestion`](api/omnibox/setdefaultsuggestion)[`tabs.create`](api/tabs/create)[`tabs.update`](api/tabs/update) |
| [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it) | Demonstrates how to use the browsingData API. | [`browserAction.onClicked`](api/browseraction/onclicked)[`browsingData.remove`](api/browsingdata/remove)[`notifications.create`](api/notifications/create)[`storage.local`](api/storage/local) |
| [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo) | Demonstrates how to use the identity API. | [`browserAction.onClicked`](api/browseraction/onclicked)[`identity.getRedirectURL`](api/identity/getredirecturl)[`identity.launchWebAuthFlow`](api/identity/launchwebauthflow)[`notifications.create`](api/notifications/create) |
| [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter) | History API demo: deletes history items for a given domain | [`history.deleteUrl`](api/history/deleteurl)[`history.search`](api/history/search)[`pageAction.show`](api/pageaction/show)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query) |
| [http-response](https://github.com/mdn/webextensions-examples/tree/master/http-response) | Demonstrates how to rewrite HTTP responses using the webRequest.filterResponseData() API. | [`webRequest.filterResponseData`](api/webrequest/filterresponsedata)[`webRequest.onBeforeRequest`](api/webrequest/onbeforerequest) |
| [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify) | Using a sidebar, illustrates the use of file picker and drag and drop. A content script replaces the current page content with the chosen image. | [`extension.getURL`](api/extension/geturl)[`runtime.onMessage`](api/runtime/onmessage)[`tabs.executeScript`](api/tabs/executescript)[`tabs.query`](api/tabs/query)[`tabs.sendMessage`](api/tabs/sendmessage) |
| [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download) | Shows the last downloaded item, and lets you open or delete it. | [`downloads.erase`](api/downloads/erase)[`downloads.getFileIcon`](api/downloads/getfileicon)[`downloads.open`](api/downloads/open)[`downloads.removeFile`](api/downloads/removefile)[`downloads.search`](api/downloads/search) |
| [list-cookies](https://github.com/mdn/webextensions-examples/tree/master/list-cookies) | This extensions list the cookies in the active tab. | [`cookies.getAll`](api/cookies/getall)[`tabs.query`](api/tabs/query) |
| [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible) | Shows how to set up a single letter access key for a menu item. | [`i18n.getMessage`](api/i18n/getmessage)[`menus.update`](api/menus/update)[`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked) |
| [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo) | Demonstrates adding and manipulating menu items using the menus API. | [`i18n.getMessage`](api/i18n/getmessage)[`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked)[`menus.remove`](api/menus/remove)[`menus.update`](api/menus/update)[`runtime.lastError`](api/runtime/lasterror)[`tabs.executeScript`](api/tabs/executescript) |
| [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open) | Shows how an extension can listen for the display of a menu and then add, remove, or update its menu items. | [`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked)[`menus.onShown`](api/menus/onshown)[`menus.refresh`](api/menus/refresh)[`menus.update`](api/menus/update)[`tabs.update`](api/tabs/update) |
| [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element) | Shows how to detect the page element at the cursor position and remove that element, or a parent element, from the page. This example includes use of the polyfill, illustrating cross-browser extension development. | [`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked)[`menus.getTargetElement`](api/menus/gettargetelement)[`pageAction.openPopup`](api/pageaction/openpopup)[`pageAction.show`](api/pageaction/show)[`tabs.executeScript`](api/tabs/executescript) |
| [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search) | Illustrates how to retrieve a list of search engines and issue a search request, using search engine details added to the context menu for selected text. | [`search.search`](api/search/search)[`search.get`](api/search/get)[`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked) |
| [mocha-client-tests](https://github.com/mdn/webextensions-examples/tree/master/mocha-client-tests) | This example shows two methods of testing an extension: running tests from within the extension, and running tests from the command line using Karma. | [`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [native-messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging) | Example of native messaging, including a Python application and an extension which exchanges messages with it. | [`browserAction.onClicked`](api/browseraction/onclicked)[`runtime.connectNative`](api/runtime/connectnative) |
| [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats) | Demonstration of the webNavigation API, showing basic stats about which pages you've visited. | [`storage.local`](api/storage/local)[`webNavigation.onCommitted`](api/webnavigation/oncommitted)[`webNavigation.onCompleted`](api/webnavigation/oncompleted) |
| [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) | Shows a localized notification when the user clicks on links. | [`extension.getURL`](api/extension/geturl)[`i18n.getMessage`](api/i18n/getmessage)[`notifications.create`](api/notifications/create)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button) | Adds a browser action icon to the toolbar. When the browser action is clicked, the add-on opens a page that was packaged with it. | [`browserAction.onClicked`](api/browseraction/onclicked)[`tabs.create`](api/tabs/create) |
| [page-to-extension-messaging](https://github.com/mdn/webextensions-examples/tree/master/page-to-extension-messaging) | Demonstrates how a web page and a content script can exchange messages. Visit https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html for the demo. |  |
| [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions) | Demonstrates optional permissions using the permissions API. | [`browserAction.onClicked`](api/browseraction/onclicked)[`permissions.getAll`](api/permissions/getall)[`permissions.remove`](api/permissions/remove)[`permissions.request`](api/permissions/request)[`runtime.getURL`](api/runtime/geturl)[`tabs.create`](api/tabs/create) |
| [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme) | Example dynamic theme: sets a dark theme for private windows. | [`theme.reset`](api/theme/reset)[`theme.update`](api/theme/update)[`windows.getAll`](api/windows/getall)[`windows.onCreated`](api/windows/oncreated) |
| [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker) | Uses the proxy API to block requests to hosts specified on a list. | [`extension.getURL`](api/extension/geturl)[`proxy.onRequest`](api/proxy/onrequest)[`proxy.onError`](api/proxy/onerror)[`storage.local`](api/storage/local)[`storage.onChanged`](api/storage/onchanged) |
| [quicknote](https://github.com/mdn/webextensions-examples/tree/master/quicknote) | Allows the user to make quick notes by clicking a button and entering text into the resulting popup. The notes are saved in storage. | [`storage.local`](api/storage/local) |
| [root-cert-stats](https://github.com/mdn/webextensions-examples/tree/master/root-cert-stats) | Shows how to get details about a request's TLS connection. | [`webRequest.getSecurityInfo`](api/webrequest/getsecurityinfo) |
| [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples) | Demo of various runtime APIs. | [`browserAction.onClicked`](api/browseraction/onclicked)[`notifications.create`](api/notifications/create)[`runtime.getManifest`](api/runtime/getmanifest)[`runtime.onInstalled`](api/runtime/oninstalled)[`runtime.reload`](api/runtime/reload) |
| [selection-to-clipboard](https://github.com/mdn/webextensions-examples/tree/master/selection-to-clipboard) | Demonstrates how to write to the clipboard from a content script |  |
| [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state) | Demonstrates how to retrieve extension-defined state from restored tabs. | [`menus.create`](api/menus/create)[`menus.onClicked`](api/menus/onclicked)[`sessions.getTabValue`](api/sessions/gettabvalue)[`sessions.setTabValue`](api/sessions/settabvalue)[`tabs.insertCSS`](api/tabs/insertcss)[`tabs.onCreated`](api/tabs/oncreated)[`tabs.onUpdated`](api/tabs/onupdated)[`tabs.query`](api/tabs/query) |
| [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images) | Demonstrates how to use the idb-file-storage library to store and manipulate files in an extension. | [`browserAction.onClicked`](api/browseraction/onclicked)[`contextMenus.create`](api/menus/create)[`contextMenus.onClicked`](api/menus/onclicked)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage)[`tabs.create`](api/tabs/create)[`windows.create`](api/windows/create) |
| [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials) | Performs basic authentication by supplying stored credentials. | [`storage.local`](api/storage/local)[`webRequest.onAuthRequired`](api/webrequest/onauthrequired)[`webRequest.onCompleted`](api/webrequest/oncompleted)[`webRequest.onErrorOccurred`](api/webrequest/onerroroccurred) |
| [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs) | Demonstrates tab manipulation: opening, closing, moving, zooming tabs. | [`browserAction.setBadgeBackgroundColor`](api/browseraction/setbadgebackgroundcolor)[`browserAction.setBadgeText`](api/browseraction/setbadgetext)[`tabs.create`](api/tabs/create)[`tabs.duplicate`](api/tabs/duplicate)[`tabs.getZoom`](api/tabs/getzoom)[`tabs.move`](api/tabs/move)[`tabs.onCreated`](api/tabs/oncreated)[`tabs.onMoved`](api/tabs/onmoved)[`tabs.onRemoved`](api/tabs/onremoved)[`tabs.query`](api/tabs/query)[`tabs.reload`](api/tabs/reload)[`tabs.remove`](api/tabs/remove)[`tabs.setZoom`](api/tabs/setzoom)[`tabs.Tab`](api/tabs/tab)[`tabs.update`](api/tabs/update) |
| [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar) | A sidebar that integrates with the current theme. | [`theme.getCurrent`](api/theme/getcurrent)[`theme.onUpdated`](api/theme/onupdated)[`windows.getCurrent`](api/windows/getcurrent) |
| [theme-switcher](https://github.com/mdn/webextensions-examples/tree/master/theme-switcher) | An example of how to use the management API for themes. | [`management.getAll`](api/management/getall)[`management.setEnabled`](api/management/setenabled) |
| [themes](https://github.com/mdn/webextensions-examples/tree/master/themes) | A collection of themes illustrating:* weta\_fade: a basic theme employing a single image specified in `theme_frame:`.
* weta\_fade\_chrome: the weta\_fade theme implemented with Chrome compatible manifest keys.
* weta\_tiled: a theme using a tiled image.
* weta\_mirror: a theme using multiple images and aligning those images in the header.
* animated: use of an animated PNG.
 |  |
| [top-sites](https://github.com/mdn/webextensions-examples/tree/master/top-sites) | Demonstration of the topSites API. | [`topSites.get`](api/topsites/get) |
| [user-agent-rewriter](https://github.com/mdn/webextensions-examples/tree/master/user-agent-rewriter) | Demonstrates using the webRequest API to rewrite the User-Agent HTTP header. | [`extension.getBackgroundPage`](api/extension/getbackgroundpage)[`webRequest.onBeforeSendHeaders`](api/webrequest/onbeforesendheaders) |
| [user-script-register](https://github.com/mdn/webextensions-examples/tree/master/user-script-register) | Illustrates how an extension can register URL-matching user scripts at runtime. | [`userScripts.register`](api/userscripts/register)[`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [webpack-modules](https://github.com/mdn/webextensions-examples/tree/master/webpack-modules) | Demonstrates how to use webpack to package npm modules in an extension. | [`runtime.onMessage`](api/runtime/onmessage)[`runtime.sendMessage`](api/runtime/sendmessage) |
| [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator) | Demonstrates how to manipulate windows: opening, closing, resizing windows. | [`windows.create`](api/windows/create)[`windows.getAll`](api/windows/getall)[`windows.getCurrent`](api/windows/getcurrent)[`windows.remove`](api/windows/remove)[`windows.update`](api/windows/update)[`windows​.Window`](#) |
| [open-irc-links](https://github.com/mdn/webextensions-examples/tree/master/open-irc-links) | Demonstrates the use of protocol handlers. |  |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Examples>

Native messaging
================



**Native messaging** enables an extension to exchange messages with a native application, installed on the user's computer. The native messaging serves the extensions without additional accesses over the web.

 Password managers: The native application manages, stores, and encrypts passwords. Then the native application communicates with the extension to populate web forms.

 Native messaging also enables extensions to access resources that are not accessible through WebExtension APIs (e.g., particular hardware).

 The native application is not installed or managed by the browser. The native application is installed, using the underlying operating system's installation machinery. Create a JSON file called the "host manifest" or "app manifest". Install the JSON file in a defined location. The app manifest file will describe how the browser can connect to the native application.

 The extension must request the `"nativeMessaging"` [permission](manifest.json/permissions) or [optional permission](manifest.json/optional_permissions) in the `manifest.json` file. Also, the native application must grant permission for the extension by including the ID in the `"allowed_extensions"` field of the app manifest.

 After installing, the extension can exchange JSON messages with the native application. Use a set of functions in the [`runtime`](api/runtime) API. On the native app side, messages are received using standard input (`stdin`) and sent using standard output (`stdout`).

  ![Application flow: the native app JSON file resides on the users computer, providing resource information to the native application. The read and write functions of the native application interact with the browser extension's runtime events.] 

 Support for native messaging in extensions is mostly compatible with Chrome, with two main differences:

 * The app manifest lists `allowed_extensions` as an array of app IDs, while Chrome lists `allowed_origins`, as an array of `"chrome-extension"` URLs.
* The app manifest is stored in a different location [compared to Chrome](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location).

 There's a complete example in the ["`native-messaging`" directory](https://github.com/mdn/webextensions-examples/tree/master/native-messaging) of the `"webextensions-examples"` repository on GitHub. Most example code in this article is taken from that example.



Setup
-----


### Extension manifest



Extension communicating with a native application:

 * Set the `"nativeMessaging"` [permission](manifest.json/permissions) or [optional permission](manifest.json/optional_permissions) in the [`manifest.json`](manifest.json) file.
* Specify your add-on ID explicitly. Use the [`browser_specific_settings`](manifest.json/browser_specific_settings) manifest key. (The app's manifest will identify the set of extensions that allow connecting to the IDs).

 Example `manifest.json` file:

 
```
{

  "description": "Native messaging example add-on",
  "manifest\_version": 2,
  "name": "Native messaging example",
  "version": "1.0",
  "icons": {
    "48": "icons/message.svg"
  },

  "browser\_specific\_settings": {
    "gecko": {
      "id": "ping\_pong@example.org",
      "strict\_min\_version": "50.0"
    }
  },

  "background": {
    "scripts": ["background.js"]
  },

  "browser\_action": {
    "default\_icon": "icons/message.svg"
  },

  "permissions": ["nativeMessaging"]

}

```
  **Note:** Chrome does not support the [browser\_specific\_settings](manifest.json/browser_specific_settings) key. You will need to use another manifest without this key to install an equivalent WebExtension on Chrome. See [Chrome incompatibilities below](#chrome_incompatibilities).

   **Note:** When using optional permission, check that permission has been granted and, where necessary, request permission from the user with the [`permissions`](api/permissions) API before communicating with the native application.

 
### App manifest



The app manifest describes to the browser how it can connect to the native application.

 The app manifest file must be installed along with the native application. The browser reads and validates app manifest files, but it does not install or manage them. The security model for when and how these files are installed and updated is much more like that for native applications than that for extensions using WebExtension APIs.

 For details of native app manifest syntax and location, see [Native manifests](native_manifests).

 For example, here's a manifest for the `"ping_pong"` native application:

 
```
{
  "name": "ping\_pong",
  "description": "Example host for native messaging",
  "path": "/path/to/native-messaging/app/ping\_pong.py",
  "type": "stdio",
  "allowed\_extensions": [ "ping\_pong@example.org" ]
}

```
 This allows the extension whose ID is `"ping_pong@example.org"` to connect, by passing the name `"ping_pong"` into the relevant [`runtime`](api/runtime) API function. The application itself is at `"/path/to/native-messaging/app/ping_pong.py"`.

  **Note:** Chrome identifies allowed extensions with another key: `allowed_origins`, using the ID of the WebExtension. Refer to [Chrome documentation for more details](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host) and see [Chrome incompatibilities below](#chrome_incompatibilities).

 
### Windows setup



As an example, you can also refer to [the readme on the native messaging extension on GitHub](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup). If you want to check your local setup after having forked this repository on a Windows machine, you may run `check_config_win.py` to troubleshoot some issues.

 #### App manifest

 In the example above, the native application is a Python script. It can be difficult to get Windows to run Python scripts reliably in this way, so an alternative is to provide a `.bat` file, and link to that from the application's manifest:

 
```
{
  "name": "ping\_pong",
  "description": "Example host for native messaging",
  "path": "c:\\path\\to\\native-messaging\\app\\ping\_pong\_win.bat",
  "type": "stdio",
  "allowed\_extensions": [ "ping\_pong@example.org" ]
}

```
 (See note above about [Chrome compatibility](#chrome_incompatibilities) regarding the `allowed_extensions` key and its counterpart in Chrome).

 The batch file then invokes the Python script:

 
```
@echo off

python -u "c:\\path\\to\\native-messaging\\app\\ping\_pong.py"

```
 #### Registry

 The browser finds the extension based on registry keys which are located in a specific location. You need to add them either programmatically with your final application or manually if you are using the example from GitHub. For more details, refer to [Manifest location](native_manifests#manifest_location).

 Following with the `ping_pong` example, if using Firefox (see [this page for Chrome](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location)), two registry entries should be created for the messaging to work:

 * `HKEY_CURRENT_USER\Software\Mozilla\NativeMessagingHosts\ping_pong`
	+ The default value for this key should be the path to the *application* manifest: ex. `C:\Users\<myusername>\webextensions-examples\native-messaging\app\ping_pong.json`
* `HKEY_LOCAL_MACHINE\Software\Mozilla\NativeMessagingHosts\ping_pong`
	+ Idem, the default value for this key should be the path to the application manifest.

  **Note:** If you base your work on the example located on GitHub, please read [this part of the readme](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup) and check the output of `check_config_win.py` before installing the WebExtension on your browser.

 
Exchanging messages
-------------------


Given the above setup, an extension can exchange JSON messages with a native application.

### Extension side



Native messaging cannot directly be used in content scripts. You must [do it indirectly via background scripts](content_scripts#communicating_with_background_scripts).

 There are two patterns to use here: **connection-based messaging** and **connectionless messaging**.

 #### Connection-based messaging

 With this pattern you call [`runtime.connectNative()`](api/runtime/connectnative), passing the name of the application (the value of the `"name"` property in the app's manifest). This launches the application if it is not already running and returns a [`runtime.Port`](api/runtime/port) object to the extension.

 Two arguments are passed to the native app when it starts:

 * The complete path to the app manifest.
* (new in Firefox 55) the ID (as given in the [browser\_specific\_settings](manifest.json/browser_specific_settings) `manifest.json` key) of the add-on that started it.

  **Note:** Chrome handles the passed arguments differently:

 * On Linux and Mac, Chrome passes *one* argument: the origin of the extension that started it (in the form `chrome-extension://[extensionID]`). This enables the app to identify the extension.
* On Windows, Chrome passes *two* arguments: the first is the origin of the extension, and the second is a handle to the Chrome native window that started the app.

  The application stays running until the extension calls `Port.disconnect()` or the page that connected to it is closed.

 To send messages using `Port`, call its `postMessage()` function, passing the JSON message to send. To listen for messages using `Port`, add the listener using its `onMessage.addListener()` function.

 Here's an example background script that establishes a connection with the `"ping_pong"` app, listens for messages from it, then sends it a `"ping"` message whenever the user clicks the browser action:

 
```
/\*
On startup, connect to the "ping\_pong" app.
\*/
let port = browser.runtime.connectNative("ping\_pong");

/\*
Listen for messages from the app.
\*/
port.onMessage.addListener((response) => {
  console.log(`Received: ${response}`);
});

/\*
On a click on the browser action, send the app a message.
\*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending: ping");
  port.postMessage("ping");
});

```
 #### Connectionless messaging

 With this pattern you call [`runtime.sendNativeMessage()`](api/runtime/sendnativemessage), passing it:

 * the name of the application
* the JSON message to send
* optionally, a callback.

 A new instance of the app is created for each message. The app passes two arguments when starting:

 * the complete path to the app manifest
* (new in Firefox 55) the ID (as given in the [browser\_specific\_settings](manifest.json/browser_specific_settings) manifest.json key) of the add-on that started it.

 The first message sent by the app is treated as a response to the `sendNativeMessage()` call, and will be passed into the callback.

 Here's the example above, rewritten to use `runtime.sendNativeMessage()`:

 
```
function onResponse(response) {
  console.log(`Received ${response}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

/\*
On a click on the browser action, send the app a message.
\*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending: ping");
  let sending = browser.runtime.sendNativeMessage(
    "ping\_pong",
    "ping");
  sending.then(onResponse, onError);
});

```

### App side



On the application side, you use standard input to receive messages and standard output to send them.

 Each message is serialized using JSON, UTF-8 encoded and is preceded with an unsigned 32-bit value containing the message length in native byte order.

 The maximum size of a single message from the application is 1 MB. The maximum size of a message sent to the application is 4 GB.

 You can quickly get started sending and receiving messages with this NodeJS code:

 
```
#!/usr/local/bin/node

(() => {

    let payloadSize = null;

    // A queue to store the chunks as we read them from stdin.
    // This queue can be flushed when `payloadSize` data has been read
    let chunks = [];

    // Only read the size once for each payload
    const sizeHasBeenRead = () => Boolean(payloadSize);

    // All the data has been read, reset everything for the next message
    const flushChunksQueue = () => {
        payloadSize = null;
        chunks.splice(0);
    };

    const processData = () => {
        // Create one big buffer with all the chunks
        const stringData = Buffer.concat(chunks);

        // The browser will emit the size as a header of the payload,
        // if it hasn't been read yet, do it.
        // The next time we'll need to read the payload size is when all of the data
        // of the current payload has been read (i.e. data.length >= payloadSize + 4)
        if (!sizeHasBeenRead()) {
            payloadSize = stringData.readUInt32LE(0);
        }

        // If the data we have read so far is >= to the size advertised in the header,
        // it means we have all of the data sent.
        // We add 4 here because that's the size of the bytes that hold the payloadSize
        if (stringData.length >= (payloadSize + 4)) {
            // Remove the header
            const contentWithoutSize = stringData.slice(4, (payloadSize + 4));

            // Reset the read size and the queued chunks
            flushChunksQueue();

            const json = JSON.parse(contentWithoutSize);
            // Do something with the data…
         }
    };

    process.stdin.on('readable', () => {
        // A temporary variable holding the nodejs.Buffer of each
        // chunk of data read off stdin
        let chunk = null;

        // Read all of the available data
        while ((chunk = process.stdin.read()) !== null) {
            chunks.push(chunk);
        }

        processData();

    });
})();

```
 Here's another example written in Python. It listens for messages from the extension. Note that the file has to be executable on Linux. If the message is `"ping"`, then it responds with a message `"pong"`.

 This is the Python 2 version:

 
```
#!/usr/bin/env -S python2 -u

# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.

import json
import sys
import struct

# Read a message from stdin and decode it.
def get\_message():
    raw_length = sys.stdin.read(4)
    if not raw_length:
        sys.exit(0)
    message_length = struct.unpack('=I', raw_length)[0]
    message = sys.stdin.read(message_length)
    return json.loads(message)

# Encode a message for transmission, given its content.
def encode\_message(message_content):
    # https://docs.python.org/3/library/json.html#basic-usage
    # To get the most compact JSON representation, you should specify 
    # (',', ':') to eliminate whitespace.
    # We want the most compact representation because the browser rejects
    # messages that exceed 1 MB.
    encoded_content = json.dumps(message_content, separators=(',', ':'))
    encoded_length = struct.pack('=I', len(encoded_content))
    return {'length': encoded_length, 'content': encoded_content}

# Send an encoded message to stdout.
def send\_message(encoded_message):
    sys.stdout.write(encoded_message['length'])
    sys.stdout.write(encoded_message['content'])
    sys.stdout.flush()

while True:
    message = get_message()
    if message == "ping":
        send_message(encode_message("pong"))

```
 In Python 3, the received binary data must be decoded into a string. The content to be sent back to the addon must be encoded into binary data using a struct:

 
```
#!/usr/bin/env -S python3 -u

# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.

import sys
import json
import struct

# Read a message from stdin and decode it.
def getMessage():
    rawLength = sys.stdin.buffer.read(4)
    if len(rawLength) == 0:
        sys.exit(0)
    messageLength = struct.unpack('@I', rawLength)[0]
    message = sys.stdin.buffer.read(messageLength).decode('utf-8')
    return json.loads(message)

# Encode a message for transmission,
# given its content.
def encodeMessage(messageContent):
    # https://docs.python.org/3/library/json.html#basic-usage
    # To get the most compact JSON representation, you should specify 
    # (',', ':') to eliminate whitespace.
    # We want the most compact representation because the browser rejects # messages that exceed 1 MB.
    encodedContent = json.dumps(messageContent, separators=(',', ':')).encode('utf-8')
    encodedLength = struct.pack('@I', len(encodedContent))
    return {'length': encodedLength, 'content': encodedContent}

# Send an encoded message to stdout
def sendMessage(encodedMessage):
    sys.stdout.buffer.write(encodedMessage['length'])
    sys.stdout.buffer.write(encodedMessage['content'])
    sys.stdout.buffer.flush()

while True:
    receivedMessage = getMessage()
    if receivedMessage == "ping":
        sendMessage(encodeMessage("pong"))

```

Closing the native app
----------------------



If you connected to the native application using `runtime.connectNative()`, then it stays running until the extension calls `Port.disconnect()` or the page that connected to it is closed. If you started the native application by sending `runtime.sendNativeMessage()`, then it is closed after it has received the message and sent a response.

 To close the native application:

 * On \*nix systems like macOS and Linux, the browser sends `SIGTERM` to the native application, then `SIGKILL` after the application has had a chance to exit gracefully. These signals propagate to any subprocesses unless they break away into a new process group.
* On Windows, the browser puts the native application's process into a [Job object](https://msdn.microsoft.com/library/windows/desktop/ms684161(v=vs.85).aspx) and kills the job. If the native application launches additional processes and wants them to remain open after the native application is killed, then the native application must launch the additional process with the [`CREATE_BREAKAWAY_FROM_JOB`](https://msdn.microsoft.com/library/windows/desktop/ms684863(v=vs.85).aspx) flag, such as by using `CreateProcess`.


Troubleshooting
---------------



If something goes wrong, check the [browser console](https://extensionworkshop.com/documentation/develop/debugging/#viewing_log_output). If the native application sends any output to stderr, the browser will redirect it to the browser console. So if you've got as far as launching the native application, you will see any error messages it emits.

 If you haven't managed to run the application, you should see an error message giving you a clue about the problem.

 
```
"No such native application <name>"

```
 * Check that the name passed to `runtime.connectNative()` matches the name in the app manifest
* macOS/Linux: check that name of the app manifest is `<name>.json`.
* macOS/Linux: check the native application's manifest file location as mentioned [here](native_manifests#mac_os_x).
* Windows: check that the registry key is in the correct place, and that its name matches the name in the app manifest.
* Windows: check that the path given in the registry key points to the app manifest. 
```
"Error: Invalid application <name>"

```
* Check that the application's name contains no invalid characters. 
```
"'python' is not recognized as an internal or external command, ..."

```
* Windows: if your application is a Python script, check that you have Python installed and have your path set up for it. 
```
"File at path <path> does not exist, or is not executable"

```
* If you see this, then the app manifest has been found successfully.
* Check that the "path" in the app's manifest is correct.
* Windows: check that you've escaped the path separators (`"c:\\path\\to\\file"`).
* Check that the app is at the location pointed to by the `"path"` property in the app's manifest.
* Check that the app is executable. 
```
"This extension does not have permission to use native application <name>"

```
* Check that the `"allowed_extensions"` key in the app manifest contains the add-on's ID. 
```
    "TypeError: browser.runtime.connectNative is not a function"

```
* Check that the extension has the `"nativeMessaging"` permission. 
```
"[object Object]       NativeMessaging.jsm:218"

```
* There was a problem starting the application.


Chrome incompatibilities
------------------------


 There are a number of differences between browsers that affect native messaging in web extensions, including the arguments passed to the native app, location of the manifest file, etc. These differences are discussed in [Chrome incompatibilities > Native messaging](chrome_incompatibilities#native_messaging). 



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging>

manifest\_version
=================





|  |  |
| --- | --- |
| Type | `Number` |
| Mandatory | Yes |
| Example | 
```
"manifest\_version": 2
```
 |

 This key specifies the version of manifest.json used by this extension.



Example
-------



```
"manifest\_version": 2

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `manifest_version` | 4 | 14 | 48 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `v1` | 4–21 | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `v2` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `v3` | 88 | No | 109 | ? | No | 15.4 | ? | ? | 109 | ? | 15.4 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version>

name
====





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | Yes |
| Example | 
```
"name": "My Extension"
```
 |

 Name of the extension. This is used to identify the extension in the browser's user interface and on sites like addons.mozilla.org.

 It's good practice to keep the name short enough to display in the UI. Google Chrome and Microsoft Edge restrict the name length to 45 characters.

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"name": "My Extension"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `name` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name>

description
===========





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"description": "Replaces pictures with pictures of cats."
```
 |

 A short description of the extension, intended for display in the browser's user interface. In Firefox and Chrome this value can be up to 132 characters. The limit in other browsers may differ.

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"description": "Replaces pictures with pictures of cats."

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `description` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description>

icons
=====





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"icons": {
  "48": "icon.png",
  "96": "icon@2x.png"
}
```
 |

 The `icons` key specifies icons for your extension. Those icons will be used to represent the extension in components such as the Add-ons Manager.

 It consists of key-value pairs of image size in px and image path relative to the root directory of the extension.

 If `icons` is not supplied, a standard extension icon will be used by default.

 You should supply at least a main extension icon, ideally 48x48 px in size. This is the default icon that will be used in the Add-ons Manager. You may, however, supply icons of any size and Firefox will attempt to find the best icon to display in different components.

 Firefox will consider the screen resolution when choosing an icon. To deliver the best visual experience to users with high-resolution displays, such as Retina displays, provide double-sized versions of all your icons.



Example
-------



The keys in the `icons` object specify the icon size in px, values specify the relative icon path. This example contains a 48px extension icon and a larger version for high-resolution displays.

 
```
"icons": {
  "48": "icon.png",
  "96": "icon@2x.png"
}

```

SVG
---



You can use SVG and the browser will scale your icon appropriately. There are currently two caveats though:

 1. You need to specify a viewBox in the image. E.g.: 
```
<svg
 xmlns="http://www.w3.org/2000/svg"
 viewBox="0 0 48 48"
 width="48"
 height="48">
  <!-- your svg content -->
</svg>

```
2. Even though you can use one file, you still need to specify various size of the icon in your manifest. E.g.: 
```
"icons": {
  "48": "icon.svg",
  "96": "icon.svg"
}

```

  **Note:** Only Firefox is known to support SVG icons. Chromium has a bug about [unsupported SVG icons](https://crbug.com/29683).

   **Note:** Remember to include the `xmlns` attribute when creating the SVG. Otherwise, Firefox won't be able to display the icon.

   **Note:** If you are using a program like Inkscape for creating SVG, you might want to save it as a "plain SVG". Firefox might be confused by various special namespaces and not display your icon.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `icons` | Yes | Yes | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `svg_icons` | No | No | 92 | ? | No | 16.4 | ? | ? | 92 | ? | 16.4 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons>

content\_scripts
================





|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"content\_scripts": [
  {
    "matches": ["\*://\*.mozilla.org/\*"],
    "js": ["borderify.js"]
  }
]
```
 |

 Instructs the browser to load [content scripts](../content_scripts) into web pages whose URL matches a given pattern.

 This key is an array. Each item is an object which:

 * **must** contain a key named `matches`, which specifies the URL patterns to be matched in order for the scripts to be loaded;
* **may** contain keys named `js` and `css`, which list scripts and/or stylesheets to be loaded into matching pages; and
* **may** contain a number of other properties that control finer aspects of how and when content scripts are loaded.

 Details of all the keys you can include are given in the table below.

 

| Name | Type | Description |
| --- | --- | --- |
| `all_frames` | `Boolean` |  `true`   Inject the scripts specified in `[js](#js)` and `[css](#css)` into all frames matching the specified URL requirements, even if the frame is not the topmost frame in a tab. This does not inject into child frames where only their parent matches the URL requirements and the child frame does not match the URL requirements. The URL requirements are checked for each frame independently.    **Note:** This also applies to any tracker or ad that uses iframes, which means that enabling this could make your content script get called dozens of times on some pages.    `false`  Inject only into frames matching the URL requirements which are the topmost frame in a tab.   Defaults to `false`. |
| `css` | `Array` |  An array of paths, relative to `manifest.json`, referencing CSS files that will be injected into matching pages.   Files are injected in the order given, and at the time specified by `[run\_at](#run_at)`.    **Note:** Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.   |
| `exclude_globs` | `Array` |  An array of strings containing wildcards. See [Matching URL patterns](#matching_url_patterns) below.  |
| `exclude_matches` | `Array` |  An array of [match patterns](../match_patterns). See [Matching URL patterns](#matching_url_patterns) below.  |
| `include_globs` | `Array` |  An array of strings containing wildcards. See [Matching URL patterns](#matching_url_patterns) below.  |
| `js` | `Array` |  An array of paths, relative to `manifest.json`, referencing JavaScript files that will be injected into matching pages.   Files are injected in the order given. This means that, for example, if you include jQuery here followed by another content script, like this:  
```
"js": ["jquery.js", "my-content-script.js"]
```
 Then, `"my-content-script.js"` can use jQuery.  The files are injected after any files in `[css](#css)`, and at the time specified by `[run\_at](#run_at)`.  |
| `match\_about\_blank` | `Boolean` |  Insert the content scripts into pages whose URL is `"about:blank"` or `"about:srcdoc"`, if the URL of the page that opened or created this page [matches the patterns](#matching_url_patterns) specified in the rest of the `content_scripts` key.   This is especially useful to run scripts in empty iframes, whose URL is `"about:blank"`. To do this you should also set the `all_frames` key.   For example, suppose you have a `content_scripts` key like this:  
```
  "content\_scripts": [
    {
      "js": ["my-script.js"],
      "matches": ["https://example.org/"],
      "match\_about\_blank": true,
      "all\_frames": true
    }
  ]
```
  If the user loads `https://example.org/`, and this page embeds an empty iframe, then `"my-script.js"` will be loaded into the iframe.    **Note:** `match_about_blank` is supported in Firefox from version 52.   Note that in Firefox, content scripts won't be injected into empty iframes at `"document_start"`, even if you specify that value in `[run\_at](#run_at)` .   |
| `matches` | `Array` |  An array of [match patterns](../match_patterns). See [Matching URL patterns](#matching_url_patterns) below.  This is the only mandatory key. |
| `run_at` | `String` |  This option determines when the files specified in `[css](#css)` and `[js](#js)` are injected. You can supply one of three strings here, each of which identifies a state in the process of loading a document. The states directly correspond to [`Document.readyState`](https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState):   `"document_start"` Corresponds to `loading`. The DOM is still loading. `"document_end"`  Corresponds to `interactive`. The DOM has finished loading, but resources such as scripts and images may still be loading.  `"document_idle"`  Corresponds to `complete`. The document and all its resources have finished loading.   The default value is `"document_idle"`.  In all cases, files in `[js](#js)` are injected after files in `[css](#css)`.  |



Matching URL patterns
---------------------



The `"content_scripts"` key attaches content scripts to documents based on URL matching: if the document's URL matches the specification in the key, then the script will be attached. There are four properties inside `"content_scripts"` that you can use for this specification:

  `matches`  an array of [match patterns](../match_patterns)

  `exclude_matches`  an array of [match patterns](../match_patterns)

  `include_globs`  an array of [globs](#globs)

  `exclude_globs`  an array of [globs](#globs)

   To match one of these properties, a URL must match at least one of the items in its array. For example, given a property like:

 
```
"matches": ["\*://\*.example.org/\*", "\*://\*.example.com/\*"]

```
 Both `http://example.org/` and `http://example.com/` will match.

 Since `matches` is the only mandatory key, the other three keys are used to limit further the URLs that match. To match the key as a whole, a URL must:

 * match the `matches` property
* AND match the `include_globs` property, if present
* AND NOT match the `exclude_matches` property, if present
* AND NOT match the `exclude_globs` property, if present


### globs



A *glob* is just a string that may contain wildcards.

 There are two types of wildcard, and you can combine them in the same glob:

 1. `*` matches zero or more characters
2. `?` matches exactly one character.

 For example: `"*na?i"` would match `"illuminati"` and `"annunaki"`, but not `"sagnarelli"`.


Example
-------




```
"content\_scripts": [
  {
    "matches": ["\*://\*.mozilla.org/\*"],
    "js": ["borderify.js"]
  }
]

```
 This injects a single content script `borderify.js` into all pages under `mozilla.org` or any of its subdomains, whether served over HTTP or HTTPS.

 
```
  "content\_scripts": [
    {
      "exclude\_matches": ["\*://developer.mozilla.org/\*"],
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["jquery.js", "borderify.js"]
    }
  ]

```
 This injects two content scripts into all pages under `mozilla.org` or any of its subdomains except `developer.mozilla.org`, whether served over HTTP or HTTPS.

 The content scripts see the same view of the DOM and are injected in the order they appear in the array, so `borderify.js` can see global variables added by `jquery.js`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `content_scripts` | YesContent scripts are not applied to tabs already open when the extension is loaded. | 14 | 48 | ? | YesContent scripts are not applied to tabs already open when the extension is loaded. | 14Content scripts are not applied to tabs until the user grants permission via the extension's access popover in the toolbar. | ? | ? | 48 | ? | 15Content scripts are not applied to tabs until the user grants permission via the extension's access alert. | ? |
| `all_frames` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `css` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `exclude_globs` | Yes | 14 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `exclude_matches` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `include_globs` | Yes | 14 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `js` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `match_about_blank` | Yes | 14 | 52Content scripts won't be injected into empty iframes at 'document\_start' even if you specify that value in 'run\_at'. | ? | Yes | No | ? | ? | 52Content scripts won't be injected into empty iframes at 'document\_start' even if you specify that value in 'run\_at'. | ? | No | ? |
| `matches` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `run_at` | Yes | 14 | 48 | ? | Yes | 14Content scripts are not applied to tabs until the user grants permission via the extension's access popover in the toolbar. Additional loads after permission is granted will respect `run_at`. | ? | ? | 48 | ? | 15Content scripts are not applied to tabs until the user grants permission via the extension's access alert. Additional loads after permission is granted will respect `run_at`. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts>

browser\_specific\_settings
===========================




|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory |  Usually, no (but see also [When do you need an Add-on ID?](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/#when-do-you-need-an-add-on-id)). Mandatory if the extension ID cannot be determined, see [`browser_specific_settings.gecko.id`](#firefox_gecko_properties).  |
| Example | 
```
"browser\_specific\_settings": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0"
  }
}

```
 |


Description
-----------


The `browser_specific_settings` key contains keys that are specific to a particular host application.

### Firefox (Gecko) properties



Firefox stores its browser specific settings in the `gecko` subkey, which has the following properties:

  `id`  The extension ID. For extensions submitted to [addons.mozilla.org](https://addons.mozilla.org/) (AMO), see [Extensions and the Add-on ID](https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/) to determine when you need to specify the ID. When required by AMO, this property must contain 80 characters or less. For extensions not submitted to AMO, if the extension is unsigned (and not loaded using `about:debugging`) an ID is required; otherwise, ID is optional.

  `strict_min_version`  Minimum version of Gecko to support. Versions containing a "\*" are not valid in this field. Defaults to "42a1".

  `strict_max_version`  Maximum version of Gecko to support. If the Firefox version on which the extension is being installed or run is above this version, then the extension will be disabled, or not permitted to be installed. Defaults to "\*", which disables checking for a maximum version.

  `update_url`  Is a link to an [extension update manifest](https://extensionworkshop.com/documentation/manage/updating-your-extension/). Note that the link must begin with "https". This key is for managing extension updates yourself (i.e. not through AMO).

   See the list of [valid Gecko versions](https://addons.mozilla.org/api/v5/applications/firefox/).

 #### Extension ID format

 The extension ID must be one of the following:

 * [GUID](https://en.wikipedia.org/wiki/Universally_unique_identifier)
* A string formatted like an email address: `extensionname@example.org`

 The latter format is easier to generate and manipulate. Be aware that using a real email address here may attract spam.

 For example:

 
```
"id": "extensionname@example.org"

```
 
```
"id": "{daf44bf7-a45e-4450-979c-91cf07434c3d}"

```

### Microsoft Edge properties



 **Warning:** Adding Edge-specific properties to the manifest caused an error prior to Firefox 69 which can prevent the extension from installing.

  Microsoft Edge stores its browser specific settings in the `edge` subkey, which has the following properties:

  `browser_action_next_to_addressbar`  Boolean property which controls the placement of the [browser action](../browser_actions).

 * `true` is equivalent to setting [`browser_action.default_area`](browser_action#syntax) to `navbar`.
* `false` is equivalent to setting [`browser_action.default_area`](browser_action#syntax) to `menupanel`.

  
### Safari properties



 **Warning:** Adding Safari-specific properties to the manifest caused an error prior to Firefox 69 which can prevent the extension from installing.

  Safari stores its browser specific settings in the `safari` subkey, which has the following properties:

  `strict_min_version`  Minimum version of Safari to support.

  `strict_max_version`  Maximum version of Safari to support.

  
Examples
--------



Example with all possible keys. Note that most extensions will omit `strict_max_version` and `update_url`.

 
```
"browser\_specific\_settings": {
  "gecko": {
    "id": "addon@example.com",
    "strict\_min\_version": "42.0",
    "strict\_max\_version": "50.\*",
    "update\_url": "https://example.com/updates.json"
  },
  "safari": {
    "strict\_min\_version": "14",
    "strict\_max\_version": "20"
  }
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `browser_specific_settings` | No | 15–79 | 42Before Firefox 48, this property was required. | ? | No | 14Supports `strict_min_version` and `strict_max_version` in a `safari` block. | ? | ? | 42Before Firefox 48, this property was required. | ? | 15Supports `strict_min_version` and `strict_max_version` in a `safari` block. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings>

version
=======





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | Yes |
| Example | 
```
"version": "0.1"
```
 |

 The **version string** for the extension.



Version format
--------------



The version string consists of 1 to 4 numbers separated by dots, for example, `1.2.3.4`. Non-zero numbers must not include a leading zero. For example, `2.01` is not allowed; however, `0.2`, `2.0.1`, and `2.10` are allowed.

 Extension stores and browsers may enforce or warn if the version string doesn't comply with this format. They may also apply restrictions to the range of numbers available. For example:

 * [addons.mozilla.org](https://addons.mozilla.org/) (AMO) allows version strings using numbers of up to nine digits, complying with this regular expression `^(0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}$`. Also, from Firefox 108, a warning is provided if an extension is installed with a version number that doesn't match this format.
* The Chrome Web Store requires [numbers between 0 and 65535](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) and does not permit all-zero extension strings. For example, 0.0 or 0.0.0.0 are not permitted.

 It may be possible to create an extension that appears to have a valid version number when run in a browser but doesn't comply with store requirements. Particular care should be taken when developing cross-browser extensions that use large number elements.

 Some browsers and web stores may recognize the <version_name> key. This key enables you to provide a descriptive version string that may be displayed instead of the version number. For example, `1.0 beta`.


### Comparing versions


To determine which of two extension versions is the most recent, the version string numbers are compared left to right. A missing version string element is equivalent to `0`. For example, 1.0 is equivalent to 1.0.0.0. The first version string with a number greater than the corresponding number in the other version string is the most recent. For example, 1.10 is a more recent version than 1.9.

Legacy version formats
----------------------


See [Legacy version formats](version/format) for details of previously supported version strings.

Access the version number in code
---------------------------------



You obtain the extension version in your JavaScript code using:

 
```
console.log(browser.runtime.getManifest().version);

```
 If the manifest contains:

 
```
"version": "0.1"

```
 You see this in the console log:

 
```
"0.1"

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `version` | YesValid Chrome versions are a subset of valid Firefox versions. | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version>

Your second extension
=====================



If you've been through the [Your first extension](your_first_webextension) article, you've already got an idea of how to write an extension. In this article, you'll write a slightly more complex extension that demonstrates a few more of the APIs.

 The extension adds a new button to the Firefox toolbar. When the user clicks the button, we display a popup enabling them to choose an animal. Once they choose an animal, we'll replace the current page's content with a picture of the chosen animal.

 To implement this, we will:

 * **define a [browser action](user_interface/browser_action), which is a button attached to the Firefox toolbar**. For the button we'll supply:
	+ an icon, called "beasts-32.png"
	+ a popup to open when the button is pressed. The popup will include HTML, CSS, and JavaScript.
* **define an icon for the extension**, called "beasts-48.png". This will be shown in the Add-ons Manager.
* **write a content script, "beastify.js" that will be injected into web pages**. This is the code that will actually modify the pages.
* **package some images of the animals, to replace images in the web page**. We'll make the images "web accessible resources" so the web page can refer to them.

 You could visualize the overall structure of the extension like this:

  ![The manifest.json file includes icons, browser actions, including popups, and web accessible resources. The choose beast javascript popup resource calls in the beastify script.] 

 It's a simple extension, but shows many of the basic concepts of the WebExtensions API:

 * adding a button to the toolbar
* defining a popup panel using HTML, CSS, and JavaScript
* injecting content scripts into web pages
* communicating between content scripts and the rest of the extension
* packaging resources with your extension that can be used by web pages

 You can find [complete source code for the extension on GitHub](https://github.com/mdn/webextensions-examples/tree/master/beastify).



Writing the extension
---------------------



Create a new directory and navigate to it:

 
```
mkdir beastify
cd beastify

```

### manifest.json



Now create a new file called "manifest.json", and give it the following contents:

 
```
{
  "manifest\_version": 2,
  "name": "Beastify",
  "version": "1.0",

  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
  "homepage\_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
  "icons": {
    "48": "icons/beasts-48.png"
  },

  "permissions": [
    "activeTab"
  ],

  "browser\_action": {
    "default\_icon": "icons/beasts-32.png",
    "default\_title": "Beastify",
    "default\_popup": "popup/choose\_beast.html"
  },

  "web\_accessible\_resources": [
    "beasts/frog.jpg",
    "beasts/turtle.jpg",
    "beasts/snake.jpg"
  ]
}

```
 * The first three keys: [`manifest_version`](manifest.json/manifest_version), [`name`](manifest.json/name), and [`version`](manifest.json/version), are mandatory and contain basic metadata for the extension.
* [`description`](manifest.json/description) and [`homepage_url`](manifest.json/homepage_url) are optional, but recommended: they provide useful information about the extension.
* [`icons`](manifest.json/icons) is optional, but recommended: it allows you to specify an icon for the extension, that will be shown in the Add-ons Manager.
* [`permissions`](manifest.json/permissions) lists permissions the extension needs. We're just asking for the [`activeTab` permission](manifest.json/permissions#activetab_permission) here.
* [`browser_action`](manifest.json/browser_action) specifies the toolbar button. We're supplying three pieces of information here:
	+ `default_icon` is mandatory, and points to the icon for the button
	+ `default_title` is optional, and will be shown in a tooltip
	+ `default_popup` is used if you want a popup to be shown when the user clicks the button. We do, so we've included this key and made it point to an HTML file included with the extension.
* [`web_accessible_resources`](manifest.json/web_accessible_resources) lists files that we want to make accessible to web pages. Since the extension replaces the content in the page with images we've packaged with the extension, we need to make these images accessible to the page.

 Note that all paths given are relative to manifest.json itself.


### The icon



The extension should have an icon. This will be shown next to the extension's listing in the Add-ons Manager (you can open this by visiting the URL "about:addons"). Our manifest.json promised that we would have an icon for the toolbar at "icons/beasts-48.png".

 Create the "icons" directory and save an icon there named "beasts-48.png". You could use [the one from our example](https://raw.githubusercontent.com/mdn/webextensions-examples/master/beastify/icons/beasts-48.png), which is taken from the [Aha-Soft's Free Retina iconset](http://www.aha-soft.com/free-icons/free-retina-icon-set/), and used under the terms of its license.

 If you choose to supply your own icon, It should be 48x48 pixels. You could also supply a 96x96 pixel icon, for high-resolution displays, and if you do this it will be specified as the `96` property of the `icons` object in manifest.json:

 
```
"icons": {
  "48": "icons/beasts-48.png",
  "96": "icons/beasts-96.png"
}

```

### The toolbar button



The toolbar button also needs an icon, and our manifest.json promised that we would have an icon for the toolbar at "icons/beasts-32.png".

 Save an icon named "beasts-32.png" in the "icons" directory. You could use [the one from our example](https://raw.githubusercontent.com/mdn/webextensions-examples/master/beastify/icons/beasts-32.png), which is taken from the [IconBeast Lite icon set](http://www.iconbeast.com/free/) and used under the terms of its [license](http://www.iconbeast.com/faq/).

 If you don't supply a popup, then a click event is dispatched to your extension when the user clicks the button. If you do supply a popup, the click event is not dispatched, but instead, the popup is opened. We want a popup, so let's create that next.


### The popup



The function of the popup is to enable the user to choose one of three beasts.

 Create a new directory called "popup" under the extension root. This is where we'll keep the code for the popup. The popup will consist of three files:

 * `choose_beast.html` defines the content of the panel
* `choose_beast.css` styles the content
* `choose_beast.js` handles the user's choice by running a content script in the active tab

 
```
mkdir popup
cd popup
touch choose_beast.html choose_beast.css choose_beast.js

```
 #### choose\_beast.html

 The HTML file looks like this:

 
```
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="choose\_beast.css" />
  </head>

  <body>
    <div id="popup-content">
      <button>Frog</button>
      <button>Turtle</button>
      <button>Snake</button>
      <button type="reset">Reset</button>
    </div>
    <div id="error-content" class="hidden">
      <p>Can't beastify this web page.</p>
      <p>Try a different page.</p>
    </div>
    <script src="choose\_beast.js"></script>
  </body>
</html>

```
 We have a [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) element with an ID of `"popup-content"` that contains a button for each animal choice and a reset button. We have another `<div>` with an ID of `"error-content"` and a class `"hidden"`. We'll use that in case there's a problem initializing the popup.

 Note that we include the CSS and JS files from this file, just like a web page.

 #### choose\_beast.css

 The CSS fixes the size of the popup, ensures that the three choices fill the space, and gives them some basic styling. It also hides elements with `class="hidden"`: this means that our `<div id="error-content"...` element will be hidden by default.

 
```
html, body {
  width: 100px;
}

.hidden {
  display: none;
}

button {
  border: none;
  width: 100%;
  margin: 3% auto;
  padding: 4px;
  text-align: center;
  font-size: 1.5em;
  cursor: pointer;
  background-color: #E5F2F2;
}

button:hover {
  background-color: #CFF2F2;
}

button[type="reset"] {
  background-color: #FBFBC9;
}

button[type="reset"]:hover {
  background-color: #EAEA9D;
}

```
 #### choose\_beast.js

 Here's the JavaScript for the popup:

 
```
/\*\*
 \* CSS to hide everything on the page,
 \* except for elements that have the "beastify-image" class.
 \*/
const hidePage = `body > :not(.beastify-image) {
 display: none;
 }`;

/\*\*
 \* Listen for clicks on the buttons, and send the appropriate message to
 \* the content script in the page.
 \*/
function listenForClicks() {
  document.addEventListener("click", (e) => {
    /\*\*
 \* Given the name of a beast, get the URL to the corresponding image.
 \*/
    function beastNameToURL(beastName) {
      switch (beastName) {
        case "Frog":
          return browser.runtime.getURL("beasts/frog.jpg");
        case "Snake":
          return browser.runtime.getURL("beasts/snake.jpg");
        case "Turtle":
          return browser.runtime.getURL("beasts/turtle.jpg");
      }
    }

    /\*\*
 \* Insert the page-hiding CSS into the active tab,
 \* then get the beast URL and
 \* send a "beastify" message to the content script in the active tab.
 \*/
    function beastify(tabs) {
      browser.tabs.insertCSS({ code: hidePage }).then(() => {
        const url = beastNameToURL(e.target.textContent);
        browser.tabs.sendMessage(tabs[0].id, {
          command: "beastify",
          beastURL: url
        });
      });
    }

    /\*\*
 \* Remove the page-hiding CSS from the active tab,
 \* send a "reset" message to the content script in the active tab.
 \*/
    function reset(tabs) {
      browser.tabs.removeCSS({ code: hidePage }).then(() => {
        browser.tabs.sendMessage(tabs[0].id, {
          command: "reset",
        });
      });
    }

    /\*\*
 \* Just log the error to the console.
 \*/
    function reportError(error) {
      console.error(`Could not beastify: ${error}`);
    }

    /\*\*
 \* Get the active tab,
 \* then call "beastify()" or "reset()" as appropriate.
 \*/
    if (e.target.tagName !== "BUTTON" || !e.target.closest("#popup-content")) {
      // Ignore when click is not on a button within <div id="popup-content">.
      return;
    } 
    if (e.target.type === "reset") {
      browser.tabs.query({active: true, currentWindow: true})
        .then(reset)
        .catch(reportError);
    } else {
      browser.tabs.query({active: true, currentWindow: true})
        .then(beastify)
        .catch(reportError);
    }
  });
}

/\*\*
 \* There was an error executing the script.
 \* Display the popup's error message, and hide the normal UI.
 \*/
function reportExecuteScriptError(error) {
  document.querySelector("#popup-content").classList.add("hidden");
  document.querySelector("#error-content").classList.remove("hidden");
  console.error(`Failed to execute beastify content script: ${error.message}`);
}

/\*\*
 \* When the popup loads, inject a content script into the active tab,
 \* and add a click handler.
 \* If we couldn't inject the script, handle the error.
 \*/
browser.tabs
  .executeScript({ file: "/content\_scripts/beastify.js" })
  .then(listenForClicks)
  .catch(reportExecuteScriptError);

```
 The place to start here is line 99. The popup script executes a content script in the active tab as soon as the popup is loaded, using the [`browser.tabs.executeScript()`](api/tabs/executescript) API. If executing the content script is successful, then the content script will stay loaded in the page until the tab is closed or the user navigates to a different page.

 A common reason the `browser.tabs.executeScript()` call might fail is that you can't execute content scripts in all pages. For example, you can't execute them in privileged browser pages like about:debugging, and you can't execute them on pages in the [addons.mozilla.org](https://addons.mozilla.org/) domain. If it does fail, `reportExecuteScriptError()` will hide the `<div id="popup-content">` element, show the `<div id="error-content"...` element, and log an error to the [console](https://extensionworkshop.com/documentation/develop/debugging/).

 If executing the content script is successful, we call `listenForClicks()`. This listens for clicks on the popup.

 * If the click was not on a button in the popup, we ignore it and do nothing.
* If the click was on a button with `type="reset"`, then we call `reset()`.
* If the click was on any other button (i.e. the beast buttons), then we call `beastify()`.

 The `beastify()` function does three things:

 * map the button clicked to a URL pointing to an image of a particular beast
* hide the page's whole content by injecting some CSS, using the [`browser.tabs.insertCSS()`](api/tabs/insertcss) API
* send a "beastify" message to the content script using the [`browser.tabs.sendMessage()`](api/tabs/sendmessage) API, asking it to beastify the page, and passing it the URL to the beast image.

 The `reset()` function essentially undoes a beastify:

 * remove the CSS we added, using the [`browser.tabs.removeCSS()`](api/tabs/removecss) API
* send a "reset" message to the content script asking it to reset the page.


### The content script



Create a new directory, under the extension root, called "content\_scripts" and create a new file in it called "beastify.js", with the following contents:

 
```
(() => {
  /\*\*
 \* Check and set a global guard variable.
 \* If this content script is injected into the same page again,
 \* it will do nothing next time.
 \*/
  if (window.hasRun) {
    return;
  }
  window.hasRun = true;

  /\*\*
 \* Given a URL to a beast image, remove all existing beasts, then
 \* create and style an IMG node pointing to
 \* that image, then insert the node into the document.
 \*/
  function insertBeast(beastURL) {
    removeExistingBeasts();
    const beastImage = document.createElement("img");
    beastImage.setAttribute("src", beastURL);
    beastImage.style.height = "100vh";
    beastImage.className = "beastify-image";
    document.body.appendChild(beastImage);
  }

  /\*\*
 \* Remove every beast from the page.
 \*/
  function removeExistingBeasts() {
    const existingBeasts = document.querySelectorAll(".beastify-image");
    for (const beast of existingBeasts) {
      beast.remove();
    }
  }

  /\*\*
 \* Listen for messages from the background script.
 \* Call "insertBeast()" or "removeExistingBeasts()".
 \*/
  browser.runtime.onMessage.addListener((message) => {
    if (message.command === "beastify") {
      insertBeast(message.beastURL);
    } else if (message.command === "reset") {
      removeExistingBeasts();
    }
  });
})();

```
 The first thing the content script does is to check for a global variable `window.hasRun`: if it's set the script returns early, otherwise it sets `window.hasRun` and continues. The reason we do this is that every time the user opens the popup, the popup executes a content script in the active tab, so we could have multiple instances of the script running in a single tab. If this happens, we need to make sure that only the first instance is actually going to do anything.

 After that, the place to start is line 40, where the content script listens for messages from the popup, using the [`browser.runtime.onMessage`](api/runtime/onmessage) API. We saw above that the popup script can send two different sorts of messages: "beastify" and "reset".

 * if the message is "beastify", we expect it to contain a URL pointing to a beast image. We remove any beasts that might have been added by previous "beastify" calls, then construct and append an [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element whose `src` attribute is set to the beast URL.
* if the message is "reset", we just remove any beasts that might have been added.


### The beasts



Finally, we need to include the images of the beasts.

 Create a new directory called "beasts", and add the three images in that directory, with the appropriate names. You can get the images from [the GitHub repository](https://github.com/mdn/webextensions-examples/tree/master/beastify/beasts), or from here:

  ![A brown frog.] 

  ![An emerald tree boa with white stripes.] 

  ![A red-eared slider turtle.] 


Testing it out
--------------



First, double check that you have the right files in the right places:

 
```
beastify/

    beasts/
        frog.jpg
        snake.jpg
        turtle.jpg

    content_scripts/
        beastify.js

    icons/
        beasts-32.png
        beasts-48.png

    popup/
        choose_beast.css
        choose_beast.html
        choose_beast.js

    manifest.json

```
 Now load the extension as a temporary add-on. Open "about:debugging" in Firefox, click "Load Temporary Add-on", and select your **manifest.json** file. You should then see the extension's icon appear in the Firefox toolbar:

  ![The beastify icon in the Firefox toolbar] 

 Open a web page, click the icon, select a beast, and see the web page change:

  ![A page replaced with the image of a turtle](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension/beastify_page.png) 


Developing from the command line
--------------------------------



You can automate the temporary installation step by using the [web-ext](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/) tool. Try this:

 
```
cd beastify
web-ext run

```

What's next?
------------



Now that you've created a more advanced WebExtension for Firefox:

 * [read about the anatomy of an extension](anatomy_of_a_webextension)
* [explore the extension examples](examples)
* [find out what you need to develop, test, and publish your extension](what_next_)
* [take your learning further](what_next_#continue_your_learning_experience).




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension>

What next?
==========



You'll now be ready to start turning your idea for a browser extension into reality. Before you start that journey, it's worth being aware of a few things that will help to make it a smooth one.

 You can find more about many of the things discussed on this page on [Extension Workshop](https://extensionworkshop.com), a website dedicated to helping you write, test, publish, and distribute extensions for Firefox.



Your development environment
----------------------------



You don't need any special development or build environment tools to create browser extensions: It's entirely possible to create great browser extensions with no more than a text editor. However, you may have been developing for the web and have a set of tools and an environment you want to reuse. If you do, you need to be aware of a couple of things.

 If you use minification or obfuscation tools to deliver your final code, you'll need to provide your source code to [the AMO review process](#the_review_process). Also, the tools you use—those for minification, obfuscation, and build processes—will need to be open source (or offer unlimited free use) and be available to run on the reviewer's computer (Windows, Mac, or Linux). Unfortunately, our reviewers can't work with commercial or web-based tools.

 [Learn more about development tools on Extension Workshop](https://extensionworkshop.com/documentation/develop/browser-extension-development-tools/)


Third-party libraries
---------------------



Third-party libraries are a great way to add complex features or functionality to your browser extensions quickly. When you submit an extension to the [AMO review process](#the_review_process), the process will also consider any third-party libraries used. To streamline the review, make sure you always download third-party libraries from their official website or repository, and if the library is minified provide a link to the source code. Please note that third-party libraries cannot be modified in any way.

 [Learn more about submitting source code on Extension Workshop](https://extensionworkshop.com/documentation/publish/source-code-submission/)


The Firefox Add-on Distribution Agreement
-----------------------------------------



Browser extensions need to be signed to install into the release or beta versions of Firefox. Signing takes place in addons.mozilla.org (AMO) and is subject to the terms and conditions of the Firefox Add-on Distribution Agreement. The goal of the agreement is to ensure Firefox users get access to well supported, quality add-ons that enhance the Firefox experience.

 [Read the agreement on Extension Workshop](https://extensionworkshop.com/documentation/publish/firefox-add-on-distribution-agreement/)

 [Learn more about signing on Extension Workshop](https://extensionworkshop.com/documentation/publish/signing-and-distribution-overview/)


The review process
------------------



When a browser extension is submitted for signing, it's subject to automated review. It may also be subject to a manual review, when the automated review determines that a manual review is needed. Your browser extension won't be signed until it's passed the automated review and may have its signing revoked if it fails to pass the manual review. The review process follows a strict set of guidelines, so it's easy to check and avoid any likely review problems.

 [Check out the review policy and guidelines on Extension Workshop](https://extensionworkshop.com/documentation/publish/add-on-policies/)


AMO featured browser extensions
-------------------------------



If you choose to list your browser extension on AMO, your extension could be featured on the AMO website, in the Firefox browser's add-on manager, or elsewhere on a Mozilla website. We've compiled a list of guidelines about how extensions are selected for featuring, by following these guidelines you give your extension the best chance of being featured.

 [Learn more about getting your add-ons featured on Extension Workshop](https://extensionworkshop.com/documentation/publish/recommended-extensions/)


Continue your learning experience
---------------------------------



Now you know what lies ahead, it's time to dive into more details about browser extension development. In the sections that follow, you'll discover:

 * More about the fundamental concepts behind browser extensions, starting with details on how to [use the JavaScript APIs](api).
* A guide to the [user interface components](user_interface) available to your browser extensions.
* A collection of how-to guides on achieving key tasks in your extensions or making use of the JavaScript APIs.
* A full reference guide to the [JavaScript APIs](browser_support_for_javascript_apis).
* A full reference guide to the [Manifest keys](manifest.json).

 You'll also want to head on over to Extension Workshop where you'll find everything you need to know about creating extensions for Firefox, including:

 * [an overview of the Firefox extension features](https://extensionworkshop.com/#about)
* [details of the tools and processes for developing and testing](https://extensionworkshop.com/documentation/develop/)
* [how to publish your extension on addons.mozilla.org or distribute it yourself](https://extensionworkshop.com/documentation/publish/)
* [how to manage your published extension](https://extensionworkshop.com/documentation/manage/)
* [an enterprise guide for developing and using extensions](https://extensionworkshop.com/documentation/enterprise/)
* [how to develop themes for Firefox](https://extensionworkshop.com/documentation/themes/)
* [details about the Firefox developer communities](https://extensionworkshop.com/community/)




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/What_next_>

Extension pages
===============



You can include HTML pages in your extension to provide forms, help, or any other content your extension needs.

  ![Example of a simple bundled page displayed as a detached panel.] 

 These pages also get access to the same privileged JavaScript APIs that are available to your extension's background scripts. However, they are in their own tab, with their own JavaScript event queue, their own globals, etc.

 Think of the background page as a "hidden extension page".



Specifying extension pages
--------------------------



You can include HTML files—and associated CSS or JavaScript files—in your extension. The files can be included in the root or organized within meaningful sub-folders.

 
```
/my-extension
    /manifest.json
    /my-page.html
    /my-page.js

```

Displaying extension pages
--------------------------



There are two options for displaying extension pages: [`windows.create()`](../api/windows/create) and [`tabs.create()`](../api/tabs/create).

 Using `windows.create()`, for example, you can open an HTML page into a detached panel (a window without the normal browser UI of address bar, bookmark bar, and alike) to create a dialog-like user experience:

 
```
let createData = {
  type: "detached\_panel",
  url: "panel.html",
  width: 250,
  height: 100,
};
let creating = browser.windows.create(createData);

```
 When the window is no longer needed, it can be closed programmatically.

 For example, after the user clicks a button, you may pass the current window's id to [`windows.remove()`](../api/windows/remove):

 
```
document.getElementById("closeme").addEventListener("click", () => {
  let winId = browser.windows.WINDOW\_ID\_CURRENT;
  let removing = browser.windows.remove(winId);
});

```

Extension pages and history
---------------------------



By default, pages you open in this way will be stored in the user's history, just like normal web pages. If you don't want to have this behavior, use [`history.deleteUrl()`](../api/history/deleteurl) to remove the browser's record:

 
```
function onVisited(historyItem) {
  if (historyItem.url === browser.extension.getURL(myPage)) {
    browser.history.deleteUrl({ url: historyItem.url });
  }
}

browser.history.onVisited.addListener(onVisited);

```
 To use the history API, you must request the "`history`" [permission](../manifest.json/permissions) in your [`manifest.json`](../manifest.json) file.


Web page design
---------------


For details on how to design your web page's to match the style of Firefox, see the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) and [browser styles](browser_styles) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator) example, which implements several of the options for creating windows.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages>

Sidebars
========



A sidebar is a pane that is displayed at the side of the browser window, next to the web page. This page describes sidebars, specifying them, designing them, and examples of use.

 The browser provides a UI that enables the user to select a sidebar to display. For example, Firefox has the "View" > "Sidebar" menu. Each browser window can display its own sidebar, which is displayed on every tab in the window.

 The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

  ![Annotator sidebar with a box allowing the user to take notes about the page.] 

 Using the [`sidebar_action`](../manifest.json/sidebar_action) manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

 Like a browser action popup, the sidebar's contents are specified as an HTML document. When the user opens the sidebar, the sidebar's document is loaded into every open browser window. Each window gets its own instance of the document. When new windows are opened, they get their own sidebar documents as well.

 A document for a particular tab can be set using the [`sidebarAction.setPanel()`](../api/sidebaraction/setpanel) function. A sidebar can figure out which window it belongs to using the [`windows.getCurrent()`](../api/windows/getcurrent) API:

 
```
// sidebar.js
browser.windows.getCurrent({ populate: true }).then((windowInfo) => {
  myWindowId = windowInfo.id;
});

```
 This is useful if a sidebar wants to display different content for different windows. For an example of this, see the ["annotate-page" example](https://github.com/mdn/webextensions-examples/tree/master/annotate-page).

 Sidebar documents get access to the same set of privileged JavaScript APIs that the extension's background and popup scripts get. They can get direct access to the background page (unless the sidebar belongs to an incognito mode window) using [`runtime.getBackgroundPage()`](../api/runtime/getbackgroundpage), and can interact with content scripts or native applications using messaging APIs like [`tabs.sendMessage()`](../api/tabs/sendmessage) and [`runtime.sendNativeMessage()`](../api/runtime/sendnativemessage).

 Sidebar documents are unloaded when their browser window is closed or when the user closes the sidebar. This means that unlike background pages, sidebar documents don't stay loaded all the time, but unlike browser action popups, they stay loaded while the user interacts with web pages.

 When an extension that defines a sidebar is first installed, its sidebar will be opened automatically. This is intended to help the user understand that the extension includes a sidebar. Note that it's not possible for an extension to open sidebars programmatically: sidebars can only be opened by the user.



Specifying sidebars
-------------------



To specify a sidebar, define the default document with the [`sidebar_action`](../manifest.json/sidebar_action) manifest.json key, alongside a default title and icon:

 
```
"sidebar\_action": {
  "default\_title": "My sidebar",
  "default\_panel": "sidebar.html",
  "default\_icon": "sidebar\_icon.png"
}

```
 The title, panel, and icon can be changed programmatically using the [`sidebarAction`](../api/sidebaraction) API.

 Title and icon are shown to the user in any UI provided by the browser to list sidebars, such as the "View > Sidebar" menu in Firefox.


Sidebar design
--------------


For details on how to design a sidebar's web page to match the style of Firefox, see the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Example
-------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page) example which implements a sidebar.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars>

Popups
======



A popup is a dialog that's associated with a [toolbar button](browser_action) or [address bar button](page_actions). This page describes popups in general, specifying them, debugging, resizing, and designing them, as well as examples of use.

  ![Page action pop-up example with three options: kittens, puppies, and reset.] 

 When the user clicks the button, the popup is shown. When the user clicks anywhere outside the popup, the popup is closed. The popup can be closed programmatically by calling [`window.close()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/close) from a script running in the popup. However, you can't open the popup programmatically from an extension's JavaScript; it can be opened only in response to a user action.

 You can define a keyboard shortcut that opens the popup using the `"_execute_browser_action"` and `"_execute_page_action"` shortcuts in Manifest V2 and `"_execute_action"`and, where supported, `"_execute_page_action"` shortcuts in Manifest V3. See the documentation for the special shortcuts in manifest.json key [`commands`](../manifest.json/commands#special_shortcuts).



Specifying a popup
------------------



The popup is specified as an HTML file, which can include CSS and JavaScript files, as a normal web page does. Unlike a normal page, though, the JavaScript can use all the [WebExtension APIs](../api) that the extension has [permissions](../manifest.json/permissions) for.

 The popup's document is loaded every time the popup is shown, and unloaded every time the popup is closed.

 The HTML file is included in the extension and specified as part of the [`browser_action`](../manifest.json/browser_action) or [`page_action`](../manifest.json/page_action) key by `"default_popup"` in the manifest.json:

 
```
  "browser\_action": {
    "default\_icon": "icons/beasts-32.png",
    "default\_title": "Beastify",
    "default\_popup": "popup/choose\_beast.html"
  }

```
 You can ask the browser to include a stylesheet in your popup that will make it look consistent with the browser's UI. To do this, include `"browser_style": true` in the [`browser_action`](../manifest.json/browser_action) or [page\_action](../manifest.json/page_action) key.

 Popups have a Content Security Policy that restricts the sources from which they can load resources, and disallows some unsafe practices such as the use of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). See [Content Security Policy](../content_security_policy) for more details on this.


Debugging popups
----------------


You can debug a popup's markup and JavaScript using the Add-on Debugger, but you'll need to turn on the Disable popup auto-hide feature to prevent popups from hiding when you click outside them. [Read about debugging popups](https://extensionworkshop.com/documentation/develop/debugging/#debugging_popups).

Popup resizing
--------------



Popups resize automatically to fit their content. The algorithm for this may differ from one browser to another.

 In Firefox, the size is calculated just before the popup is shown, and at most 10 times per second after DOM mutations. For strict mode documents, the size is calculated based on the layout size of the [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body) element. For quirks mode, it's the [`<html>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html) element. Firefox calculates the preferred width of the contents of that element, reflows it to that width, and then resizes so there's no vertical scrolling. It will grow to a size of **800x600 pixels** at most if that fits on the user's screen. (Prior to Firefox 60 [it was only 680px](https://bugzil.la/1434177).) If the user [moves the extension's button to the menu](https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars#w_customize-the-menu-or-the-toolbar) or it appears in the toolbar overflow, then the popup appears inside the menu's panel and is given a fixed width.

 When setting the popup `width` in CSS, you should set the it in the [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body) and not in the `:root`.

 In Firefox Android 57, the popup is shown as a normal page in a new tab.


Popup design
------------


For details on how to design your popup's web page to match the style of Firefox, see the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify) example, which implements a browser action with a popup.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups>

Toolbar button
==============



 Commonly referred to as a [browser action](../api/browseraction), this user interface option is a button added to the browser toolbar. Users click the button to interact with your extension. ![A custom browser action icon it the browser tool bar that looks like paw print.] 

 The toolbar button (browser action) is very like the address bar button (page action). For the differences, and guidance on when to use what, see [Page actions and browser actions](page_actions#page_actions_and_browser_actions).



Specifying the browser action
-----------------------------



You define the browser action's properties using the [`browser_action`](../manifest.json/browser_action) key in manifest.json:

 
```
"browser\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?"
}

```
 The only mandatory key is `default_icon`.

 There are two ways to specify a browser action: with or without a [popup](popups). If you don't specify a popup, when the user clicks the button an event is dispatched to the extension, which the extension listens for using [`browserAction.onClicked`](../api/browseraction/onclicked):

 
```
browser.browserAction.onClicked.addListener(handleClick);

```
 If you specify a popup, the click event is not dispatched: instead, the popup is shown when the user clicks the button. The user is able to interact with the popup and it closes automatically when the user clicks outside it. See the [Popup](popups) article for more details on creating and managing popups.

 Note that your extension can have only one browser action.

 You can change many of the browser action properties programmatically using the [`browserAction`](../api/browseraction) API.


Icons
-----


For details on how to create icons to use with your browser action, see [Iconography](https://acorn.firefox.com/latest/styles/iconography.html) in the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------



The [`webextensions-examples`](https://github.com/mdn/webextensions-examples) repository on GitHub contains two examples of extensions that implement browser actions:

 * [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it) uses a browser action without a popup
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify) uses a browser action with a popup




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action>

Address bar button
==================



Commonly referred to as a [page action](../api/pageaction) button, this user interface option is a button added to the browser address bar. Users click the button to interact with extensions.

  ![Page action button is an icon of a dog paw print] 



Page actions and browser actions
--------------------------------



The address bar button (or page action) is similar to the toolbar button (or browser action).

 The differences are:

 * **The button's location:**
	+ The page action is displayed inside the browser address bar.
	+ The browser action is displayed outside the address bar, in the browser toolbar.
* **The button's visibility:**
	+ The page action is hidden by default (although this default can be changed via the `show_matches` and `hide_matches` [manifest key](../manifest.json/page_action) properties), and you call [`pageAction.show()`](../api/pageaction/show) and [`pageAction.hide()`](../api/pageaction/hide) to show or hide it in specific tabs.
	+ The browser action is always displayed.

 Use a page action when the action relates to the current page. Use a browser action when the action relates to the browser as a whole or to many pages. For example:

 

| Type | Bookmarks action | Content action | Tabs operation |
| --- | --- | --- | --- |
| page action | Bookmark this page | Reddit enhancement | Send tab |
| browser action | Show all bookmarks | Enable ad-blocking | Sync all open tabs |


Specifying the page action
--------------------------



You define the page action's properties using the [`page_action`](../manifest.json/page_action) key in manifest.json:

 
```
"page\_action": {
  "browser\_style": true,
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?"
}

```
 The only mandatory key is `default_icon`.

 There are two ways to specify a page action: with or without a [popup](popups).

 * **Without a popup:** When the user clicks the button, an event is dispatched to the extension, which the extension listens for using [`pageAction.onClicked`](../api/pageaction/onclicked): 
```
browser.pageAction.onClicked.addListener(handleClick);

```
* **With a popup:** the `click` event is not dispatched. Instead, the popup appears when the user clicks the button. The user then interacts with the popup. When the user clicks outside of the popup, it closes automatically. See the [Popup](popups) article for more details on creating and managing popups.

 Note that your extension can have just one page action.

 You can change any of the page action properties programmatically using the [`pageAction`](../api/pageaction) API.


Icons
-----


For details on how to create icons to use with your page action, see [Iconography](https://acorn.firefox.com/latest/styles/iconography.html) in the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out) example which implements a page action without a popup.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions>

Options page
============



An Options page enables you to define preferences for your extension that your users can change. Users can access the options page for an extension from the browser's add-ons manager:


 The way users access the page, and the way it's integrated into the browser's user interface, will vary from one browser to another.

 You can open the page programmatically by calling [`runtime.openOptionsPage()`](../api/runtime/openoptionspage).

 Options pages have a Content Security Policy that restricts the sources from which they can load resources, and disallows some unsafe practices such as the use of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). See [Content Security Policy](../content_security_policy) for more details.



Specifying the options page
---------------------------



To create an options page, write an HTML file defining the page. This page can include CSS and JavaScript files, like a normal web page. This page, from the [favourite-color](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour) example, includes a JavaScript file:

 
```
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
  </head>

  <body>
    <form>
      <label for="color">Favorite color</label>
      <input type="text" id="color" name="color" />
      <button type="submit">Save</button>
    </form>
    <script src="options.js"></script>
  </body>
</html>

```
 JavaScript running in the page can use all the [WebExtension APIs](../api) that the add-on has [permissions](../manifest.json/permissions) for. In particular, you can use the [`storage`](../api/storage) API to persist preferences.

 Package the page's files in your extension.

 You also need to include the [`options_ui`](../manifest.json/options_ui) key in your manifest.json file, giving it the URL to the page.

 
```
"options\_ui": {
  "page": "options.html",
  "browser\_style": true
},

```
  **Note:** **Google Chrome** and **Opera** use `chrome_style` instead of `browser_style`, so if you wish to support them, you need to add both keys.

  See the [`options_ui`](../manifest.json/options_ui) page for **sharing options** between your options page and background or content scripts.


Options content design
----------------------


For details on how to design your options content to match the style of Firefox, see the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) and [browser styles](browser_styles) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [favourite-color](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour) example which implements options page features.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages>

windows.create()
================



Creates a new window.

 When you create the window, you can:

 * Load one or more new tabs into the window.
* Move a tab from an existing window into the new window.
* Set the size and position of the window.
* Create a "panel" style window, which in this context means a window without any of the normal browser UI (address bar, toolbar, etc.).
* Set various properties of the window, such as whether it is focused or private.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let creating = browser.windows.create(
  createData            // optional object
)

```
### Parameters


 
`createData` Optional
  `object`.

  
`allowScriptsToClose` Optional
  `boolean`. When the window is opened, it will contain a single tab, or more than one tab if `url` is given and includes an array containing more than one URL. By default scripts running in these pages are not allowed to close their tab using [`window.close()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/close). If you include `allowScriptsToClose` and set it to `true`, then this default behavior is changed, so scripts can close their tabs. Note that:

 * this only applies to the tabs that were opened when the window was created. If the user opens more tabs in this window, then scripts will not be able to close those new tabs.
* if the URL(s) given in `url` point to [extension pages](../../user_interface/extension_pages) (that is, they are pages included with this extension and loaded with the "moz-extension:" protocol) then scripts *are* by default allowed to close those tabs.

  
`cookieStoreId` Optional
  `integer`. If present, specifies the `CookieStoreId` for all tabs that will be created when the window is opened.

  
`focused` Optional
  `boolean`. If `true`, the new window will be focused. If `false`, the new window will be opened in the background and the currently focused window will stay focused. Defaults to `true`.

  
`height` Optional
  `integer`. The height in pixels of the new window, including the frame. If not specified defaults to a natural height.

  
`incognito` Optional
  `boolean`. Whether the new window should be an incognito (private) window. Note that if you specify `incognito` and `tabId`, the ID must refer to a private tab — that is, you can't move a non-private tab to a private window.

  
`left` Optional
  `integer`. The number of pixels to position the new window from the left edge of the screen. If not specified, the new window is offset naturally from the last focused window. This value is ignored for panels. (In Firefox, this value currently is ignored for popups (bug 1271047) but can be set using browser.windows.update().)

  
`state` Optional
  A [`windows.WindowState`](windowstate) value. The initial state of the window. The `minimized`, `maximized` and, `fullscreen` states cannot be combined with `left`, `top`, `width`, or `height`.

  
`tabId` Optional
  `integer`. If included, moves a tab of the specified ID from an existing window into the new window.

  
`titlePreface` Optional
  `string`. Use this to add a string to the beginning of the browser window's title. Depending on the underlying operating system, this might not work on browser windows that don't have a title (such as about:blank in Firefox).

  
`top` Optional
  `integer`. The number of pixels to position the new window from the top edge of the screen. If not specified, the new window is offset naturally from the last focused window. This value is ignored for panels. (In Firefox, this value currently is ignored for popups (bug 1271047) but can be set using browser.windows.update().)

  
`type` Optional
  A [`windows.CreateType`](createtype) value. Specifies what type of browser window to create. Specify `panel` or `popup` here to open a window without any of the normal browser UI (address bar, toolbar, etc.).

  
`url` Optional
  `string` or `array` of `string`s. A URL or array of URLs to open as tabs in the window. Fully-qualified URLs must include a scheme (i.e. `http://www.google.com`, not `www.google.com`). Relative URLs will be relative to the current page within the extension. Defaults to the New Tab Page.

  
`width` Optional
  `integer`. The width in pixels of the new window, including the frame. If not specified defaults to a natural width.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](window) object containing the details of the new window. This `Window` object will always have its `tabs` property set, unlike the `Window` objects returned from [`windows.get()`](get) and similar APIs, which only contain `tabs` if the `populate` option is passed. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Open a window containing two tabs:

 
```
function onCreated(windowInfo) {
  console.log(`Created window: ${windowInfo.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  let creating = browser.windows.create({
    url: ["https://developer.mozilla.org",
          "https://addons.mozilla.org"]
  });
  creating.then(onCreated, onError);
});

```
 Open a window when the user clicks a browser action, and move the currently active tab into it:

 
```
function onCreated(windowInfo) {
  console.log(`Created window: ${windowInfo.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  let creating = browser.windows.create({
    tabId: tab.id
  });
  creating.then(onCreated, onError);
});

```
 Open a small panel-style window, and load a locally-packaged file into it:

 
```
function onCreated(windowInfo) {
  console.log(`Created window: ${windowInfo.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {

  let popupURL = browser.extension.getURL("popup/popup.html");

  let creating = browser.windows.create({
    url: popupURL,
    type: "popup",
    height: 200,
    width: 200
  });
  creating.then(onCreated, onError);

});

```

### Example extensions


* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | Yes | 14 | 45["'url' and 'tabId options can't both be set together.", "The returned 'Window' object contains the 'tabs' property only from version 52 onwards.", "From Firefox 86, the `focused: false` option is ignored."] | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-create) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 
See also
--------


* [`window.open`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/create>

permissions
===========





|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"permissions": [
  "webRequest"
]
```
 |

 Use the `permissions` key to request special powers for your extension. This key is an array of strings, and each string is a request for a permission.

 If you request permissions using this key, then the browser may inform the user at install time that the extension is requesting certain privileges, and ask them to confirm that they are happy to grant these privileges. The browser may also allow the user to inspect an extension's privileges after installation. As the request to grant privileges may impact on users' willingness to install your extension, requesting privileges is worth careful consideration. For example, you want to avoid requesting unnecessary permissions and may want to provide information about why you are requesting permissions in your extension's store description. More information on the issues you should consider is provided in the article [Request the right permissions](https://extensionworkshop.com/documentation/develop/request-the-right-permissions/).

 For information on how to test and preview permission requests, see [Test permission requests](https://extensionworkshop.com/documentation/develop/test-permission-requests/) on the Extension Workshop site.

 The key can contain three kinds of permissions:

 * host permissions (Manifest V2 only, host permissions are specified in the [`host_permissions`](host_permissions) manifest key for Manifest V3 or higher.)
* API permissions
* the `activeTab` permission



Host permissions
----------------



 **Note:** When using Manifest V3 or higher, host permissions must be specified in the [`host_permissions`](host_permissions) manifest key.

  Host permissions are specified as [match patterns](../match_patterns), and each pattern identifies a group of URLs for which the extension is requesting extra privileges. For example, a host permission could be `"*://developer.mozilla.org/*"`.

 The extra privileges include:

 * [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) and [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) access to those origins without cross-origin restrictions (even for requests made from content scripts)
* the ability to read tab-specific metadata without the "tabs" permission, such as the `url`, `title`, and `favIconUrl` properties of [`tabs.Tab`](../api/tabs/tab) objects
* the ability to inject scripts programmatically (using [`tabs.executeScript()`](../api/tabs/executescript)) into pages served from those origins
* the ability to receive events from the [`webrequest`](../api/webrequest) API for these hosts
* the ability to access cookies for that host using the [`cookies`](../api/cookies) API, as long as the `"cookies"` API permission is also included.
* bypassing tracking protection for extension pages where a host is specified as a full domain or with wildcards. Content scripts, however, can only bypass tracking protection for hosts specified with a full domain.

 In Firefox, from version 56 onwards, extensions automatically get host permissions for their own origin, which is of the form:

 
```
moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/

```
 where `60a20a9b-1ad4-af49-9b6c-c64c98c37920` is the extension's internal ID. The extension can get this URL programmatically by calling [`extension.getURL()`](../api/extension/geturl):

 
```
browser.extension.getURL("");
// moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/

```

API permissions
---------------



API permissions are specified as keywords, and each keyword names a [WebExtension API](../api) that the extension would like to use.

 These permissions are available in Manifest V2 and above unless otherwise noted:

 * `activeTab`
* `alarms`
* `background`
* `bookmarks`
* `browserSettings`
* `browsingData`
* `captivePortal`
* `clipboardRead`
* `clipboardWrite`
* `contentSettings`
* `contextMenus`
* `contextualIdentities`
* `cookies`
* `debugger`
* `declarativeNetRequest`
* `declarativeNetRequestFeedback`
* `declarativeNetRequestWithHostAccess`
* `dns`
* `downloads`
* `downloads.open`
* `find`
* `geolocation`
* `history`
* `identity`
* `idle`
* `management`
* `menus`
* `menus.overrideContext`
* `nativeMessaging`
* `notifications`
* `pageCapture`
* `pkcs11`
* `privacy`
* `proxy`
* `scripting`
* `search`
* `sessions`
* `storage`
* `tabHide`
* `tabs`
* `theme`
* `topSites`
* `unlimitedStorage`
* `webNavigation`
* `webRequest`
* `webRequestBlocking`
* `webRequestFilterResponse`
* `webRequestFilterResponse.serviceWorkerScript`

 In most cases the permission just grants access to the API, with the following exceptions:

 * `tabs` gives you access to [`privileged parts of the `tabs` API`](../api/tabs) without the need for [host permissions](#host_permissions): `Tab.url`, `Tab.title`, and `Tab.faviconUrl`.
	+ In Firefox 85 and earlier, you also need `tabs` if you want to include `url` in the `queryInfo` parameter to [`tabs.query()`](../api/tabs/query). The rest of the `tabs` API can be used without requesting any permission.
	+ As of Firefox 86 and Chrome 50, matching [host permissions](#host_permissions) can also be used instead of the "tabs" permission.
* `webRequestBlocking` enables you to use the `"blocking"` argument, so you can [`modify and cancel requests`](../api/webrequest).
* `downloads.open` lets you use the [`downloads.open()`](../api/downloads/open) API.
* `tabHide` lets you use the [`tabs.hide()`](../api/tabs/hide) API.


activeTab permission
--------------------



This permission is specified as `"activeTab"`. If an extension has the `activeTab` permission, then when the user interacts with the extension, the extension is granted extra privileges for the active tab only.

 "User interaction" includes:

 * the user clicks the extension's [browser action](../api/browseraction) or page action
* the user selects its context menu item
* the user activates a keyboard shortcut defined by the extension

 The extra privileges are:

 * The ability to inject JavaScript or CSS into the tab programmatically, using [`browser.tabs.executeScript()`](../api/tabs/executescript) and [`browser.tabs.insertCSS()`](../api/tabs/insertcss)
* Access to the privileged parts of the tabs API for the current tab: `Tab.url`, `Tab.title`, and `Tab.faviconUrl`.

 The intention of this permission is to enable extensions to fulfill a common use case, without having to give them very powerful permissions. Many extensions want to "do something to the current page when the user asks".

 For example, consider an extension that wants to run a script in the current page when the user clicks a browser action. If the `activeTab` permission did not exist, the extension would need to ask for the host permission `<all_urls>`. But this gives the extension more power than it needs: it could now execute scripts in *any tab*, *any time* it likes, instead of just the active tab and only in response to a user action.

  **Note:** You can only get access to the tab/data that was there, when the user interaction occurred (e.g. the click). When the active tab navigates away (e.g., due to finishing loading or some other event), the permission does not grant you access to the tab anymore.

  Usually the tab that's granted `activeTab` is just the currently active tab, except in one case. The [`menus`](../api/menus) API enables an extension to create a menu item which is shown if the user context-clicks on a tab (that is, on the element in the tabstrip that enables the user to switch from one tab to another).

 If the user clicks such an item, then the `activeTab` permission is granted for the tab the user clicked, even if it's not the currently active tab (as of Firefox 63, [Firefox bug 1446956](https://bugzil.la/1446956)).


Clipboard access
----------------



There are two permissions which enables the extension to interact with the clipboard:

  `clipboardWrite`  Write to the clipboard using [`Clipboard.write()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write), [`Clipboard.writeText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText), `document.execCommand("copy")` or `document.execCommand("cut")`

  `clipboardRead`  Read from the clipboard using [`Clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read), [`Clipboard.readText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText) or `document.execCommand("paste")`

   See [Interact with the clipboard](../interact_with_the_clipboard) for more details.


Unlimited storage
-----------------



The `unlimitedStorage` permission:

 * Enables extensions to exceed any quota imposed by the [`storage.local`](../api/storage/local) API
* In Firefox, enables extensions to create a ["persistent" IndexedDB database](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) without the browser prompting the user for permission at the time the database is created.


Example
-------




```
 "permissions": ["\*://developer.mozilla.org/\*"]

```
 In Manifest V2 only, request privileged access to pages under `developer.mozilla.org`.

 
```
  "permissions": ["tabs"]

```
 Request access to the privileged pieces of the `tabs` API.

 
```
  "permissions": ["\*://developer.mozilla.org/\*", "tabs"]

```
 In Manifest V2 only, request both of the above permissions.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `permissions` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `activeTab` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `alarms` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `background` | 10 | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `bookmarks` | Yes | 15 | 48 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `browserSettings` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |
| `browsingData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `captivePortal` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |
| `clipboardRead` | Yes | 79 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `clipboardWrite` | Yes | 79 | 51 | ? | Yes | 14 | ? | ? | 51 | ? | 15 | ? |
| `contentSettings` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `contextMenus` | Yes | 14 | 55Available as an alias to the `menus` permission. | ? | Yes | 14Available as an alias to the `menus` permission. | ? | ? | No | ? | No | ? |
| `contextualIdentities` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |
| `cookies` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `debugger` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `declarativeNetRequest` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `declarativeNetRequestFeedback` | 84Available only to unpacked extensions. | 84Available only to unpacked extensions. | No | ? | 70Available only to unpacked extensions. | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `declarativeNetRequestWithHostAccess` | 84 | 84 | No | ? | 70 | 16 | ? | ? | No | ? | 16 | ? |
| `dns` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `downloads` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `downloads_open` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `find` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `geolocation` | Yes | 14 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `history` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `identity` | Yes | 79 | 53 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `idle` | Yes | 15 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `management` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `menus` | No | No | 53 | ? | No | 14 | ? | ? | No | ? | No | ? |
| `nativeMessaging` | 29 | 15 | 50 | ? | 16 | 14 | ? | ? | No | ? | 15 | ? |
| `notifications` | 5 | 79 | 48 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `pageCapture` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `pkcs11` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `privacy` | Yes | 79 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `proxy` | 33 | 79 | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |
| `search` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `sessions` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `storage` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `tabHide` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |
| `tabs` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `theme` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `topSites` | Yes | 79 | 52 | ? | Yes | No | ? | ? | 52 | ? | No | ? |
| `unlimitedStorage` | Yes | 14 | 56 | ? | No | 16Since Safari 16, the storage quota is unlimited.14Does not grant an unlimited storage quota. Grants a 10 MB storage quota, instead of the standard 5 MB. | ? | ? | 56 | ? | 16Since Safari 16, the storage quota is unlimited.15Does not grant an unlimited storage quota. Grants a 10 MB storage quota, instead of the standard 5 MB. | ? |
| `webNavigation` | Yes | 14 | 48 | ? | 17 | 14 | ? | ? | 48 | ? | 15 | ? |
| `webRequest` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | No | ? |
| `webRequestBlocking` | Yes | 14 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `webRequestFilterResponse` | No | No | 110 | ? | No | No | ? | ? | 110 | ? | No | ? |
| `webRequestFilterResponse_serviceWorkerScript` | No | No | 95 | ? | No | No | ? | ? | 95 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions>

tabs.create()
=============



Creates a new tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let creating = browser.tabs.create(
  createProperties   // object
)

```
### Parameters


 `createProperties`  `object`. Properties to give the new tab. To learn more about these properties, see the [`tabs.Tab`](tab) documentation.

  
`active` Optional
  `boolean`. Whether the tab should become the active tab in the window. If `false`, it has no effect. Does not affect whether the window is focused (see [`windows.update`](../windows/update)). Defaults to `true`.

  
`cookieStoreId` Optional
  `string`. Use this to create a tab whose cookie store ID is `cookieStoreId`. This option is only available if the extension has the `"cookies"` [permission](../../manifest.json/permissions).

  
`discarded` Optional
  `boolean`. Whether the tab is created and made visible in the tab bar without any content loaded into memory, a state known as discarded. The tab's content is loaded when the tab is activated.

  
`index` Optional
  `integer`. The position the tab should take in the window. The provided value will be clamped to between zero and the number of tabs in the window.

  
`muted` Optional
  `boolean`. Whether the tab should be muted. Defaults to `false`.

  
`openerTabId` Optional
  `integer`. The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as the newly created tab.

  
`openInReaderMode` Optional
  `boolean`. If `true`, open this tab in [Reader Mode](togglereadermode). Defaults to `false`.

  
`pinned` Optional
  `boolean`. Whether the tab should be pinned. Defaults to `false`.

  
`selected` Optional
  `boolean`. Whether the tab should become the selected tab in the window. Defaults to `true`.

  **Warning:** This property is deprecated, and is not supported in Firefox. Use `active` instead.

   
`title` Optional
  `string`. The title of the tab. Allowed only if the tab is created with `discarded` set to `true`.

  
`url` Optional
  `string`. The URL to navigate the tab to initially. Defaults to the New Tab Page.

 Fully-qualified URLs must include a scheme (for example, '[http://www.google.com](https://www.google.com)' not '[www.google.com](https://www.google.com)').

 For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail:

 * chrome: URLs
* javascript: URLs
* data: URLs
* file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below)
* privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`). Non-privileged URLs (e.g., `about:blank`) are allowed.
* The New Tab page (`about:newtab`) can be opened if no value for URL is provided.

 To load a page that's packaged with your extension, specify an absolute URL starting at the extension's manifest.json file. For example: '/path/to/my-page.html'. If you omit the leading '/', the URL is treated as a relative URL, and different browsers may construct different absolute URLs.

  
`windowId` Optional
  `integer`. The window to create the new tab in. Defaults to the current window.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing details about the created tab. If the tab could not be created (for example, because `url` used a privileged scheme) the promise will be rejected with an error message.

 The promise returned by `browser.tabs.create()` resolves as soon as the tab has been created. The tab may still be loading. To detect when the tab has finished loading, listen to the [`tabs.onUpdated`](onupdated) or the [`webNavigation.onCompleted`](../webnavigation/oncompleted) event before calling `tabs.create`.


Examples
--------



Open "<https://example.org>" in a new tab:

 
```
function onCreated(tab) {
  console.log(`Created new tab: ${tab.id}`)
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(() => {
  let creating = browser.tabs.create({
    url:"https://example.org"
  });
  creating.then(onCreated, onError);
});

```

### Example extensions


* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)
* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)
* [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-create) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/create>

action
======





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 3 or higher |
| Example | 
```
"action": {
  "browser\_style": true,
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html",
  "theme\_icons": [{
    "light": "icons/geo-16-light.png",
    "dark": "icons/geo-16.png",
    "size": 16
  }, {
    "light": "icons/geo-32-light.png",
    "dark": "icons/geo-32.png",
    "size": 32
  }]
}
```
 |

 An action is a button that your extension adds to the browser's toolbar. The button has an icon, and may optionally have a popup whose content is specified using HTML, CSS, and JavaScript.

 This key replaces [`browser_action`](browser_action) in Manifest V3 extensions.

 If you supply a popup, then the popup is opened when the user clicks the button, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's [background scripts](../background_scripts) when the user clicks the button.

 You can also create and manipulate actions programmatically using the [`action`](../api/action) .



Syntax
------



The `action` key is an object that may have any of these properties, all optional:

 

| Name | Type | Description |
| --- | --- | --- |
| `[browser\_style](../user_interface/browser_styles)` | `Boolean` | Optional, defaulting to `false`.  Use this to include a stylesheet in your popup that will make its look consistent with the browser's UI and with other extensions that use the `browser_style` property. Although this key defaults to `false`, it's recommended that you include it and set it to `true` in order to make your popups consistent with the look of the rest of the browser user interface.   In Firefox, the stylesheet can be seen at chrome://browser/content/extension.css, or chrome://browser/content/extension-mac.css on macOS. When setting dimensions, be aware that this style sheet currently sets `box-sizing: border-box` (see [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)).   [Browser styles](../user_interface/browser_styles) describes the classes you can apply to elements in the popup in order to get particular styles.   The [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download) example extension uses `browser_style` in its popup.    **Note:** Setting `browser_style` to `true` prevents users from selecting text in an extension's popup or sidebar content. This is normal behavior. You can't select parts of the UI in the browser. However, You can work around this limitation to allow your users to select text in two ways:  1. Set `browser_style` to `false`
2. Use CSS styling on the body of your sidebar or popup's HTML to allow text selection by adding the rule `-moz-user-select` with a value of `all` or `text`.

  |
| `default_area` | `String` |  Defines the part of the browser in which the button is initially placed. This is a string that may take one of four values: * "navbar": the button is placed in the main browser toolbar, alongside the URL bar.
* "menupanel": the button is placed in a popup panel.
* "tabstrip": the button is placed in the toolbar that contains browser tabs.
* "personaltoolbar": the button is placed in the bookmarks toolbar.

This property is only supported in Firefox. This property is optional, and defaults to "menupanel".  Firefox remembers the `default_area` setting for an extension, even if that extension is uninstalled and subsequently reinstalled. To force the browser to acknowledge a new value for `default_area`, the id of the extension must be changed.   An extension can't change the location of the button after it has been installed, but the user may be able to move the button using the browser's built-in UI customization mechanism.  |
| `default_icon` | `Object` or `String` |  Use this to specify one or more icons for the action. The icon is shown in the browser toolbar by default.  Icons are specified as URLs relative to the manifest.json file itself. You can specify a single icon file by supplying a string here: 
```
"default\_icon": "path/to/geo.svg"
```
  To specify multiple icons in different sizes, specify an object here. The name of each property is the icon's height in pixels, and must be convertible to an integer. The value is the URL. For example:  
```
    "default\_icon": {
      "16": "path/to/geo-16.png",
      "32": "path/to/geo-32.png"
    }
```
  You cannot specify multiple icons of the same sizes.See [Choosing icon sizes](action#choosing_icon_sizes) for more guidance on this.  |
| `default_popup` | `String` | The path to an HTML file containing the specification of the popup.  The HTML file may include CSS and JavaScript files using `[<link>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)` and `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` elements, just like a normal web page. However, `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)`must have `[src](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` attribute to load a file. Don't use `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` with embedded code, because you'll get a confusing Content Violation Policy error.   Unlike a normal web page, JavaScript running in the popup can access all the [WebExtension APIs](../api) (subject, of course, to the extension having the appropriate <permissions>).   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `default_title` | `String` |  Tooltip for the button, displayed when the user moves their mouse over it. If the button is added to the browser's menu panel, this is also shown under the app icon.   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `theme_icons` | `Array` |  This property enables you to specify different icons for themes depending on whether Firefox detects that the theme uses dark or light text.   If this property is present, it's an array containing at least one `ThemeIcons` object. A `ThemeIcons` object contains three mandatory properties:   `"dark"`  A URL pointing to an icon. This icon displays when a theme using dark text is active (such as the Firefox Light theme, and the Default theme if no default\_icon is specified).  `"light"`  A URL pointing to an icon. This icon displays when a theme using light text is active (such as the Firefox Dark theme).  `"size"` The size of the two icons in pixels.  Icons are specified as URLs relative to the manifest.json file.  You should supply 16x16 and 32x32 (for retina display) `ThemeIcons`.  |


Choosing icon sizes
-------------------



The action's icon may need to be displayed in different sizes in different contexts:

 * The icon is displayed in the browser toolbar. Older versions of Firefox supported the option of placing the icon in the browser's menu panel (the panel that opens when the user clicks the "hamburger" icon). In those versions of Firefox the icon in the menu panel was larger than the icon in the toolbar.
* On a high-density display like a Retina screen, icons needs to be twice as big.

 If the browser can't find an icon of the right size in a given situation, it will pick the best match and scale it. Scaling may make the icon appear blurry, so it's important to choose icon sizes carefully.

 There are two main approaches to this. You can supply a single icon as an SVG file, and it will be scaled correctly:

 
```
"default\_icon": "path/to/geo.svg"

```
 Alternatively, you can supply several icons in different sizes, and the browser will pick the best match.

 In Firefox:

 * The default height and width for icons in the toolbar is 16 \* [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio).
* The default height and width for icons in the menu panel is 32 \* [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio).

 So you can specify icons that match exactly, on both normal and Retina displays, by supplying three icon files, and specifying them like this:

 
```
"default\_icon": {
  "16": "path/to/geo-16.png",
  "32": "path/to/geo-32.png",
  "64": "path/to/geo-64.png"
}

```
 If Firefox can't find an exact match for the size it wants, then it will pick the smallest icon specified that's bigger than the ideal size. If all icons are smaller than the ideal size, it will pick the biggest icon specified.


Example
-------




```
"action": {
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  }
}

```
 An action with just an icon, specified in 2 sizes. The extension's background scripts can receive click events when the user clicks the icon using code like this:

 
```
 browser.Action.onClicked.addListener(handleClick);

```
 
```
"action": {
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html"
}

```
 An action with an icon, a title, and a popup. The popup is shown when the user clicks the button.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `action` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109 | ? | 15.4 | ? |
| `browser_style` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |
| `default_area` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |
| `default_icon` | 88SVG icons are not supported. | 88["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 109 | ? | 74SVG icons are not supported. | 15.4SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | No | ? | 15.4SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109 | ? | 15.4 | ? |
| `default_title` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109Browser actions are presented as menu items, and the title is the menu item's label. | ? | 15.4 | ? |
| `theme_icons` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action>

background
==========





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"background": {
  "scripts": ["background.js"]
}
```
 |

 Use the `background` key to include one or more background scripts or a background page in your extension.

 Background scripts are the place to put code that needs to maintain a long-term state, or perform long-term operations, independently of the lifetime of any particular web pages or browser windows.

 Background scripts are loaded as soon as the extension is loaded and stay loaded until the extension is disabled or uninstalled unless `persistent` is specified as `false`. You can use any WebExtension APIs in the script as long as you have requested the necessary <permissions>.

 See [Background scripts](../background_scripts) for some more details.

 The `background` key is an object that must have one of these properties:

 

|  |  |
| --- | --- |
| `scripts` |  An `Array` of `Strings`, each of which is a path to a JavaScript source. The path is relative to the manifest.json file itself. These are the scripts that are executed in the extension's background page.  The scripts share the same `window` global context. The scripts are loaded in the order they appear in the array.  If you specify `scripts`, an empty page is created where your scripts run.    **Note:** If you want to fetch a script from a remote location with the `<script>` tag (e.g., `<script src =
"https://code.jquery.com/jquery-3.6.0.min.js">`), you have to change the `<content_security_policy>` key in the manifest.json file of your extension.   |
| `page` |  If you need specific content in the background page, you can define a page using the `page` property. This is a `String` representing a path, relative to the manifest.json file, to an HTML document included in your extension bundle.   If you use this property, you can not specify background scripts using `scripts`, but you can include scripts from the page, just like a normal web page.  |

 The `background` key can also contain this optional property:

 

|  |  |
| --- | --- |
| `persistent` | A `Boolean` value. If omitted, this property default to `true` in Manifest V2 and `false` in Manifest V3. Setting to `true` in Manifest V3 results in an error.* `true` indicates the background page is to be kept in memory from when the extension is loaded or the browser starts until the extension is unloaded or disabled, or the browser is closed (that is, the background page is persistent).
* `false` indicates the background page may be unloaded from memory when idle and recreated when needed. Such background pages are often called Event Pages, because they are loaded into memory to allow the background page to handle the events to which it has added listeners. Registration of listeners is persistent when the page is unloaded from memory, but other values are not persistent. If you want to store data persistently in an event page, then you should use the [storage API](../api/storage).
 |
| `type` | A `String` value. Determines whether the scripts specified in `"scripts"` are loaded as ES modules.* `classic` indicates the background scripts or service workers are not included as an ES Module.
* `module` indicates the background scripts or service workers are included as an ES Module. This enables the background page or service worker to `import` code.

If omitted, this property defaults to `classic`. |



Example
-------




```
  "background": {
    "scripts": ["jquery.js", "my-background.js"]
  }

```
 Load two background scripts.

 
```
  "background": {
    "page": "my-background.html"
  }

```
 Load a custom background page.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `background` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `page` | YesAvailable for use in Manifest V2 only. | 14 | 48 | ? | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 or later. | ? | ? | 48 | ? | 15Available for use in Manifest V2 or later. | ? |
| `persistent` | YesAvailable for use in Manifest V2 only. | 14This property is required. | 48["From Firefox 106, persistent and non-persistent pages are supported for Manifest V2.", "To Firefox 105, only persistent pages are supported.", "Before version 66, Firefox would log a warning even if the value was set to `true`."] | ? | YesAvailable for use in Manifest V2 only. | 14.1Since Safari 15.4, ignored if `service_worker` is used.14Only persistent pages are supported. | ? | ? | 48["From Firefox 106, persistent and non-persistent pages are supported for Manifest V2.", "To Firefox 105, only persistent pages are supported.", "Before version 66, Firefox would log a warning even if the value was set to `true`."] | ? | 15.4Only non-persistent pages are supported. Requires `persistent: false` or `service_worker`.15Only non-persistent pages are supported. Requires `persistent: false`. | ? |
| `scripts` | YesAvailable for use in Manifest V2 only. | 14 | 48Before Firefox 50, when the debugger is open, scripts are not always loaded in the order given in the array. | ? | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 or later. | ? | ? | 48Before Firefox 50, when the debugger is open, scripts are not always loaded in the order given in the array. | ? | 15Available for use in Manifest V2 or later. | ? |
| `service_worker` | 88Available for use in Manifest V2 or later. | 88Available for use in Manifest V2 or later. | No | ? | 74Available for use in Manifest V2 or later. | 15.4Available for use in Manifest V2 or later. | ? | ? | No | ? | 15.4Available for use in Manifest V2 or later. | ? |
| `type` | Yes | Yes | 112 | ? | Yes | 16.4 | ? | ? | 112 | ? | 16.4 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background>

chrome\_settings\_overrides
===========================





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"chrome\_settings\_overrides" : {
  "homepage": "https://developer.mozilla.org/"
 },

```
 |

 Use the `chrome_settings_overrides` key to override the browser's home page and add a new search engine.



Syntax
------



The `chrome_settings_overrides` key is an object that may have the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `homepage` | `String` | Defines the page to be used as the browser's homepage. The replacement is given as a URL. The URL may:* point to a file bundled with the extension, in which case it is given as a URL relative to the manifest.json file
* be a remote URL, such as "https://developer.mozilla.org/".

 If two or more extensions both set this value, then the setting from the most recently installed one will take precedence.  To override new tabs, use "<chrome_url_overrides>" instead.  This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `search_provider` | `Object` | Defines a search provider to add to the browser.  The search provider has a name and a primary search URL. Alternative URLs may be provided, including URLs for more specialized searches like image search. In the URL you supply, use "`{searchTerms}`" to interpolate the search term into the URL, like: `https://www.discogs.com/search/?q={searchTerms}`. You can also provide POST parameters to be sent along with the search.   The search provider will be presented to the user alongside the built-in providers. If you include the `is_default` property and set it to `true`, the new search provider will be the default option. By supplying the `keyword` property, you enable the user to select your search provider by typing the keyword into the search/address bar before the search term.   This is an object with the properties listed below. All string properties are [localizable](../internationalization#internationalizing_manifest.json).   `name` String: The search engine's name, displayed to the user. `search_url` String: URL used by the search engine. This must be an HTTPS URL. `is_default Optional`  Boolean: True if the search engine should be the default choice. On Firefox, this is opt-in and the user will only be asked the first time the extension is installed. They will not be asked again if a search engine is added later.  `alternate_urls Optional`  Array of String: An array of alternative URLs that can be used instead of `search_url`.  `encoding Optional`  String: Encoding of the search term, specified as a [standard character encoding name](https://www.iana.org/assignments/character-sets/character-sets.xhtml), such as "UTF-8".  `favicon_url Optional`  String: URL pointing to an icon for the search engine. In Manifest V2, this must be an absolute HTTP or HTTPS URL. In Manifest V3, this must reference an icon provided in the extension as a path relative to the extension's root.  `image_url Optional` String: URL used for image search. `image_url_post_params Optional` String: POST parameters to send to `image_url`. `instant_url Optional` String: URL used for instant search. `instant_url_post_params Optional` String: POST parameters to send to `instant_url`. `keyword Optional` String: Address bar keyword for the search engine. `prepopulated_id Optional` The ID of a built-in search engine to use. `search_url_post_params Optional` String: POST parameters to send to `search_url`. `suggest_url Optional` String: URL used for search suggestions. This must be an HTTPS URL. `suggest_url_post_params Optional` String: POST parameters to send to `suggest_url`.  |


Example
-------



This example shows how to set a search provider.

 
```
"chrome\_settings\_overrides": {
  "search\_provider": {
    "name": "Discogs",
    "search\_url": "https://www.discogs.com/search/?q={searchTerms}",
    "keyword": "disc",
    "favicon\_url": "https://www.discogs.com/favicon.ico"
  }
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `chrome_settings_overrides` | Yes | 79 | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `homepage` | Yes | 79 | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `search_provider` | Yes | 79 | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `startup_pages` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_settings_overrides>

chrome\_url\_overrides
======================





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
  "chrome\_url\_overrides" : {
    "newtab": "my-new-tab.html"
  }
```
 |

 Use the `chrome_url_overrides` key to provide a custom replacement for the documents loaded into various special pages usually provided by the browser itself.



Syntax
------



The `chrome_url_overrides` key is an object that may have the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `bookmarks` | `String` | Provide a replacement for the page that shows the bookmarks. |
| `history` | `String` | Provide a replacement for the page that shows the browsing history. |
| `newtab` | `String` |  Provide a replacement for the document that's shown in the "new tab" page. This is the page that's shown when the user has opened a new tab but has not loaded any document into it: for example, by using the `Ctrl`/`Command`+`T` keyboard shortcut.   The replacement is given as a URL to an HTML file. The file must be bundled with the extension: you can't specify a remote URL here. You can specify it relative to the extension's root folder, like: "path/to/newtab.html".   The document can load CSS and JavaScript, just like a normal web page. JavaScript running in the page gets access to the same [privileged "browser.\*" APIs](../api) as the extension's background script.   It's very good practice to include a [<title>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) for the page, or the tab's title will be the "moz-extension://..." URL.   A common use case is to let the user define a new tab page: to do this, provide a custom new tab page that navigates to the page the user defined.   If two or more extensions both define custom new tab pages, then the last one to be installed or enabled gets to use its value.  To override the browser's homepage, use "<chrome_settings_overrides>" instead. |

 All properties are [localizable](../internationalization#internationalizing_manifest.json).


Example
-------



```
"chrome\_url\_overrides" : {
  "newtab": "my-new-tab.html"
}

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `chrome_url_overrides` | Yes | 79 | 54 | ? | No | 1514.1 | ? | ? | No | ? | 15 | ? |
| `bookmarks` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `history` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `newtab` | YesIf two or more extensions both define a custom new tab page, then in Firefox the first extension to run wins. In Chrome the last extension wins. | 79If two or more extensions both define a custom new tab page, then in Firefox the first extension to run wins. In Edge the last extension wins. | 54If two or more extensions both define a custom new tab page, then in Firefox the first extension to run wins. In Chrome the last extension wins. | ? | No | 14.1An extension can define a custom new tab or window page, but it does not take effect until the user chooses the extension to override the page in Safari's *General* settings. | ? | ? | No | ? | 15An extension can define a custom new tab or window page, but it does not take effect until the user chooses the extension to override the page in Safari's *Extensions* settings. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides>

Background scripts
==================



Background scripts or a background page enable you to monitor and react to events in the browser, such as navigating to a new page, removing a bookmark, or closing a tab.

 Background scripts or a page are:

 * Persistent – loaded when the extension starts and unloaded when the extension is disabled or uninstalled.
* Non-persistent (which are also known as event pages) – loaded only when needed to respond to an event and unloaded when they become idle. However, a background page does not unload until all visible views and message ports are closed. Opening a view does not cause the background page to load but does prevent it from closing.

 In Manifest V2, background scripts or a page can be persistent or non-persistent. Non-persistent background scripts are recommended as they reduce the resource cost of your extension. In Manifest V3, only non-persistent background scripts or a page are supported.

 If you have persistent background scripts or a page in Manifest V2 and want to prepare your extension for migration to Manifest V3, [Convert to non-persistent](#convert_to_non-persistent) provides advice on transitioning the scripts or page to the non-persistent model.



Background script environment
-----------------------------


### DOM APIs



Background scripts run in the context of a special page called a background page. This gives them a [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) global, along with all the standard DOM APIs provided by that object.

  **Warning:** In Firefox, background pages do not support the use of [`alert()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert), [`confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm), or [`prompt()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt).

 
### WebExtension APIs


Background scripts can use any [WebExtension APIs](api), as long as their extension has the necessary [permissions](manifest.json/permissions).

### Cross-origin access


Background scripts can make XHR requests to hosts they have [host permissions](manifest.json/permissions) for.

### Web content


Background scripts do not get direct access to web pages. However, they can load [content scripts](content_scripts) into web pages and [communicate with these content scripts using a message-passing API](content_scripts#communicating_with_background_scripts).

### Content security policy



Background scripts are restricted from certain potentially dangerous operations, such as the use of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval), through a Content Security Policy.

 See [Content Security Policy](content_security_policy) for more details.


Implementing background scripts
-------------------------------


This section describes how to implement a non-persistent background script.

### Specify the background scripts



In your extension, you include a background script or scripts, if you need them, using the [`"background"`](manifest.json/background) key in `manifest.json`. For Manifest V2 extensions, the `persistent` property must be `false` to create a non-persistent script. It can be omitted for Manifest V3 extensions or must be set to `false`, as script are always non-persistent in Manifest V3. Including `"type": "module"` loads the background scripts as ES modules.

 
```
"background": {
  "scripts": ["background-script.js"],
  "persistent": false,
  "type": "module"
}

```
 These scripts execute in the extension's background page, so they run in the same context, like scripts loaded into a web page.

 However, if you need certain content in the background page, you can specify one. You then specify your script from the page rather than using the `"scripts"` property. Before the introduction of the `"type"` property to the `"background"` key, this was the only option to include ES modules. You specify a background page like this:

 * manifest.json 
```
"background": {
  "page": "background-page.html",
  "persistent": false
}

```
* background-page.html 
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <script type="module" src="background-script.js"></script>
  </head>
</html>

```

 You cannot specify background scripts and a background page.


### Initialize the extension



Listen to [`runtime.onInstalled`](api/runtime/oninstalled) to initialize an extension on installation. Use this event to set a state or for one-time initialization. For extensions with event pages, this is where stateful APIs, such as a context menu created using `browser.menus.create`, should be used.

 
```
browser.runtime.onInstalled.addListener(() => {
  browser.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

```

### Add listeners



Structure background scripts around events the extension depends on. Defining relevant events enables background scripts to lie dormant until those events are fired and prevents the extension from missing essential triggers.

 Listeners must be registered synchronously from the start of the page.

 
```
browser.runtime.onInstalled.addListener(() => {
  browser.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

// This will run when a bookmark is created.
browser.bookmarks.onCreated.addListener(() => {
  // do something
});

```
 Do not register listeners asynchronously, as they will not be properly triggered. So, rather than:

 
```
window.onload = () => {
  // WARNING! This event is not persisted, and will not restart the event page.
  browser.bookmarks.onCreated.addListener(() => {
    // do something
  });
}

```
 Do this:

 
```
browser.tabs.onUpdated.addListener(() => {
  // This event is run in the top level scope of the event page, and will persist, allowing
  // it to restart the event page if necessary.
});

```
 Extensions can remove listeners from their background scripts by calling `removeListener`, such as with [`runtime.onMessage`](api/runtime/onmessage) `removeListener`. If all listeners for an event are removed, the browser no longer loads the extension's background script for that event.

 
```
browser.runtime.onMessage.addListener(function messageListener(message, sender, reply) {
  browser.runtime.onMessage.removeListener(messageListener);
});

```

### Filter events



Use APIs that support event filters to restrict listeners to the cases the extension cares about. If an extension is listening for [`tabs.onUpdated`](api/tabs/onupdated), use the [`webNavigation.onCompleted`](api/webnavigation/oncompleted) event with filters instead, as the tabs API does not support filters.

 
```
browser.webNavigation.onCompleted.addListener(() => {
  console.log("This is my favorite website!");
}, { url: [{ urlMatches : 'https://www.mozilla.org/' }] });

```

### React to listeners



Listeners exist to trigger functionality once an event has fired. To react to an event, structure the desired reaction inside of the listener event.

 
```
browser.runtime.onMessage.addListener((message, callback) => {
  if (message.data === "setAlarm") {
    browser.alarms.create({delayInMinutes: 5})
  } else if (message.data === "runLogic") {
    browser.tabs.executeScript({file: 'logic.js'});
  } else if (message.data === "changeColor") {
    browser.tabs.executeScript(
      {code: 'document.body.style.backgroundColor="orange"'});
  };
});

```

### Unload background scripts



Data should be persisted periodically to not lose important information if an extension crashes without receiving [`runtime.onSuspend`](api/runtime/onsuspend). Use the storage API to assist with this.

 
```
browser.storage.local.set({variable: variableInformation});

```
 Message ports cannot prevent an event page from shutting down. If an extension uses message passing, the ports are closed when the event page idles. Listening to the [`runtime.Port`](api/runtime/port) `onDisconnect` lets you discover when open ports are closing, however the listener will be under the same time constraints as [`runtime.onSuspend`](api/runtime/onsuspend).

 
```
browser.runtime.onMessage.addListener((message, callback) => {
  if (message === 'hello') {
    sendResponse({greeting: 'welcome!'})
  } else if (message === 'goodbye') {
    browser.runtime.Port.disconnect();
  }
});

```
 Background scripts unload after a few seconds of inactivity. However, if during the suspension of a background script another event wakes the background script, [`runtime.onSuspendCanceled`](api/runtime/onsuspendcanceled) is called and the background script continues running. If any cleanup is required, listen to [`runtime.onSuspend`](api/runtime/onsuspend).

 
```
browser.runtime.onSuspend.addListener(() => {
  console.log("Unloading.");
  chrome.browserAction.setBadgeText({text: ""});
});

```
 However, persisting data should be preferred rather than relying on [`runtime.onSuspend`](api/runtime/onsuspend). It doesn't allow for as much cleanup as may be needed and does not help in case of a crash.


Convert to non-persistent
-------------------------


If you've a persistent background script, this section provides instructions on converting it to the non-persistent model.

### Update your manifest.json file



In your extension's `manifest.json` file, change the persistent property of [`"background"`](manifest.json/background) key to `false` for your script or page.

 
```
"background": {
  …,
  "persistent": false
}

```

### Move event listeners



Listeners must be at the top-level to activate the background script if an event is triggered. Registered listeners may need to be restructured to the synchronous pattern and moved to the top-level.

 
```
browser.runtime.onStartup.addListener(() => {
  // run startup function
})

```

### Record state changes



As scripts now open and close as needed, use the storage API to set and return states and values. Use [`storage.local`](api/storage/local) `set` to update on the local machine.

 
```
browser.storage.local.set({ variable: variableInformation });

```
 Use [`storage.local`](api/storage/local) `get` to retrieve the value of that variable.

 
```
browser.storage.local.get(['variable'], (result) => {
  let someVariable = result.variable;
  // Do something with someVariable
});

```

### Change timers into alarms



DOM-based timers do not remain active after an event page has idled. Instead, use the [`alarms`](api/alarms) API if you need a timer to wake an event page.

 
```
browser.alarms.create({delayInMinutes: 3.0})

```
 Then add a listener.

 
```
browser.alarms.onAlarm.addListener(() => {
  alert("Hello, world!")
});

```

### Update calls for background script functions



If a content script or action must call a function, use [`runtime.getBackgroundPage`](api/runtime/getbackgroundpage) to ensure the event page is running. If the call is optional (that is, only needed if the event page is alive) then use [`extension.getBackgroundPage`](api/extension/getbackgroundpage), which return `null` if the page is not running.

 
```
document.getElementById('target').addEventListener('click', async () => {
  let backgroundPage = await window.runtime.getBackgroundPage();
  backgroundPage.backgroundFunction();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Background_scripts>

web\_accessible\_resources
==========================




|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"web\_accessible\_resources": [
  "images/my-image.png"
]
```
 |


Description
-----------



Sometimes you want to package resources—for example, images, HTML, CSS, or JavaScript—with your extension and make them available to web pages and other extensions.

  **Note:** Until Firefox 105, extensions could access resources packaged in other extensions by default. From Firefox 105 onwards, to enable other extensions to access an extension's resources they must be included in this key.

  For example, the [Beastify example extension](https://github.com/mdn/webextensions-examples/tree/master/beastify) replaces a web page with an image of a beast selected by the user. The beast images are packaged with the extension. To make the selected image visible, the extension adds [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) elements whose `src` attribute points to the beast's image. For the web page to be able to load the images, they must be made web accessible.

 With the `web_accessible_resources` key, you list all the packaged resources that you want to make available to web pages. You specify them as paths relative to the manifest.json file.

 Note that content scripts don't need to be listed as web accessible resources.

 If an extension wants to use [`webRequest`](../api/webrequest) to redirect a public URL (e.g., HTTPS) to a page that's packaged in the extension, then the extension must list the page in the `web_accessible_resources` key.


### Manifest V2 syntax



In Manifest V2, web accessible resources are added as an array under the key, like this:

 
```
"web\_accessible\_resources": [
  "images/my-image.png"
]

```

### Manifest V3 syntax



In Manifest V3, the `web_accessible_resources` key is an array of objects like this:

 
```
{
  // …
  "web_accessible_resources": [
    {
      "resources": [ "test1.png", "test2.png" ],
      "matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
    }, {
      "resources": [ "test3.png", "test4.png" ],
      "matches": [ "https://web-accessible-resources-2.glitch.me/*" ],
      "use_dynamic_url": true
    }
  ],
  // …
}

```
 Each object must include a `"resources"` property and either a `"matches"` or `"extension_ids"` property from the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `extension_ids` | `String` | A list of extension IDs specifying the extensions that can access the resources. |
| `matches` | `String` | A list of URL match patterns specifying the pages that can access the resources. Only the origin is used to match URLs. Origins include subdomain matching. Paths are ignored. |
| `resources` | `String` | An array of resources to be exposed. Resources are specified as strings and may contain `*` for wildcard matches. For example, `"/images/*"` exposes everything in the extension's `/images` directory recursively, while `"*.png"` exposes all PNG files. |
| `use_dynamic_url` | `Boolean` | Whether resources to be accessible through the dynamic ID. The dynamic ID is generated per session and regenerated on browser restart or extension reload. |


### Using web\_accessible\_resources



Suppose your extension includes an image file at `images/my-image.png`, like this:

 
```
my-extension-files/
    manifest.json
    my-background-script.js
    images/
        my-image.png

```
 To enable a web page to use an [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element whose `src` attribute points to this image, you would specify `web_accessible_resources` like this:

 
```
"web\_accessible\_resources": ["images/my-image.png"]

```
 The file is then available using a URL like:

 
```
moz-extension://<extension-UUID>/images/my-image.png"

```
 `<extension-UUID>` is **not** your extension's ID. This ID is randomly generated for every browser instance. This prevents websites from fingerprinting a browser by examining the extensions it has installed.

  **Note:** In Chrome in Manifest V2, an extension's ID is fixed. When a resource is listed in `web_accessible_resources`, it is accessible as `chrome-extension://<your-extension-id>/<path/to/resource>`. In Manifest V3, Chrome can use a dynamic URL by setting `use_dynamic_url` to `true`.

  The recommended approach to obtaining the URL of the resource is to use [`runtime.getURL`](../api/runtime/geturl) passing the path relative to manifest.json, for example:

 
```
browser.runtime.getURL("images/my-image.png");
// something like:
// moz-extension://944cfddf-7a95-3c47-bd9a-663b3ce8d699/images/my-image.png

```
 This approach gives you the correct URL regardless of the browser your extension is running on.


### Wildcards



`web_accessible_resources` entries can contain wildcards. For example, the following entry would also work to include the resource at "images/my-image.png":

 
```
  "web\_accessible\_resources": ["images/\*.png"]

```

### Security



If you make a page web-accessible, any website may link or redirect to that page. The page should then treat any input (POST data, for example) as if it came from an untrusted source, just as a normal web page should.

 Web-accessible extension resources are not blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) or [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Because of this ability to bypass security checks, extensions should avoid using web-accessible scripts when possible. A web-accessible extension script can unexpectedly be misused by malicious websites to weaken the security of other websites. Follow the [security best practices](https://extensionworkshop.com/documentation/develop/build-a-secure-extension/) by avoiding injection of moz-extension:-URLs in web pages and ensuring that third-party libraries are up to date.


Example
-------




```
"web\_accessible\_resources": ["images/my-image.png"]

```
 Make the file at "images/my-image.png" web accessible.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `web_accessible_resources` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `extension_ids` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `matches` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `resources` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `use_dynamic_url` | 88 | 88 | No | ? | 74 | NoThe extension's base URL is always dynamic in Safari. | ? | ? | No | ? | NoThe extension's base URL is always dynamic in Safari. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources>

author
======





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"author": "Walt Whitman"
```
 |

 The extension's author, intended for display in the browser's user interface. If the <developer> key is supplied and it contains the "name" property, it will override the author key. There's no way to specify multiple authors.

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"author": "Walt Whitman"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `author` | Yes | 14This property is required. | 52 | ? | Yes | 14Not displayed in Safari Extensions settings. | ? | ? | 52 | ? | 15Not displayed in Safari Extensions settings. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/author>

browser\_action
===============





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 |
| Example | 
```
"browser\_action": {
  "browser\_style": true,
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html",
  "theme\_icons": [{
    "light": "icons/geo-16-light.png",
    "dark": "icons/geo-16.png",
    "size": 16
  }, {
    "light": "icons/geo-32-light.png",
    "dark": "icons/geo-32.png",
    "size": 32
  }]
}
```
 |

 A browser action is a button that your extension adds to the browser's toolbar. The button has an icon, and may optionally have a popup whose content is specified using HTML, CSS, and JavaScript.

 This key is replaced by [`action`](action) in Manifest V3 extensions.

 If you supply a popup, then the popup is opened when the user clicks the button, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's [background scripts](../anatomy_of_a_webextension#background_scripts) when the user clicks the button.

 You can also create and manipulate browser actions programmatically using the [browserAction API](../api/browseraction).



Syntax
------



The `browser_action` key is an object that may have any of the following properties, all optional:

 

| Name | Type | Description |
| --- | --- | --- |
| `[browser\_style](../user_interface/browser_styles)` | `Boolean` | Optional, defaulting to `false`.  Use this to include a stylesheet in your popup that will make its look consistent with the browser's UI and with other extensions that use the `browser_style` property. Although this key defaults to `false`, it's recommended that you include it and set it to `true` in order to make your popups consistent with the look of the rest of the browser user interface.   In Firefox, the stylesheet can be seen at chrome://browser/content/extension.css, or chrome://browser/content/extension-mac.css on macOS. When setting dimensions, be aware that this style sheet currently sets `box-sizing: border-box` (see [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)).   [Browser styles](../user_interface/browser_styles) describes the classes you can apply to elements in the popup in order to get particular styles.   The [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download) example extension uses `browser_style` in its popup.    **Note:** Setting `browser_style` to `true` prevents users from selecting text in an extension's popup or sidebar content. This is normal behavior. You can't select parts of the UI in the browser. However, You can work around this limitation to allow your users to select text in two ways:  1. Set `browser_style` to `false`
2. Use CSS styling on the body of your sidebar or popup's HTML to allow text selection by adding the rule `-moz-user-select` with a value of `all` or `text`.

  |
| `default_area` | `String` |  Defines the part of the browser in which the button is initially placed. This is a string that may take one of four values: * "navbar": the button is placed in the main browser toolbar, alongside the URL bar.
* "menupanel": the button is placed in a popup panel.
* "tabstrip": the button is placed in the toolbar that contains browser tabs.
* "personaltoolbar": the button is placed in the bookmarks toolbar.

This property is only supported in Firefox. This property is optional, and defaults to "menupanel".  Firefox remembers the `default_area` setting for an extension, even if that extension is uninstalled and subsequently reinstalled. To force the browser to acknowledge a new value for `default_area`, the id of the extension must be changed.   An extension can't change the location of the button after it has been installed, but the user may be able to move the button using the browser's built-in UI customization mechanism.  |
| `default_icon` | `Object` or `String` |  Use this to specify one or more icons for the browser action. The icon is shown in the browser toolbar by default.  Icons are specified as URLs relative to the manifest.json file itself. You can specify a single icon file by supplying a string here: 
```
"default\_icon": "path/to/geo.svg"
```
  To specify multiple icons in different sizes, specify an object here. The name of each property is the icon's height in pixels, and must be convertible to an integer. The value is the URL. For example:  
```
    "default\_icon": {
      "16": "path/to/geo-16.png",
      "32": "path/to/geo-32.png"
    }
```
  You cannot specify multiple icons of the same sizes.See [Choosing icon sizes](browser_action#choosing_icon_sizes) for more guidance on this.  |
| `default_popup` | `String` | The path to an HTML file containing the specification of the popup.  The HTML file may include CSS and JavaScript files using `[<link>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)` and `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` elements, just like a normal web page. However, `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)`must have `[src](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` attribute to load a file. Don't use `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` with embedded code, because you'll get a confusing Content Violation Policy error.   Unlike a normal web page, JavaScript running in the popup can access all the [WebExtension APIs](../api) (subject, of course, to the extension having the appropriate <permissions>).   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `default_title` | `String` |  Tooltip for the button, displayed when the user moves their mouse over it. If the button is added to the browser's menu panel, this is also shown under the app icon.   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `theme_icons` | `Array` |  This property enables you to specify different icons for themes depending on whether Firefox detects that the theme uses dark or light text.   If this property is present, it's an array containing at least one `ThemeIcons` object. A `ThemeIcons` object contains three mandatory properties:   `"dark"`  A URL pointing to an icon. This icon displays when a theme using dark text is active (such as the Firefox Light theme, and the Default theme if no default\_icon is specified).  `"light"`  A URL pointing to an icon. This icon displays when a theme using light text is active (such as the Firefox Dark theme).  `"size"` The size of the two icons in pixels.  Icons are specified as URLs relative to the manifest.json file.  You should supply 16x16 and 32x32 (for retina display) `ThemeIcons`.  |


Choosing icon sizes
-------------------



The browser action's icon may need to be displayed in different sizes in different contexts:

 * The icon is displayed in the browser toolbar. Older versions of Firefox supported the option of placing the icon in the browser's menu panel (the panel that opens when the user clicks the "hamburger" icon). In those versions of Firefox the icon in the menu panel was larger than the icon in the toolbar.
* On a high-density display like a Retina screen, icons needs to be twice as big.

 If the browser can't find an icon of the right size in a given situation, it will pick the best match and scale it. Scaling may make the icon appear blurry, so it's important to choose icon sizes carefully.

 There are two main approaches to this. You can supply a single icon as an SVG file, and it will be scaled correctly:

 
```
"default\_icon": "path/to/geo.svg"

```
 Alternatively, you can supply several icons in different sizes, and the browser will pick the best match.

 In Firefox:

 * The default height and width for icons in the toolbar is 16 \* [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio).
* The default height and width for icons in the menu panel is 32 \* [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio).

 So you can specify icons that match exactly, on both normal and Retina displays, by supplying three icon files, and specifying them like this:

 
```
"default\_icon": {
  "16": "path/to/geo-16.png",
  "32": "path/to/geo-32.png",
  "64": "path/to/geo-64.png"
}

```
 If Firefox can't find an exact match for the size it wants, then it will pick the smallest icon specified that's bigger than the ideal size. If all icons are smaller than the ideal size, it will pick the biggest icon specified.


Example
-------




```
"browser\_action": {
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  }
}

```
 A browser action with just an icon, specified in 2 different sizes. The extension's background scripts can receive click events when the user clicks the icon using code like this:

 
```
 browser.browserAction.onClicked.addListener(handleClick);

```
 
```
"browser\_action": {
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html"
}

```
 A browser action with an icon, a title, and a popup. The popup will be shown when the user clicks the button.

 For a simple, but complete, extension that uses a browser action, see the [walkthrough tutorial](../your_second_webextension).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `browser_action` | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14Available for use in Manifest V2 only. | 48Available for use in Manifest V2 only. | ? | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? | ? | 55Available for use in Manifest V2 only. | ? | 15["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? |
| `browser_style` | No | No | 48 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_area` | No | No | 54 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | YesSVG icons are not supported. | 14["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 48 | ? | YesSVG icons are not supported. | 14SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | No | ? | 15SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 57 | ? | 15 | ? |
| `default_title` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 55Browser actions are presented as menu items, and the title is the menu item's label. | ? | 15 | ? |
| `theme_icons` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |


See also
--------


* [`page_action`](page_action)
* [`sidebar_action`](sidebar_action)
* [Browser styles](../user_interface/browser_styles)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action>

content\_security\_policy
=========================





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | Manifest V2: 
```
"content\_security\_policy": "default-src 'self'"
```
Manifest V3: 
```
"content\_security\_policy": {
  "extension\_pages": "default-src 'self'"
}
```
 |

 Extensions have a content security policy (CSP) applied to them by default. The default policy restricts the sources from which extensions can load code (such as [<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) resources) and disallows potentially unsafe practices such as the use of [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). See [Default content security policy](../content_security_policy#default_content_security_policy) to learn more about the implications of this.

 You can use the `"content_security_policy"` manifest key to loosen or tighten the default policy. This key is specified in the same way as the Content-Security-Policy HTTP header. See [Using Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) for a general description of CSP syntax.

 For example, you can use this key to:

 * Restrict permitted sources for other types of content, such as images and stylesheets, using the appropriate [policy directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
* Allow the extension to take advantage of [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) by including the `'wasm-unsafe-eval'` source in the `script-src` directive.
* Loosen the default [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) policies (Manifest V2 only):
	+ Allow the extension to load scripts from outside its package by supplying their URL in the [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) directive.
	+ Allow the extension to execute inline scripts by [supplying the hash of the script in the `script-src` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_inline_script).
	+ Allow the extension to use `eval()` and similar features by including `'unsafe-eval'` in the [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) directive.

 There are restrictions on the policy you can specify with this manifest key:

 * The [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) directive must include at least the `'self'` keyword and may only contain secure sources. The set of permitted secure sources differs between Manifest V2 and Manifest V3.
* The policy may include [`default-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) alone (without [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src)) if its sources meet the requirement for the [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) directive.
* The [`object-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src) keyword may be required, see [object-src directive](#object-src_directive) for details.
* Directives that reference code – [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src), [`script-src-elem`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src-elem), [`worker-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/worker-src), and [`default-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src) (if used as a fallback) – share the same secure source requirement. There are no restrictions on CSP directives that cover non-script content, such as [`img-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src).

  In Manifest V3, all CSP sources that refer to external or non-static content are forbidden. The only permitted values are `'none'`, `'self'`, and `'wasm-unsafe-eval'`. In Manifest V2, a source for a script directive is considered secure if it meets these criteria: 

 * Wildcard hosts are not permitted, such as `"script-src 'self' *"`.
* Remote sources must use `https:` schemes.
* Remote sources must not use wildcards for any domains in the [public suffix list](https://publicsuffix.org/list/) (so "\*.co.uk" and "\*.blogspot.com" are not allowed, although "\*.foo.blogspot.com" is permitted).
* All sources must specify a host.
* The only permitted schemes for sources are `blob:`, `filesystem:`, `moz-extension:`, `https:`, and `wss:`.
* The only permitted [keywords](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src#sources) are: `'none'`, `'self'`, `'unsafe-eval'`, and `'wasm-unsafe-eval'`.



object-src directive
--------------------



The `[`object-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src)` directive may be required in some browsers that support obsolete [plugins](https://developer.mozilla.org/en-US/docs/Glossary/Plugin) and should be set to a secure source such as `'none'` if needed. This may be necessary for browsers up until 2022.

 * In Firefox, `"object-src"` it optional from Firefox 106. In earlier versions, if `"object-src"` isn't specified, `"content_security_policy"` is ignored and the default CSP used.
* In Chrome, `"object-src"` is required. If it's missing or deemed insecure, the default (`"object-src 'self'"`) is used and a warning message logged.
* In Safari, there is no requirement for `"object-src"`.

 See W3C WebExtensions Community Group [issue 204](https://github.com/w3c/webextensions/issues/204), Remove object-src from the CSP, for more information.


Manifest V2 syntax
------------------



In Manifest V2, there is one content security policy specified against the key like this:

 
```
"content\_security\_policy": "default-src 'self'"

```

Manifest V3 syntax
------------------



In Manifest V3, the `content_security_policy` key is an object that may have any of these properties, all optional:

 

| Name | Type | Description |
| --- | --- | --- |
| `extension_pages` | `String` | The content security policy used for extension pages. The `script-src` and `worker-src` directives may only have these values: * `'self'`
* `'none'`
* `'wasm-unsafe-eval'`
 |
| `sandbox` | `String` | The content security policy used for sandboxed extension pages. |


Examples
--------


### Valid examples



  **Note:** Valid examples demonstrate the correct use of keys in CSP. However, extensions with 'unsafe-eval', remote script, blob, or remote sources in their CSP are not allowed for Firefox extensions per the [add-on policies](https://extensionworkshop.com/documentation/publish/add-on-policies/) and due to significant security issues. 

   **Note:** Some examples include the `[`object-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src)` directive, which provides backward compatibility for older browser versions. See [object-src directive](#object-src_directive) for more details.

  Require that all types of content should be packaged with the extension:

 * Manifest V2 
```
"content\_security\_policy": "default-src 'self'"

```
* Manifest V3 
```
"content\_security\_policy": {
  "extension\_pages": "default-src 'self'"
}

```

 Allow remote scripts from "<https://example.com>":

 * Manifest V2 
```
"content\_security\_policy": "script-src 'self' https://example.com; object-src 'self'"

```
* Manifest V3 does not allow remote URLs in `script-src` of `extension_pages`.

 Allow remote scripts from any subdomain of "jquery.com":

 * Manifest V2 
```
"content\_security\_policy": "script-src 'self' https://\*.jquery.com; object-src 'self'"

```
* Manifest V3 does not allow remote URLs in `script-src` of `extension_pages`.

 Allow [`eval()` and friends](../content_security_policy#eval%28%29_and_friends):

 * Manifest V2 
```
"content\_security\_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"

```
* Manifest V3 does not allow `'unsafe-eval'` in `script-src`.

 Allow the inline script: `"<script>alert('Hello, world.');</script>"`:

 * Manifest V2 
```
"content\_security\_policy": "script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='; object-src 'self'"

```
* Manifest V3 does not allow CSP hashes in `script-src` of `extension_pages`.

 Keep the rest of the policy, but also require that images should be packaged with the extension:

 * Manifest V2 
```
"content\_security\_policy": "script-src 'self'; object-src 'self'; img-src 'self'"

```
* Manifest V3 
```
"content\_security\_policy": {
  "extension\_pages": "script-src 'self'; img-src 'self'"
}

```

 Enable the use of [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly):

 * Manifest V2 For backward compatibility, Manifest V2 extensions in Firefox can use WebAssembly without the use of `'wasm-unsafe-eval'`. However, this behavior isn't guaranteed. See [Firefox bug 1770909](https://bugzil.la/1770909). Extensions using WebAssembly are therefore encouraged to declare `'wasm-unsafe-eval'` in their CSP. See [WebAssembly](../content_security_policy#webassembly) on the Content Security Policy page for more information. 
```
"content\_security\_policy": "script-src 'self' 'wasm-unsafe-eval'"

```
* Manifest V3 
```
"content\_security\_policy": {
  "extension\_pages": "script-src 'self' 'wasm-unsafe-eval'"
}

```


### Invalid examples



Policy that omits the `"object-src"` directive:

 
```
"content\_security\_policy": "script-src 'self' https://\*.jquery.com;"

```
 However, this is only invalid in browsers that support obsolete [plugins](https://developer.mozilla.org/en-US/docs/Glossary/Plugin). See [object-src directive](#object-src_directive) for more details..

 Policy that omits the `"self"` keyword in the `"script-src"` directive:

 
```
"content\_security\_policy": "script-src https://\*.jquery.com; object-src 'self'"

```
 Scheme for a remote source is not `https`:

 
```
"content\_security\_policy": "script-src 'self' http://code.jquery.com; object-src 'self'"

```
 Wildcard is used with a generic domain:

 
```
"content\_security\_policy": "script-src 'self' https://\*.blogspot.com; object-src 'self'"

```
 Source specifies a scheme but no host:

 
```
"content\_security\_policy": "script-src 'self' https:; object-src 'self'"

```
 Directive includes the unsupported keyword `'unsafe-inline'`:

 
```
"content\_security\_policy": "script-src 'self' 'unsafe-inline'; object-src 'self'"

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `content_security_policy` | YesUntil Chrome 110, the `object-src` directive was required with a secure source. From Chrome 111, the `object-src` directive is optional. | YesUntil Edge 110, the `object-src` directive was required with a secure source. From Edge 111, the `object-src` directive is optional. | 48["Firefox does not support 'http://127.0.0.1' or 'http://localhost' as script sources: they must be served over HTTPS.", "Until Firefox 105, the `object-src` directive was required with a secure source. From Firefox 106, the `object-src` directive is optional."] | ? | YesUntil Opera 96, the `object-src` directive was required with a secure source. From Opera 97, the `object-src` directive is optional. | 14There is no requirement to include the `object-src` directive. | ? | ? | No | ? | 15There is no requirement to include the `object-src` directive. | ? |
| `extension_pages` | 88["Available for use in Manifest V3 or later.", "Until Chrome 110, the `object-src` directive was required with a secure source. From Chrome 111, the `object-src` directive is optional."] | 88["Available for use in Manifest V3 or later.", "Until Edge 110, the `object-src` directive was required with a secure source. From Edge 111, the `object-src` directive is optional."] | 72Until Firefox 105, the `object-src` directive was required with a secure source. From Firefox 106, the `object-src` directive is optional. | ? | 74["Available for use in Manifest V3 or later.", "Until Opera 96, the `object-src` directive was required with a secure source. From Opera 97, the `object-src` directive is optional."] | 15.4["Available for use in Manifest V3 or later.", "There is no requirement to include the `object-src` directive."] | ? | ? | No | ? | 15.4["Available for use in Manifest V3 or later.", "There is no requirement to include the `object-src` directive."] | ? |
| `isolated_world` | 88 | 88 | No | ? | 74 | No | ? | ? | No | ? | No | ? |
| `sandbox` | 88 | 88 | No | ? | 74 | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy>

declarative\_net\_request
=========================





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 |
| Example | 
```
"declarative\_net\_request" : {
  "rule\_resources" : [{
    "id": "ruleset",
    "enabled": true,
    "path": "rules.json"
  }]
}
```
 |

 Specify static rulesets for use with [`declarativeNetRequest`](../api/declarativenetrequest).



Syntax
------



The `"declarative_net_request"` key is an object that must contain the `"rule_resources"` property, an array that must include at least one object with these properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `"id"` | `String` | A non-empty string uniquely identifying the ruleset. IDs beginning with '\_' are reserved for internal use. |
| `"enabled"` | `Boolean` | Whether the ruleset is enabled by default. |
| `"path"` | `String` | The path of the JSON ruleset relative to the extension directory. See the [Rules](../api/declarativenetrequest#rules) section of the `declarativeNetRequest` API for information on the content of the ruleset JSON file. |


Example
-------



```
"declarative\_net\_request" : {
  "rule\_resources" : [{
    "id": "ruleset\_1",
    "enabled": true,
    "path": "rules\_1.json"
  }, {
    "id": "ruleset\_2",
    "enabled": false,
    "path": "rules\_2.json"
  }]
}

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `declarative_net_request` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `rule_resources` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/declarative_net_request>

dictionaries
============





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"dictionaries": {
  "en-US": "dictionaries/en-US.dic"
}
```
 |

 The `dictionaries` key specifies the `locale_code` for which your extension supplies a dictionary. Although the dictionary consists of two files, one with a `.dic` and one with an `.aff` file extension, only the one with the `.dic` extension is referenced in the manifest.json.

 If you use the `dictionaries` key, you must also set an ID for your extension using the [`browser_specific_settings`](browser_specific_settings) manifest.json key.



Example
-------



```
"dictionaries": {
  "en-US": "dictionaries/en-US.dic"
}

```
Browser compatibility
---------------------



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/dictionaries>

externally\_connectable
=======================





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"externally_connectable": {
  "ids": [
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "cccccccccccccccccccccccccccccccc"
  ],
  "matches": [
    "https://example1.com/*",
    "*://*.example2.com/*"
  ]
}
```
 |

 Externally connectable controls which other extensions and web pages can communicate with an extension using [`runtime.connect()`](../api/runtime/connect) and [`runtime.sendMessage()`](../api/runtime/sendmessage) message passing. If `externally_connectable` is not specified, all extensions can communicate with each other but not with web pages.

   **Note:** For communication with web pages: 

 * In Chrome, `chrome.runtime.connect` and `chrome.runtime.sendMessage` are used. These methods are only available when there is at least one extension listening for messages, see [chrome.runtime will no longer be defined unconditionally in Chrome 106](https://groups.google.com/a/chromium.org/g/chromium-extensions/c/tCWVZRq77cg/m/KB6-tvCdAgAJ) for more details.
* In Safari, `browser.runtime.connect` and `browser.runtime.sendMessage` are used.
* In Firefox, neither API is supported. See [Firefox bug 1319168](https://bugzil.la/1319168).

 

### "ids" attribute


`ids` enables communication between this extension and other installed extensions specified by extension identifiers. Use the pattern `"*"` to communicate with all extensions.

### "matches" attribute



`matches` is a list of regular expressions that enables communication between an extension and the web pages that match the expression.

  **Note:** If `externally_connectable` is not specified, communication among extensions is allowed as if `externally_connectable` specified `{"ids": ["*"] }`. Therefore, if you specify `externally_connectable.matches`, don't forget to add `ids` if you want to communicate with other extensions.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `externally_connectable` | Yes | 79 | NoSee [bug 1319168](https://bugzil.la/1319168). | ? | Yes | 15.4Safari only supports the `matches` property. | ? | ? | No | ? | 15.4Safari only supports the `matches` property. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable>

homepage\_url
=============





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"homepage\_url": "https://example.org/my-addon"
```
 |

 URL for the extension's home page.

  If a <developer> key containing the "url" property and "homepage\_url" are defined, Firefox uses "developer.url" while Opera uses "homepage\_url". Chrome and Safari do not support the "developer" key. 

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"homepage\_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `homepage_url` | Yes | 79 | 48 | ? | Yes | 14Not displayed in Safari Extensions settings. | ? | ? | 48 | ? | 15Not displayed in Safari Extensions settings. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url>

host\_permissions
=================





|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 3 or higher |
| Example | 
```
"host\_permissions": [
  "\*://developer.mozilla.org/\*",
  "\*://\*.example.org/\*"
]
```
 |

 Use the `host_permissions` key to request access for the APIs in your extension that read or modify host data, such as [`cookies`](../api/cookies), [`webRequest`](../api/webrequest), and [`tabs`](../api/tabs). This key is an array of strings, and each string is a request for a permission.

 If you request permissions using this key, the browser may prompt the user to grant the extension access to this host data at install time. Whether the user is prompted or not, the browser allows the user to control the extension's host permissions after installation: grant or revoke them as needed.

 As the request to grant host permissions may impact users' willingness to install your extension, requesting host permissions is worth careful consideration. For example, you want to avoid requesting unnecessary host permissions and may want to provide information about why you are requesting host permissions in your extension's store description. The article [Request the right permissions](https://extensionworkshop.com/documentation/develop/request-the-right-permissions/) provides more information on the issues you should consider.

 For information on how to test and preview permission requests, see [Test permission requests](https://extensionworkshop.com/documentation/develop/test-permission-requests/) on the Extension Workshop site.

 Host permissions are specified as [match patterns](../match_patterns), and each pattern identifies a group of URLs for which the extension is requesting extra privileges. For example, a host permission could be `"*://developer.mozilla.org/*"`.

 The extra privileges include:

 * [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) and [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) access to those origins without cross-origin restrictions (though not for requests from content scripts, as was the case in Manifest V2).
* the ability to read tab-specific metadata without the "tabs" permission, such as the `url`, `title`, and `favIconUrl` properties of [`tabs.Tab`](../api/tabs/tab) objects.
* the ability to inject scripts programmatically (using [`tabs.executeScript()`](../api/tabs/executescript)) into pages served from those origins.
* the ability to receive events from the [`webrequest`](../api/webrequest) API for these hosts.
* the ability to access cookies for that host using the [`cookies`](../api/cookies) API, as long as the `"cookies"` API permission is also included.
* bypassing tracking protection for extension pages where a host is specified as a full domain or with wildcards.

 In Firefox extensions get host permissions for their origin, which is of the form:

 
```
moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/

```
 where `60a20a9b-1ad4-af49-9b6c-c64c98c37920` is the extension's internal ID. The extension can get this URL programmatically by calling [`extension.getURL()`](../api/extension/geturl):

 
```
browser.extension.getURL("");
// moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/

```


Example
-------




```
 "host\_permissions": ["\*://developer.mozilla.org/\*"]

```
 Request privileged access to pages under `developer.mozilla.org`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `host_permissions` | 88Available for use in Manifest V3 or later. | 88Available for use in Manifest V3 or later. | 109Available for use in Manifest V3 or later. | ? | 74Available for use in Manifest V3 or later. | 15.4Available for use in Manifest V3 or later. | ? | ? | 109Available for use in Manifest V3 or later. | ? | 15.4Available for use in Manifest V3 or later. | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions>

commands
========





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"commands": {
  "toggle-feature": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y",
      "linux": "Ctrl+Shift+U"
    },
    "description": "Send a 'toggle-feature' event"
  }
}
```
 |

 Use the `commands` key to define one or more keyboard shortcuts for your extension.

 Each keyboard shortcut is defined with a **name**, a **combination of keys**, and a **description**. Once you've defined commands in your extension's `manifest.json`, you can listen for their associated key combinations with the [`commands`](../api/commands) JavaScript API.



Syntax
------



The `commands` key is an object, and each shortcut is a property of it. **The property's name is the name of the shortcut.**

 Each shortcut's value is an object, with up to 2 properties:

 1. `suggested_key`: the combination of keys that activate the shortcut.
2. `description`: a string that describes the shortcut; i.e. what it does.

 The `suggested_key` property is an object with any of the following properties (all strings):

 * `"default"`
* `"mac"`
* `"linux"`
* `"windows"`
* `"chromeos"`
* `"android"`
* `"ios"`

 The value of each property is the keyboard shortcut for the command on that platform, as a string containing keys separated by "`+`". The value for `"default"` is used on all platforms that are not explicitly listed.

 For example:

 
```
"commands": {
  "toggle-feature": {
    "suggested\_key": {
      "default": "Alt+Shift+U",
      "linux": "Ctrl+Shift+U"
    },
    "description": "Send a 'toggle-feature' event to the extension"
  },
  "do-another-thing": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y"
    }
  }
}

```
 This JSON defines 2 shortcuts:

 1. `"toggle-feature"`, accessed with `Ctrl` + `Shift` + `U` on Linux, and `Alt` + `Shift` + `U` on all other platforms.
2. `"do-another-thing"`, accessed with `Ctrl` + `Shift` + `Y` on all platforms.

 You could then listen for the `"toggle-feature"` command with code like this:

 
```
browser.commands.onCommand.addListener((command) => {
  if (command === "toggle-feature") {
    console.log("Toggling the feature!");
  }
});

```

### Special shortcuts



There are these 4 **special shortcuts with default actions** for which the [`commands.onCommand`](../api/commands/oncommand) event does not fire:

 * `_execute_browser_action`: works like a click on a [toolbar button](../user_interface/browser_action) created with [`browserAction`](../api/browseraction) or specified in the <browser_action> key in the manifest.json key.
* `_execute_action`: works like a click on a [toolbar button](../user_interface/browser_action) created with [`action`](../api/action) or specified in the <action> key in the manifest.json key.
* `_execute_page_action`: works like a click on an [address bar button](../user_interface/page_actions) created with [`pageAction`](../api/pageaction) or specified in the <page_action> key in the manifest.json key.
* `_execute_sidebar_action`: opens the extension's [sidebar](../user_interface/sidebars) specified in the <sidebar_action> manifest.json key.

 The availability of these special shortcuts varies between manifest versions and browsers, like this:

 

|  | Manifest V2 | Manifest V3 |
| --- | --- | --- |
| `_execute_browser_action` | Yes | No |
| `_execute_action` | No | Yes |
| `_execute_page_action` | Yes | Not available in Chromium-based browsers |
| `_execute_sidebar_action` | Firefox only | Firefox only |

 For example, this JSON defines a key combination that clicks the extension's browser action:

 
```
"commands": {
  "\_execute\_browser\_action": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y"
    }
  }
}

```

Shortcut values
---------------


There are two valid formats for shortcut keys: as a **key combination** or as a **media key**.

### Key combinations



 **Note:** On Macs, `"Ctrl"` is interpreted as `"Command"`, so if you actually need `"Ctrl"`, specify `"MacCtrl"`.

  Key combinations must consist of 2 or 3 keys:

 1. **modifier** (mandatory, except for function keys). This can be any of: `"Ctrl"`, `"Alt"`, `"Command"`, or `"MacCtrl"`.
2. **secondary modifier** (optional). If supplied, this must be either `"Shift"` or (for Firefox ≥ 63) any one of `"Ctrl"`, `"Alt"`, `"Command"`, or `"MacCtrl"`. Must not be the modifier already used as the main modifier.
3. **key** (mandatory). This can be any one of:
	* the letters `A` – `Z`
	* the numbers `0` – `9`
	* the function keys `F1` – `F12`
	* `Comma`, `Period`, `Home`, `End`, `PageUp`, `PageDown`, `Space`, `Insert`, `Delete`, `Up`, `Down`, `Left`, `Right`

 The key is then given as a string containing the set of key values, in the order listed above, separated by "`+`". For example, `"Ctrl+Shift+Z"`.

 If a key combination is already used by the browser (like `"Ctrl+P"`) or by an existing add-on, then you can't override it. You can define it, but your event handler will not be called when the user presses the key combination.


### Media keys



Alternatively, the shortcut may be specified as one of the following media keys:

 * `"MediaNextTrack"`
* `"MediaPlayPause"`
* `"MediaPrevTrack"`
* `"MediaStop"`


Updating shortcuts
------------------


Shortcuts can be updated via [`commands.update()`](../api/commands/update). Users can also update shortcuts via the "Manage Extension Shortcuts" option at `about:addons` in Firefox, as shown in [this video](https://bug1303384.bmoattachments.org/attachment.cgi?id=9051647). In Chrome, users can change shortcuts at `chrome://extensions/shortcuts`.

Example
-------



Define a single keyboard shortcut, using only the default key combination:

 
```
"commands": {
  "toggle-feature": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y"
    },
    "description": "Send a 'toggle-feature' event"
  }
}

```
 Define two keyboard shortcuts, one with a platform-specific key combination:

 
```
"commands": {
  "toggle-feature": {
    "suggested\_key": {
      "default": "Alt+Shift+U",
      "linux": "Ctrl+Shift+U"
    },
    "description": "Send a 'toggle-feature' event"
  },
  "do-another-thing": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y"
    }
  }
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `F1-F12` | Yes | 79 | 53 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `MediaNextTrack` | Yes | 79 | 57["macOS support requires the `global` command feature which isn't supported yet. See [Bug 1251795](https://bugzil.la/1251795#c11).", "Can only register one Media\* command at a time. See [Bug 1251795](https://bugzil.la/1251795#c13)."] | ? | Yes | No | ? | ? | No | ? | No | ? |
| `MediaPlayPause` | Yes | 79 | 57["macOS support requires the `global` command feature which isn't supported yet. See [Bug 1251795](https://bugzil.la/1251795#c11).", "Can only register one Media\* command at a time. See [Bug 1251795](https://bugzil.la/1251795#c13)."] | ? | Yes | No | ? | ? | No | ? | No | ? |
| `MediaPrevTrack` | Yes | 79 | 57["macOS support requires the `global` command feature which isn't supported yet. See [Bug 1251795](https://bugzil.la/1251795#c11).", "Can only register one Media\* command at a time. See [Bug 1251795](https://bugzil.la/1251795#c13)."] | ? | Yes | No | ? | ? | No | ? | No | ? |
| `MediaStop` | Yes | 79 | 57["macOS support requires the `global` command feature which isn't supported yet. See [Bug 1251795](https://bugzil.la/1251795#c11).", "Can only register one Media\* command at a time. See [Bug 1251795](https://bugzil.la/1251795#c13)."] | ? | Yes | No | ? | ? | No | ? | No | ? |
| `MoreSecondaryModifiers` | No | No | 63 | ? | No | 14 | ? | ? | No | ? | 15 | ? |
| `commands` | Yes | 79 | 48 | ? | Yes | 14Changing the keyboard shortcut for a command is not supported. | ? | ? | No | ? | 15Changing the keyboard shortcut for a command is not supported. | ? |
| `_execute_sidebar_action` | No | No | 54 | ? | No | No | ? | ? | No | ? | No | ? |
| `global` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands>

default\_locale
===============





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory |  Contingent: must be present if the \_locales subdirectory is present, must be absent otherwise.  |
| Example | 
```
"default\_locale": "en"
```
 |

 This key must be present if the extension contains the \_locales directory, and must be absent otherwise. It identifies a subdirectory of \_locales, and this subdirectory will be used to find the default strings for your extension.

 See [Internationalization](../internationalization).



Example
-------



```
"default\_locale": "en"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `default_locale` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale>

developer
=========





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"developer": {
  "name": "Walt Whitman",
  "url": "https://en.wikipedia.org/wiki/Walt\_Whitman"
}
```
 |

 The name of the extension's developer and their homepage URL, intended for display in the browser's user interface.

 The object, and both of its properties, are optional. The "name" and "url" properties, if present, will override the <author> and <homepage_url> keys, respectively. This object only allows for a single developer name and URL to be specified.

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"developer": {
  "name": "Walt Whitman",
  "url": "https://en.wikipedia.org/wiki/Walt\_Whitman"
}

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `developer` | No | No | 52 | ? | Yes | No | ? | ? | 52 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/developer>

devtools\_page
==============





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"devtools\_page": "devtools/my-page.html"
```
 |

 Use this key to enable your extension to extend the browser's built-in devtools.

 This key is defined as a URL to an HTML file. The HTML file must be bundled with the extension, and the URL is relative to the extension's root.

 See [Extending the developer tools](../extending_the_developer_tools) to learn more.



Example
-------



```
"devtools\_page": "devtools/my-page.html"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `devtools_page` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page>

incognito
=========





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"incognito": "spanning"
```
 
```
"incognito": "split"
```
 
```
"incognito": "not\_allowed"
```
 |

 Use the `incognito` key to control how the extension works with private browsing windows.

  **Note:** By default, extensions do not run in private browsing windows. Whether an extension can access private browsing windows is under user control. For details, see [Extensions in Private Browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing). Your extension can check whether it can access private browsing windows using [`extension.isAllowedIncognitoAccess`](../api/extension/isallowedincognitoaccess).

  This is a string that can take any of these values:

 * "spanning" (the default): the extension will see events from private and non-private windows and tabs. Windows and tabs will get an `incognito` property in the [`Window`](../api/windows/window) or [`Tab`](../api/tabs/tab) that represents them. This property indicates whether or not the object is private: 
```
browser.windows.getLastFocused().then((windowInfo) => {
  console.log(`Window is private: ${windowInfo.incognito}`);
});

```
* "split": the extension will be split between private and non-private windows. There are effectively two copies of the extension running: one sees only non-private windows, the other sees only private windows. Each copy has isolated access to Web APIs (so, for example, [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) is not shared). However, the WebExtension API [`storage.local`](../api/storage/local) is shared. (**Note:** this setting is not supported by Firefox.)
* "not\_allowed": private tabs and windows are invisible to the extension.



Example
-------




```
"incognito": "spanning"

```
 
```
"incognito": "split"

```
 
```
"incognito": "not\_allowed"

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `incognito` | Yes | ≤18 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `not_allowed` | Yes | 17 | 67 | ? | Yes | No | ? | ? | 67 | ? | No | ? |
| `spanning` | Yes | ≤18 | 48 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `split` | Yes | 17 | NoSee [bug 1380812](https://bugzil.la/1380812). | ? | Yes | No | ? | ? | NoSee [bug 1380812](https://bugzil.la/1380812). | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/incognito>

omnibox
=======





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"omnibox": {
  "keyword": "mdn"
}
```
 |

 Use the `omnibox` key to define an omnibox keyword for your extension.

 When the user types this keyword into the browser's address bar, followed by a space, then any subsequent characters will be sent to the extension using the [`omnibox`](../api/omnibox) API. The extension will then be able to populate the address bar's drop-down suggestions list with its own suggestions.

 If two or more extensions define the same keyword, then the extension that was installed last gets to control the keyword. Any previously installed extensions that defined the same keyword will no longer be able to use the `omnibox` API.



Example
-------



```
"omnibox": {
  "keyword": "mdn"
}

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `omnibox` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `key` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/omnibox>

optional\_permissions
=====================





|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"optional\_permissions": [
  "webRequest"
]
```
 |

 Use the `optional_permissions` key to list permissions that you want to ask for at runtime, after your extension has been installed.

 The [`permissions`](permissions) key lists permissions that your extension needs before it can be installed. In contrast, `optional_permissions` lists permissions that your extension doesn't need at install time but it may ask for after it has been installed. To ask for a permission, use the [`permissions`](../api/permissions) API. Asking for a permission may present the user with a dialog requesting them to grant the permission to your extension.

 For advice on designing your request for runtime permissions, to maximize the likelihood that users grant them, see [Request permissions at runtime](https://extensionworkshop.com/documentation/develop/request-the-right-permissions/#request_permissions_at_runtime).

 Starting with Firefox 84, users will be able to manage optional permissions from the Firefox Add-ons Manager. Extensions that use optional permissions should listen for [browser.permissions.onAdded](../api/permissions/onadded) and [browser.permissions.onRemoved](../api/permissions/onremoved) API events to know when a user grants or revokes these permissions.

 The key can contain two kinds of permissions: host permissions and API permissions.



Host permissions
----------------



These are the same as the host permissions you can specify in the [`permissions`](permissions#host_permissions) key.

  **Note:** When using Manifest V3 or higher:

 * in Chrome, host permissions must be specified in the [`host_permission`](host_permissions) manifest key.
* in Firefox, during the Manifest V3 developer preview, hosts can be in either `host_permissions` or `optional_permissions`. Subject to completion of [bug 1766026](https://bugzil.la/1766026), hosts will be specified in either `host_permissions` or `optional_host_permissions`.

 
API permissions
---------------



You can include any of the following here, but not in all browsers: check the compatibility table for browser-specific details.

 * `activeTab`
* `background`
* `bookmarks`
* `browserSettings`
* `clipboardRead`
* `clipboardWrite`
* `contentSettings`
* `contextMenus`
* `cookies`
* `debugger`
* `downloads`
* `downloads.open`
* `find`
* `geolocation`
* `history`
* `idle`
* `management`
* `nativeMessaging`
* `notifications`
* `pageCapture`
* `privacy`
* `scripting` (Manifest V3 or higher)
* `tabHide`
* `tabs`
* `topSites`
* `webNavigation`
* `webRequest`
* `webRequestBlocking`
* `webRequestFilterResponse`
* `webRequestFilterResponse.serviceWorkerScript`

 Note that this is a subset of the API permissions allowed in [`permissions`](permissions#api_permissions).

 Of this set, the following permissions are granted silently, without a user prompt:

 * `activeTab`
* `cookies`
* `idle`
* `webRequest`
* `webRequestBlocking`
* `webRequestFilterResponse`
* `webRequestFilterResponse.serviceWorkerScript`


Example
-------




```
 "optional\_permissions": ["\*://developer.mozilla.org/\*"]

```
 In Manifest V2 only, enable the extension to ask for privileged access to pages under developer.mozilla.org.

 
```
  "optional\_permissions": ["tabs"]

```
 Enable the extension to ask for access to the privileged pieces of the `tabs` API.

 
```
  "optional\_permissions": ["\*://developer.mozilla.org/\*", "tabs"]

```
 In Manifest V2 only, enable the extension to ask for both of the above permissions.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `optional_permissions` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `activeTab` | No | No | 55 | ? | No | 14 | ? | ? | 55 | ? | 15 | ? |
| `background` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `bookmarks` | Yes | 79 | 55 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `browserSettings` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `browsingData` | No | No | 77 | ? | No | No | ? | ? | No | ? | No | ? |
| `clipboardRead` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `clipboardWrite` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `contentSettings` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `contextMenus` | Yes | 79 | No | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `cookies` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `debugger` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `downloads` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `downloads_open` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `find` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `geolocation` | No | No | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |
| `history` | Yes | 79 | 55 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `idle` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `management` | Yes | 79 | 77 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `nativeMessaging` | No | No | 87 | ? | No | 14 | ? | ? | No | ? | 15 | ? |
| `notifications` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `pageCapture` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `pkcs11` | No | No | 77 | ? | No | No | ? | ? | No | ? | No | ? |
| `privacy` | Yes | 79 | 75 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `proxy` | No | No | 77 | ? | No | No | ? | ? | No | ? | No | ? |
| `sessions` | No | No | 77 | ? | No | No | ? | ? | No | ? | No | ? |
| `tabHide` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |
| `tabs` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `topSites` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `webNavigation` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `webRequest` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 55 | ? | No | ? |
| `webRequestBlocking` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `webRequestFilterResponse` | No | No | 110 | ? | No | No | ? | ? | 110 | ? | No | ? |
| `webRequestFilterResponse_serviceWorkerScript` | No | No | 95 | ? | No | No | ? | ? | 95 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions>

options\_page
=============





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"options\_page": "options/options.html"
```
 |

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

  **Warning:** This manifest key has been deprecated. Use [`options_ui`](options_ui) instead.

  Use the `options_page` key to define an [options page](../user_interface/options_pages) for your extension.

 The options page contains settings for the extension. The user can access it from the browser's add-ons manager, and you can open it from within your extension using [`runtime.openOptionsPage()`](../api/runtime/openoptionspage).

 Unlike options pages specified using the newer `options_ui` key, options pages specified using the deprecated `options_page` key don't receive browser styles and always open in a normal browser tab.



Example
-------



```
"options\_page": "options/options.html"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `options_page` | Yes | 14 | No | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |


See also
--------


* [`options_ui`](options_ui)
* [Options pages](../user_interface/options_pages)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_page>

options\_ui
===========





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"options\_ui": {
  "page": "options/options.html"
}
```
 |

 Use the `options_ui` key to define an [options page](../user_interface/options_pages) for your extension.

 The options page contains settings for the extension. The user can access it from the browser's add-ons manager, and you can open it from within your extension using [`runtime.openOptionsPage()`](../api/runtime/openoptionspage).

 You specify `options_ui` as a path to an HTML file packaged with your extension. The HTML file can include CSS and JavaScript files, just like a normal web page. Unlike a normal page, though, the JavaScript can use all the [WebExtension APIs](../api) that the extension has <permissions> for. However, it runs in a different scope than your background scripts.

  If you want to **share** data or functions between the JavaScript on your **options page** and your **background script(s)**, you can do so directly by obtaining a reference to the [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) of your background scripts by using [`extension.getBackgroundPage()`](../api/extension/getbackgroundpage), or a reference to the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) of any of the pages running within your extension with [`extension.getViews()`](../api/extension/getviews). Alternately, you can communicate between the JavaScript for your options page and your background script(s) using [`runtime.sendMessage()`](../api/runtime/sendmessage), [`runtime.onMessage`](../api/runtime/onmessage), or [`runtime.connect()`](../api/runtime/connect). The latter (or [`runtime.Port`](../api/runtime/port) equivalents) can also be used to share options between your [background script(s)](../anatomy_of_a_webextension#background_scripts) and your **[content script(s).](../content_scripts)** 

 In general, you will want to store options changed on option pages using the [storage API](../api/storage) to either [`storage.sync()`](../api/storage/sync) (if you want the settings synchronized across all instances of that browser that the user is logged into), or [`storage.local()`](../api/storage/local) (if the settings are local to the current machine/profile). If you do so and your [background script(s)](../anatomy_of_a_webextension#background_scripts) (or [content script(s)](../content_scripts)) need to know about the change, your script(s) might choose to add a listener to [`storage.onChanged`](../api/storage/onchanged).



Syntax
------



The `options_ui` key is an object with the following contents:

 

| Name | Type | Description |
| --- | --- | --- |
| `[browser\_style](../user_interface/browser_styles)`Optional | `Boolean` | Defaults to `true`.  Use this to include a stylesheet in your page that will make it look consistent with the browser's UI and with other extensions that use the `browser_style` property. Although it defaults to `true`, it's recommended that you include this property.   In Firefox, the stylesheet can be seen at `chrome://browser/content/extension.css`, or `chrome://browser/content/extension-mac.css` on macOS. When setting dimensions, be aware that this style sheet currently sets `box-sizing: border-box` (see [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)).   The [Firefox Style Guide](https://acorn.firefox.com/latest/acorn.html) describes the classes you can apply to elements in the popup in order to get particular styles.  |
| `open_in_tab`Optional | `Boolean` | Defaults to `false`.  If `true`, the options page will open in a normal browser tab, rather than being integrated into the browser's add-ons manager.  |
| `page` | `String` | Mandatory.  The path to an HTML file containing the specification of your options page.   The path is relative to the location of `manifest.json` itself.  |


Example
-------



```
"options\_ui": {
  "page": "options/options.html"
}

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `options_ui` | 40 | 79 | 48 | ? | 27 | 14 | ? | ? | 57 | ? | 15 | ? |
| `browser_style` | 40 | 79 | 55 | ? | 27 | No | ? | ? | 57 | ? | No | ? |
| `open_in_tab` | 40 | 79 | 48 | ? | NoOptions pages are always opened in a separate browser tab. | NoOptions pages are always opened in a separate browser tab. | ? | ? | 57 | ? | NoOptions pages are always opened in a separate browser tab. | ? |
| `page` | 40 | 79 | 48 | ? | 27 | 14 | ? | ? | 57 | ? | 15 | ? |


See also
--------


* [`options_page`](options_page)  Deprecated
* [Browser styles](../user_interface/browser_styles)
* [Options pages](../user_interface/options_pages)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui>

offline\_enabled
================





|  |  |
| --- | --- |
| Type | `Boolean` |
| Mandatory | No |
| Manifest version | 2 |
| Example | 
```
"offline\_enabled": true
```
 |

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

 Whether the app or extension is expected to work offline. When Chrome detects that it is offline, apps with this field set to true will be highlighted on the New Tab page.

 As of Chrome 35, apps (ChromeOS only from 2018) are assumed to be offline enabled and the default value of `"offline_enabled"` is `true` unless `"webview"` permission is requested. In this case, network connectivity is assumed to be required and `"offline_enabled"` defaults to `false`.

 The `"offline_enabled"` value is also used to determine whether a network connectivity check will be performed when launching an app in [Chrome OS kiosk mode](https://developer.chrome.com/docs/apps/manifest/kiosk_enabled/). A network connectivity check will be performed when apps are not offline enabled, and app launching put on hold until the device obtains connectivity to the Internet.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `offline_enabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/offline_enabled>

page\_action
============





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"page\_action": {
  "browser\_style": true,
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html"
}
```
 |

 A page action is an icon that your extension adds inside the browser's URL bar.

 Your extension may optionally also supply an associated popup whose content is specified using HTML, CSS, and JavaScript.

 If you supply a popup, then the popup is opened when the user clicks the icon, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's [background scripts](../anatomy_of_a_webextension#background_pages) when the user clicks the icon.

 You can also create and manipulate page actions programmatically using the [`pageAction API`](../api/pageaction).

 Page actions are like browser actions, except that they are associated with particular web pages rather than with the browser as a whole. If an action is only relevant on certain pages, then you should use a page action and display it only on relevant pages. If an action is relevant to all pages or to the browser itself, use a browser action.

 While browser actions are displayed by default, page actions are hidden by default. They can be shown for a particular tab by calling [`pageAction.show()`](../api/pageaction/show), passing in the tab's `id`. You can also change this default behavior using the `show_matches` property.



Syntax
------



The `page_action` key is an object that may have any of three properties, all optional:

 

| Name | Type | Description |
| --- | --- | --- |
| `[browser\_style](../user_interface/browser_styles)` | `Boolean` | Optional. Defaults to `false`.  Use this to include a stylesheet in your popup that will make it look consistent with the browser's UI and with other extensions that use the `browser_style` property. Although this key defaults to `false`, it's recommended that you include it and set it to `true` in order to make your popups consistent with the look of the rest of the browser user interface.   In Firefox, the stylesheet can be seen at `chrome://browser/content/extension.css`, or `chrome://browser/content/extension-mac.css` on macOS.   The [Firefox Style Guide](https://firefoxux.github.io/StyleGuide/#/controls) describes the classes you can apply to elements in the popup in order to get particular styles.   The [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download) example extension uses `browser_style` in its popup.  |
| `default_icon` | `Object` or `String` | Use this to specify an icon for the action.  It's recommended that you supply two icons here (19×19 pixels and 38×38 pixels), and specify them in an object with properties named `"19"` and `"38"`, like this:  
```
    "default\_icon": {
      "19": "geo-19.png",
      "38": "geo-38.png"
    }
```
  If you do this, then the browser will pick the right size icon for the screen's pixel density.  You can just supply a string here: 
```
"default\_icon": "geo.png"
```
  If you do this, then the icon will be scaled to fit the toolbar, and may appear blurry.  |
| `default_popup` | `String` | The path to an HTML file containing the specification of the popup.  The HTML file may include CSS and JavaScript files using `[<link>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)` and `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` elements, just like a normal web page. However, don't use `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` with embedded code, because you'll get a Content Violation Policy error. Instead, `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` must use the `[src](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` attribute to load a separate script file.   Unlike a normal web page, JavaScript running in the popup can access all the [WebExtension APIs](../api) (subject, of course, to the extension having the appropriate <permissions>).   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `default_title` | `String` |  Tooltip for the icon, displayed when the user moves their mouse over it.   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `hide_matches` | `Array` of `Match Pattern` except `<all_urls>` |  Hide the page action by default for pages whose URLs match any of the given [match patterns](../match_patterns).   Note that page actions are always hidden by default unless `show_matches` is given. Therefore, it only makes sense to include this property if `show_matches` is also given, and will override the patterns in `show_matches`.  For example, consider a value like: 
```
"page\_action": {
  "show\_matches": ["https://\*.mozilla.org/\*"],
  "hide\_matches": ["https://developer.mozilla.org/\*"]
}
```
  This shows the page action by default for all HTTPS URLs under the `"mozilla.org"` domain, except for pages under `"developer.mozilla.org"`.  |
| `show_matches` | `Array` of `Match Pattern` |  Show the page action by default for pages whose URLs match any of the given patterns.  See also `hide_matches`. |
| `pinned`  Deprecated  | `Boolean` | Optional. Defaults to `true`.  Controls whether or not the page action should appear in the location bar by default when the user installs the extension. This property is no longer supported since Firefox 89.  |


Example
-------




```
"page\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  }
}

```
 A page action with just an icon, specified in 2 different sizes. The extension's background scripts can receive click events when the user clicks the icon using code like this:

 
```
 browser.pageAction.onClicked.addListener(handleClick);

```
 
```
"page\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html"
}

```
 A page action with an icon, a title, and a popup. The popup will be shown when the user clicks the icon.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `page_action` | Yes["Since Chrome 49, page actions are displayed on the toolbar, rather than in the address bar.", "If an extension defines a page action, it is not allowed to define a browser action as well."] | 14 | 48 | ? | YesIf an extension defines a page action, it is not allowed to define a browser action as well. | 14If an extension defines a page action, it is not allowed to define a browser action as well. | ? | ? | Yes | ? | 15If an extension defines a page action, it is not allowed to define a browser action as well. | ? |
| `browser_style` | No | No | 48 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | YesSVG icons are not supported. | 14["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 48 | ? | YesSVG icons are not supported. | 14SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | Yes | ? | 15SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | Yes | ? | 15 | ? |
| `default_title` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | Yes | ? | 15 | ? |
| `hide_matches` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `pinned` | No | No | 64 | ? | No | No | ? | ? | No | ? | No | ? |
| `show_matches` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |


See also
--------


* [`browser_action`](browser_action)
* [`sidebar_action`](sidebar_action)
* [Browser styles](../user_interface/browser_styles)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action>

protocol\_handlers
==================





|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"protocol\_handlers": [
  {
    "protocol": "ircs",
    "name": "IRC Mozilla Extension",
    "uriTemplate": "https://irccloud.mozilla.com/#!/%s"
  }
]
```
 |

 Use this key to register one or more web-based protocol handlers.

 A protocol handler is an application that knows how to handle particular types of links: for example, a mail client is a protocol handler for "mailto:" links. When the user clicks a "mailto:" link, the browser opens the application selected as the handler for the "mailto:" protocol (or offers them a choice of handlers, depending on their settings).

  **Note:** By default, extensions do not run in private browsing windows. As protocol handlers are part of the extension, they don't work in private browsing windows by default. Whether an extension can access private browsing windows and its protocol handlers become active is under user control. For details, see [Extensions in Private Browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing). Your extension can check whether it can access private browsing windows using [`extension.isAllowedIncognitoAccess`](../api/extension/isallowedincognitoaccess).

  With this key, you can register a website as a handler for a particular protocol. The syntax and semantics of this key is very much like the [`Navigator.registerProtocolHandler()`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler) function, except that with `registerProtocolHandler()` a website can only register itself as a handler.

 Each protocol handler has three properties, all mandatory:

  `protocol`  A string defining the protocol. This must be either:

 * one of the following: "bitcoin", "dat", "dweb", "ftp", "geo", "gopher", "im", "ipfs", "ipns", "irc", "ircs", "magnet", "mailto", "matrix", "mms", "news", "nntp", "sip", "sms", "smsto", "ssb", "ssh", "tel", "urn", "webcal", "wtai", "xmpp".
* a string consisting of a custom name prefixed with "web+" or "ext+". For example: "web+foo" or "ext+foo". The custom name must consist only of lower-case ASCII characters. It's recommended that extensions use the "ext+" form.

  `name`  A string representing the name of the protocol handler. This will be displayed to the user when they are being asked if they want this handler to open the link.

  `uriTemplate`  A string representing the URL of the handler. This string must include "%s" as a placeholder: this will be replaced with the escaped URL of the document to be handled. This URL might be a true URL, or it could be a phone number, email address, or so forth. This is a [localizable property](../internationalization#internationalizing_manifest.json).

  

Example
-------




```
"protocol\_handlers": [
  {
    "protocol": "magnet",
    "name": "Magnet Extension",
    "uriTemplate": "https://example.com/#!/%s"
  }
]

```
 If the protocol is not in the allowed list then it has to start with 'ext+'

 
```
"protocol\_handlers": [
  {
    "protocol": "ext+foo",
    "name": "Foo Extension",
    "uriTemplate": "https://example.com/#!/%s"
  }
]

```
 Handlers can also be [extension pages](../user_interface/extension_pages).

 
```
"protocol\_handlers": [
  {
    "protocol": "magnet",
    "name": "Magnet Extension",
    "uriTemplate": "/example.xhtml#!/%s"
  }
]

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `protocol_handlers` | No | No | 54 | ? | No | No | ? | ? | 54 | ? | No | ? |
| `dat` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `dweb` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `ftp` | No | No | 88 | ? | No | No | ? | ? | 88 | ? | No | ? |
| `gopher` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |
| `ipfs` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `ipns` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `matrix` | No | No | 90 | ? | No | No | ? | ? | 90 | ? | No | ? |
| `ssb` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers>

sidebar\_action
===============





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"sidebar\_action": {
  "default\_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default\_title": "My sidebar",
  "default\_panel": "sidebar/sidebar.html",
  "open\_at\_install":true
}
```
 |
|  |  |

 A [sidebar](../user_interface/sidebars) is a pane that is displayed at the left-hand side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display.

 The sidebar\_action key enables you to define the default properties for the sidebar. You can change these properties at runtime using the [`sidebarAction`](../api/sidebaraction) API.



Syntax
------



The `sidebar_action` key is an object that may have any of the properties listed below. The only mandatory property is `default_panel`.

 

| Name | Type | Description |
| --- | --- | --- |
| `[browser\_style](../user_interface/browser_styles)` | `Boolean` | Optional, defaulting to `true`.  Use this to include a stylesheet in your popup that will make it look consistent with the browser's UI and with other extensions that use the `browser_style` property.   In Firefox, the stylesheet can be seen at chrome://browser/content/extension.css, or chrome://browser/content/extension-mac.css on macOS. When setting dimensions, be aware that this style sheet currently sets `box-sizing: border-box` (see [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)).   The [Firefox Style Guide](https://firefoxux.github.io/StyleGuide/#/controls) describes the classes you can apply to elements in the sidebar in order to get particular styles.  |
| `default_icon` | `Object` or `String` |  Use this to specify one or more icons for the sidebar. The icon is shown in the browser's UI for opening and closing sidebars.  Icons are specified as URLs relative to the manifest.json file itself. You can specify a single icon file by supplying a string here: 
```
"default\_icon": "path/to/geo.svg"
```
  To specify multiple icons in different sizes, specify an object here. The name of each property is the icon's height in pixels, and must be convertible to an integer. The value is the URL. For example:  
```
    "default\_icon": {
      "16": "path/to/geo-16.png",
      "32": "path/to/geo-32.png"
    }
```
  See [Choosing icon sizes](browser_action#choosing_icon_sizes) for more guidance on this.   This property is optional: if it is omitted, the sidebar doesn't get an icon.  |
| `default_panel` | `String` | The path to an HTML file that specifies the sidebar's contents.  The HTML file may include CSS and JavaScript files using `[<link>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)` and `[<script>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)` elements, just like a normal web page.   Unlike a normal web page, JavaScript running in the panel can access all the [WebExtension APIs](../api) (subject, of course, to the extension having the appropriate <permissions>).  This property is mandatory.  This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `default_title` | `String` |  Title for the sidebar. This is used in the browser UI for listing and opening sidebars, and is displayed at the top of the sidebar when it is open.   This property is optional: if it is omitted, the sidebar's title is the extension's `<name>`.   This is a [localizable property](../internationalization#internationalizing_manifest.json).  |
| `open_at_install` | Boolean |  Optional, defaulting to `true`. Determines whether the sidebar should open on install. The default behavior is to open the sidebar when installation is completed.  |


Example
-------




```
"sidebar\_action": {
  "default\_icon": "sidebar.svg",
  "default\_title": "My sidebar!",
  "default\_panel": "sidebar.html",
  "browser\_style": true
}

```
 For a simple example of an extension that uses a sidebar, see [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sidebar_action` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `browser_style` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | No | No | 54 | ? | 30SVG icons are not supported. | No | ? | ? | No | ? | No | ? |
| `default_panel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `default_title` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `open_at_install` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


See also
--------


* [`browser_action`](browser_action)
* [`page_action`](page_action)
* [Browser styles](../user_interface/browser_styles)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/sidebar_action>

storage
=======





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"storage": {
  "managed\_schema": "schema.json"
}
```
 |

 Use the `storage` key to specify the name of the schema file that defines the structure of data in managed storage.

 Managed data declares the enterprise policies supported by the app. Policies are analogous to options but are configured by a system administrator instead of the user, enabling the app to be configured for all users of an organization.

 After declaring the policies, they are read from the [`storage.managed`](../api/storage/managed) API. However, if a policy value does not conform to the schema, then it is not published by the `storage.managed` API. It's up to the app to enforce the policies configured by the administrator.

  **Note:** Firefox does not define a schema for managed storage, see [`storage.managed`](../api/storage/managed) for more details.

  The `storage` key is an object that has the following required property:

 

|  |  |
| --- | --- |
| `managed_schema` |  A `String` specifying the full path of the file within the extension that defines the schema of the manage storage.  |



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `storage` | Yes | 79 | No | ? | No | 14 | ? | ? | No | ? | 15 | ? |
| `managed_schema` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:**

 This page includes details from the Chrome developer website page [Manifest for storage areas](https://developer.chrome.com/docs/extensions/mv2/manifest/storage/) included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/storage>

theme\_experiment
=================





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"theme\_experiment": {
  "stylesheet": "style.css",
  "colors": {
    "popup\_affordance": "--arrowpanel-dimmed"
  },
  "images": {
    "theme\_toolbar": "--toolbar-bgimage"
  },
  "properties": {
    "toolbar\_image\_alignment":
    "--toolbar-bgalignment"
  }
}
```
 |

 This key enables the definition of experimental [`theme`](theme) key properties for the Firefox interface. These experiments are a precursor to proposing new theme features for inclusion in Firefox. Experimentation is done by:

 * creating a stylesheet that defines mappings between internal CSS selectors for Firefox UI elements and arbitrary CSS variables. The CSS variables are then mapped in the `colors`, `images`, and `properties` objects to new `theme` key properties.
* (without a stylesheet) using `colors`, `images`, and `properties` to map internal Firefox CSS selectors, such as `--arrowpanel-dimmed` to new `theme` key properties. This option limits experimentation to UI components that are associated with an inbuilt CSS variable.

 To discover the CSS selectors for Firefox UI elements or internal Firefox CSS variables use the [browser toolbox](https://firefox-source-docs.mozilla.org/devtools-user/browser_toolbox/index.html).

  **Note:** This key is only available for use in Firefox Developer Edition and Firefox Nightly channels and requires the `extensions.experiments.enabled` preference to be enabled. In Firefox 73 and earlier, the `extensions.legacy.enabled` had to be used instead.

   **Warning:** This feature is experimental and could be subject to change.

 

Syntax
------



The theme\_experiment key is an object that takes the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `stylesheet` | `String` | Optional  Name of a stylesheet providing mapping of Firefox UI element CSS selectors to CSS variables.  |
| `images` | `Object` | Optional  Mappings of CSS variables (as defined in Firefox or by the stylesheet defined in `stylesheet`) to `images` property names for use in the `<theme>` key.  |
| `colors` | `Object` | Optional  Mappings of CSS variables (as defined in Firefox or by the stylesheet defined in `stylesheet`) to `colors` property names for use in the `<theme>` key.  |
| `properties` | `Object` | Optional  Mappings of CSS variables (as defined in Firefox or by the stylesheet defined in `stylesheet`) to `properties` property names for use in the `<theme>` key.  |


Examples
--------



This example uses a stylesheet named `style.css` to provide the ability to set a color for the browser reload button in the [`theme`](theme) key.

 The stylesheet defines:

 
```
#reload-button {
  fill: var(--reload-button-color);
}

```
 where `#reload-button` is the Firefox internal CSS selector for the reload button and `--reload-button-color` is an arbitrary name.

 In the `manifest.json` file, `--reload-button-color` is then mapped to the name to be used in the `colors` property of `theme`:

 
```
"theme\_experiment": {
  "stylesheet": "style.css",
  "colors": {
    "reload\_button": "--reload-button-color"
  }
}

```
 The argument `reload_button` is used in the same way as any other `theme` property:

 
```
"theme": {
  "colors": {
    "reload\_button": "orange"
  }
}

```
 This has the effect of making the reload icon orange.

  ![Outcome of a theme experiment, showing the reload button colored orange.] 

 This property can also be used in `browser.theme.update()`. `images` and `properties` work in a similar way to `colors`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `theme_experiment` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `colors` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `images` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `properties` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/theme_experiment>

user\_scripts
=============





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 |
| Example | 
```
  "user\_scripts": {
    "api\_script": "apiscript.js",
  }

```
 |

 Instructs the browser to load a script packaged in the extension, known as the API script, this script is used to export a set of custom API methods for use in user scripts. The API script path, relative to the manifest.json file, is defined as a `string` in `"api_script"`.

  **Note:** The `user_script` key is required for the [`userScripts`](../api/userscripts) API to function, even if no API script is specified. For example. `user_scripts: {}`.

  The API script:

 * runs in the content processes.
* has access to the window and document globals related to the webpage it is attached to.
* has access to the same subset of WebExtension APIs usually available in a content script.

 The script executes automatically on any webpage defined in `matches` by [`userScripts.register`](../api/userscripts/register). However, this is before the user script sandbox object is created and the custom API methods can be exported.

 To export the custom API methods, the script listens for [`userScripts.onBeforeScript`](../api/userscripts/onbeforescript) and then export the custom API methods.

 Not every user script may need to consume all of the custom API methods. You can, therefore, include details of the APIs needed in `scriptMetadata` when running [`userScripts.register`](../api/userscripts/register). The API script then accesses the `scriptMetadata` through the `script` parameter received by the [`userScripts.onBeforeScript`](../api/userscripts/onbeforescript) listener (as `script.metadata`).



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `user_scripts` | Yes | 79 | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |
| `api_script` | Yes | 79 | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |


See also
--------


* [`userScripts`](../api/userscripts)
* [`contentScripts`](../api/contentscripts)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/user_scripts>

version\_name
=============





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"version\_name": "0.1 beta"
```
 |

 In addition to the <version> field, which is used for update purposes, [version\_name](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) can be set to a descriptive version string and will be used for display purposes if present.

 If no **version\_name** is present, the **version** field will be used for display purposes as well.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `version_name` | Yes | 79 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version_name>

short\_name
===========





|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"short\_name": "My Extension"
```
 |

 Short name for the extension. If given, this will be used in contexts where the <name> field is too long. It's recommended that the short name should not exceed 12 characters. If the short name field is not included in manifest.json, then name will be used instead and may be truncated.

 This is a [localizable property](../internationalization#internationalizing_manifest.json).



Example
-------



```
"short\_name": "My Extension"

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `short_name` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/short_name>

runtime.getManifest()
=====================


Get the complete [manifest.json](../../manifest.json) file, deserialized from JSON to an object.


Syntax
------



```
browser.runtime.getManifest()

```
### Parameters


None.

### Return value


An `object` representing the manifest.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getManifest` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Get the manifest and log the "name" property:

 
```
let manifest = browser.runtime.getManifest();
console.log(manifest.name);

```

### Example extensions



* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-getManifest) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getManifest>

permissions
===========



Enables extensions to request extra permissions at runtime, after they have been installed.

 Extensions need permissions to access more powerful WebExtension APIs. They can ask for permissions at install time, by including the permissions they need in the [`permissions`](../manifest.json/permissions) manifest.json key. The main advantages of asking for permissions at install time are:

 * The user is only asked once, so it's less disruptive for them, and a simpler decision.
* The extension can rely on the access to the APIs it needs, because if already running, the permissions have been granted.

 In most major browsers, users can see if their installed extensions request advanced permissions through the browser's extensions manager.

 With the permissions API, an extension can ask for additional permissions at runtime. These permissions need to be listed in the [`optional_permissions`](../manifest.json/optional_permissions) manifest.json key. Note that some permissions are not allowed in `optional_permissions`. The main advantages of this are:

 * The extension can run with a smaller set of permissions, except when it actually needs them.
* The extension can handle permission denial in a graceful manner, instead of presenting the user with a global "all or nothing" choice at install time. You can still get a lot out of that map extension, without giving it access to your location, for example.
* The extension may need [host permissions](../manifest.json/permissions#host_permissions), but not know at install time which host permissions it needs. For example, the list of hosts may be a user setting. In this scenario, asking for a more specific range of hosts at runtime, can be an alternative to asking for "<all\_urls>" at install time.

 To use the permissions API, decide which permissions your extension can request at runtime, and list them in [`optional_permissions`](../manifest.json/optional_permissions). After this, you can request any permissions that were included in `optional_permissions`. Requests may only be made in the handler for a user action (for example, a click handler).

 Starting with Firefox 84, users will be able to manage optional permissions of installed extensions from the Add-ons Manager. Extensions that use optional permissions should listen for [browser.permissions.onAdded](permissions/onadded) and [browser.permissions.onRemoved](permissions/onremoved) API events to know when a user grants or revokes these permissions.

 For advice on designing your request for runtime permissions, to maximize the likelihood that users grant them, see [Request permissions at runtime](https://extensionworkshop.com/documentation/develop/request-the-right-permissions/#request_permissions_at_runtime).



Types
-----


 [`permissions.Permissions`](permissions/permissions)  Represents a set of permissions.

  Methods
-------


 [`permissions.contains()`](permissions/contains)  Discover an extension's given set of permissions.

  [`permissions.getAll()`](permissions/getall)  Get all the permissions this extension currently has.

  [`permissions.remove()`](permissions/remove)  Give up a set of permissions.

  [`permissions.request()`](permissions/request)  Ask for a set of permissions.

  Event handlers
--------------


 [`permissions.onAdded`](permissions/onadded)  Fired when a new permission is granted.

  [`permissions.onRemoved`](permissions/onremoved)  Fired when a permission is removed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Permissions` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `contains` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `getAll` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `onAdded` | Yes | 79 | 77 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `onRemoved` | Yes | 79 | 77 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `remove` | Yes | 79 | 55 | ? | Yes | 14Removing `<all_urls>` or `*://*/*` origins will remove previously granted permission to request specific origin patterns and will stop automatically prompting the user for access to any visited website via the extension's access popover in the toolbar. | ? | ? | 79 | ? | 15Removing `<all_urls>` or `*://*/*` origins will remove previously granted permission to request specific origin patterns and will stop automatically prompting the user for access to any visited website via the extension's access popover in the toolbar. | ? |
| `request` | Yes | 79 | 55["It's not possible to request permissions from a sidebar document ([bug 1493396](https://bugzil.la/1493396)).", "Before version 75, permissions cannot be requested from popup panels (see [bug 1432083](https://bugzil.la/1432083)).", "Before version 61, permissions cannot be requested from options pages embedded in `about:addons` (see [bug 1382953](https://bugzil.la/1382953))."] | ? | Yes | 14["Requesting `<all_urls>` or `*://*/*` origins will grant permission to request specific origin patterns and automatically prompt the user for access to any visited website via the extension's access popover in the toolbar.", "The user will be prompted again for permissions that have been previously granted and then removed.", "Supported permissions will be granted without prompting the user. Only specific origin patterns will prompt the user."] | ? | ? | 102 | ? | 15["Requesting `<all_urls>` or `*://*/*` origins will grant permission to request specific origin patterns and automatically prompt the user for access to any visited website via the extension's banner.", "The user will be prompted again for permissions that have been previously granted and then removed.", "Supported permissions will be granted without prompting the user. Only specific origin patterns will prompt the user."] | ? |


See also
--------


* `manifest.json` [`permissions`](../manifest.json/permissions) property
* `manifest.json` [`optional_permissions`](../manifest.json/optional_permissions) property
Example extensions
------------------



* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)

  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions>

downloads
=========



Enables extensions to interact with the browser's download manager. You can use this API module to download files, cancel, pause, resume downloads, and show downloaded files in the file manager.

 To use this API you need to have the "downloads" [API permission](../manifest.json/permissions#api_permissions) specified in your [manifest.json](../manifest.json) file.



Types
-----


 [`downloads.FilenameConflictAction`](downloads/filenameconflictaction)  Defines options for what to do if the name of a downloaded file conflicts with an existing file.

  [`downloads.InterruptReason`](downloads/interruptreason)  Defines a set of possible reasons why a download was interrupted.

  [`downloads.DangerType`](downloads/dangertype)  Defines a set of common warnings of possible dangers associated with downloadable files.

  [`downloads.State`](downloads/state)  Defines different states that a current download can be in.

  [`downloads.DownloadItem`](downloads/downloaditem)  Represents a downloaded file.

  [`downloads.StringDelta`](downloads/stringdelta)  Represents the difference between two strings.

  [`downloads.DoubleDelta`](downloads/doubledelta)  Represents the difference between two doubles.

  [`downloads.BooleanDelta`](downloads/booleandelta)  Represents the difference between two booleans.

  [`downloads.DownloadTime`](downloads/downloadtime)  Represents the time a download took to complete.

  [`downloads.DownloadQuery`](downloads/downloadquery)  Defines a set of parameters that can be used to search the downloads manager for a specific set of downloads.

  Functions
---------


 [`downloads.download()`](downloads/download)  Downloads a file, given its URL and other optional preferences.

  [`downloads.search()`](downloads/search)  Queries the [`DownloadItems`](downloads/downloaditem) available in the browser's downloads manager, and returns those that match the specified search criteria.

  [`downloads.pause()`](downloads/pause)  Pauses a download.

  [`downloads.resume()`](downloads/resume)  Resumes a paused download.

  [`downloads.cancel()`](downloads/cancel)  Cancels a download.

  [`downloads.getFileIcon()`](downloads/getfileicon)  Retrieves an icon for the specified download.

  [`downloads.open()`](downloads/open)  Opens the downloaded file with its associated application.

  [`downloads.show()`](downloads/show)  Opens the platform's file manager application to show the downloaded file in its containing folder.

  [`downloads.showDefaultFolder()`](downloads/showdefaultfolder)  Opens the platform's file manager application to show the default downloads folder.

  [`downloads.erase()`](downloads/erase)  Erases matching [`DownloadItems`](downloads/downloaditem) from the browser's download history, without deleting the downloaded files from disk.

  [`downloads.removeFile()`](downloads/removefile)  Removes a downloaded file from disk, but not from the browser's download history.

  [`downloads.acceptDanger()`](downloads/acceptdanger)  Prompts the user to accept or cancel a dangerous download.

  [`downloads.drag()`](downloads/drag)  Initiates dragging the downloaded file to another application.

  [`downloads.setShelfEnabled()`](downloads/setshelfenabled)  Enables or disables the gray shelf at the bottom of every window associated with the current browser profile. The shelf will be disabled as long as at least one extension has disabled it.

  Events
------


 [`downloads.onCreated`](downloads/oncreated)  Fires with the [`DownloadItem`](downloads/downloaditem) object when a download begins.

  [`downloads.onErased`](downloads/onerased)  Fires with the `downloadId` when a download is erased from history.

  [`downloads.onChanged`](downloads/onchanged)  When any of a [`DownloadItem`](downloads/downloaditem)'s properties except `bytesReceived` changes, this event fires with the `downloadId` and an object containing the properties that changed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BooleanDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `DangerType` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `DoubleDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `DownloadQuery` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `DownloadTime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `FilenameConflictAction` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `InterruptReason` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `State` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `StringDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `acceptDanger` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `cancel` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `download` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `drag` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `erase` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `getFileIcon` | Yes | 79 | 48 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onChanged` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `onCreated` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `onErased` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `open` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `pause` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `removeFile` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `resume` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `search` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `setShelfEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `show` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `showDefaultFolder` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Example extensions
------------------



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads>

runtime
=======



This module provides information about your extension and the environment it's running in.

 It also provides messaging APIs enabling you to:

 * Communicate between different parts of your extension. For advice on choosing between the messaging options, see [Choosing between one-off messages and connection-based messaging](../content_scripts#choosing_between_one-off_messages_and_connection-based_messaging).
* Communicate with other extensions.
* Communicate with native applications.



Types
-----


 [`runtime.Port`](runtime/port)  Represents one end of a connection between two specific contexts, which can be used to exchange messages.

  [`runtime.MessageSender`](runtime/messagesender)  Contains information about the sender of a message or connection request.

  [`runtime.PlatformOs`](runtime/platformos)  Identifies the browser's operating system.

  [`runtime.PlatformArch`](runtime/platformarch)  Identifies the browser's processor architecture.

  [`runtime.PlatformInfo`](runtime/platforminfo)  Contains information about the platform the browser is running on.

  [`runtime.RequestUpdateCheckStatus`](runtime/requestupdatecheckstatus)  Result of a call to [`runtime.requestUpdateCheck()`](runtime/requestupdatecheck).

  [`runtime.OnInstalledReason`](runtime/oninstalledreason)  The reason that the [`runtime.onInstalled`](runtime/oninstalled) event is being dispatched.

  [`runtime.OnRestartRequiredReason`](runtime/onrestartrequiredreason)  The reason that the [`runtime.onRestartRequired`](runtime/onrestartrequired) event is being dispatched.

  Properties
----------


 [`runtime.lastError`](runtime/lasterror)  This value is set when an asynchronous function has an error condition that it needs to report to its caller.

  [`runtime.id`](runtime/id)  The ID of the extension.

  Functions
---------


 [`runtime.getBackgroundPage()`](runtime/getbackgroundpage)  Retrieves the [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for the background page running inside the current extension.

  [`runtime.openOptionsPage()`](runtime/openoptionspage)  Opens your extension's [options page](../user_interface/options_pages).

  [`runtime.getFrameId()`](runtime/getframeid)  Gets the frame ID of any window global or frame element.

  [`runtime.getManifest()`](runtime/getmanifest)  Gets the complete [manifest.json](../manifest.json) file, serialized as an object.

  [`runtime.getURL()`](runtime/geturl)  Given a relative path from the [manifest.json](../manifest.json) to a resource packaged with the extension, returns a fully-qualified URL.

  [`runtime.setUninstallURL()`](runtime/setuninstallurl)  Sets a URL to be visited when the extension is uninstalled.

  [`runtime.reload()`](runtime/reload)  Reloads the extension.

  [`runtime.requestUpdateCheck()`](runtime/requestupdatecheck)  Checks for updates to this extension.

  [`runtime.connect()`](runtime/connect)  Establishes a connection from a content script to the main extension process, or from one extension to a different extension.

  [`runtime.connectNative()`](runtime/connectnative)  Connects the extension to a native application on the user's computer.

  [`runtime.sendMessage()`](runtime/sendmessage)  Sends a single message to event listeners within your extension or a different extension. Similar to [`runtime.connect`](runtime/connect) but only sends a single message, with an optional response.

  [`runtime.sendNativeMessage()`](runtime/sendnativemessage)  Sends a single message from an extension to a native application.

  [`runtime.getPlatformInfo()`](runtime/getplatforminfo)  Returns information about the current platform.

  [`runtime.getBrowserInfo()`](runtime/getbrowserinfo)  Returns information about the browser in which this extension is installed.

  [`runtime.getPackageDirectoryEntry()`](runtime/getpackagedirectoryentry)  Returns a DirectoryEntry for the package directory.

  Events
------


 [`runtime.onStartup`](runtime/onstartup)  Fired when a profile that has this extension installed first starts up. This event is not fired when an incognito profile is started.

  [`runtime.onInstalled`](runtime/oninstalled)  Fired when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.

  [`runtime.onSuspend`](runtime/onsuspend)  Sent to the event page just before the extension is unloaded. This gives the extension an opportunity to do some cleanup.

  [`runtime.onSuspendCanceled`](runtime/onsuspendcanceled)  Sent after [`runtime.onSuspend`](runtime/onsuspend) to indicate that the extension won't be unloaded after all.

  [`runtime.onUpdateAvailable`](runtime/onupdateavailable)  Fired when an update is available, but isn't installed immediately because the extension is currently running.

  
[`runtime.onBrowserUpdateAvailable`](runtime/onbrowserupdateavailable)  Deprecated 
  Fired when an update for the browser is available, but isn't installed immediately because a browser restart is required.

  [`runtime.onConnect`](runtime/onconnect)  Fired when a connection is made with either an extension process or a content script.

  [`runtime.onConnectExternal`](runtime/onconnectexternal)  Fired when a connection is made with another extension.

  [`runtime.onMessage`](runtime/onmessage)  Fired when a message is sent from either an extension process or a content script.

  [`runtime.onMessageExternal`](runtime/onmessageexternal)  Fired when a message is sent from another extension. Cannot be used in a content script.

  [`runtime.onRestartRequired`](runtime/onrestartrequired)  Fired when the device needs to be restarted.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MessageSender` | 26 | 14 | 45Before version 54, 'id' was the add-on's internal UUID, not the add-on ID. | ? | 15 | 14 | ? | ? | 48Before version 54, 'id' was the add-on's internal UUID, not the add-on ID. | ? | 15 | ? |
| `OnInstalledReason` | YesUses 'chrome\_update' instead of 'browser\_update'. | 14Only supports 'install' and 'update'. | 45 | ? | YesUses 'chrome\_update' instead of 'browser\_update'. | 14Only supports 'install' and 'update'. | ? | ? | 48 | ? | 15Only supports 'install' and 'update'. | ? |
| `OnRestartRequiredReason` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `PlatformArch` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `PlatformInfo` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `PlatformNaclArch` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `PlatformOs` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `Port` | 26 | 15 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `RequestUpdateCheckStatus` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `connect` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `connectNative` | 29 | 15 | 50 | ? | 16 | 14See the documentation on developer.apple.com about native messaging in Safari. | ? | ? | 68 | ? | 15See the documentation on developer.apple.com about native messaging in Safari. | ? |
| `getBackgroundPage` | 22 | 14 | 45If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then it will always return `null`. | ? | 15 | 14 | ? | ? | 48If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then it will always return `null`. | ? | 15 | ? |
| `getBrowserInfo` | No | No | 51 | ? | No | No | ? | ? | 51 | ? | No | ? |
| `getFrameId` | No | No | 96 | ? | No | 16 | ? | ? | 96 | ? | 16 | ? |
| `getManifest` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `getPackageDirectoryEntry` | 29 | 79 | No | ? | 16 | No | ? | ? | No | ? | No | ? |
| `getPlatformInfo` | 29 | 79 | 45 | ? | 16 | 14 | ? | ? | 48 | ? | 15 | ? |
| `getURL` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `id` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `lastError` | YeslastError is not an Error object. Instead, it is a plain Object with the error text as the string value of the 'message' property. | 14 | 47 | ? | YeslastError is not an Error object. Instead, it is a plain Object with the error text as the string value of the 'message' property. | 14`lastError` is only set if a callback is used. `Promise` results that fail will be rejected with an `Error` object. | ? | ? | 48 | ? | 15`lastError` is only set if a callback is used. `Promise` results that fail will be rejected with an `Error` object. | ? |
| `onBrowserUpdateAvailable` | 27 | 79 | No | ? | 15 | No | ? | ? | No | ? | No | ? |
| `onConnect` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `onConnectExternal` | 26 | 79 | 54 | ? | 15 | No | ? | ? | 54 | ? | No | ? |
| `onInstalled` | 22 | 14 | 52Before version 55, this event is not triggered for temporarily installed add-ons. | ? | 15 | 14 | ? | ? | 52Before version 55, this event is not triggered for temporarily installed add-ons. | ? | 15 | ? |
| `onMessage` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `onMessageExternal` | 26 | 79 | 54 | ? | 15 | 15.4Since Safari 15.4, this event is also fired in response to a message from webpages allowed in [`externally_connectable`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable).14This event is only fired in response to a message from an extension's containing app, not webpages nor other extensions. | ? | ? | 54 | ? | 15.4Since Safari 15.4, this event is also fired in response to a message from webpages allowed in [`externally_connectable`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable).15This event is only fired in response to a message from an extension's containing app, not webpages nor other extensions. | ? |
| `onRestartRequired` | 29 | 79 | No | ? | 16 | No | ? | ? | No | ? | No | ? |
| `onStartup` | 23 | 79 | 52 | ? | 15 | 14 | ? | ? | 52 | ? | 15 | ? |
| `onSuspend` | 22 | 79 | 100This event does not fire until Firefox 106, when event pages are available. | ? | 15 | No | ? | ? | 100This event does not fire until Firefox 106, when event pages are available. | ? | No | ? |
| `onSuspendCanceled` | 22 | 79 | 100This event does not fire until Firefox 106, when event pages are available. | ? | 15 | No | ? | ? | 100This event does not fire until Firefox 106, when event pages are available. | ? | No | ? |
| `onUpdateAvailable` | 25 | 79 | 51 | ? | 15 | No | ? | ? | 51 | ? | No | ? |
| `openOptionsPage` | 42 | 79 | 48 | ? | 29 | 14 | ? | ? | 57 | ? | 15 | ? |
| `reload` | 25 | 15 | 51 | ? | 15 | 14 | ? | ? | 51 | ? | 15 | ? |
| `requestUpdateCheck` | 25 | 79 | No | ? | 15 | No | ? | ? | No | ? | No | ? |
| `sendMessage` | 26 | 14`runtime.onMessage` listeners in extension views receive the messages they sent. | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `sendNativeMessage` | 29 | 15 | 50 | ? | 16 | 14See the documentation on developer.apple.com about native messaging in Safari. | ? | ? | 68 | ? | 15See the documentation on developer.apple.com about native messaging in Safari. | ? |
| `setUninstallURL` | 41 | 15 | 47 | ? | 28 | 14API exists, but has no effect. | ? | ? | 48 | ? | 15API exists, but has no effect. | ? |


Example extensions
------------------



* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers)
* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [mocha-client-tests](https://github.com/mdn/webextensions-examples/tree/master/mocha-client-tests)
* [native-messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)
* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [user-script-register](https://github.com/mdn/webextensions-examples/tree/master/user-script-register)
* [webpack-modules](https://github.com/mdn/webextensions-examples/tree/master/webpack-modules)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime>

tabs.query()
============



Gets all tabs that have the specified properties, or all tabs if no properties are specified.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let querying = browser.tabs.query(queryObj)

```
### Parameters


 `queryObj`  `object`. The `query()` function will only get tabs whose properties match the properties included here.

 See the [`tabs.Tab`](tab) documentation to learn more about these properties.

  
`active` Optional
  `boolean`. Whether the tabs are active in their windows.

  
`audible` Optional
  `boolean`. Whether the tabs are audible.

  
`autoDiscardable` Optional
  `boolean`. Whether the tabs can be discarded automatically by the browser when resources are low.

  
`cookieStoreId` Optional
  `string` or `array` of `string`. Use this to return tabs whose `tab.cookieStoreId` matches any of the `cookieStoreId` strings. This option is only available if the add-on has the `"cookies"` [permission](../../manifest.json/permissions).

  
`currentWindow` Optional
  `boolean`. Whether the tabs are in the current window.

  
`discarded` Optional
  `boolean`. Whether the tabs are discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content gets reloaded the next time it's activated.

  
`hidden` Optional
  `boolean`. Whether the tabs are hidden.

  
`highlighted` Optional
  `boolean`. Whether the tabs are highlighted.

  
`index` Optional
  `integer`. The position of the tabs within their windows.

  
`muted` Optional
  `boolean`. Whether the tabs are muted.

  
`lastFocusedWindow` Optional
  `boolean`. Whether the tabs are in the last focused window.

  
`pinned` Optional
  `boolean`. Whether the tabs are pinned.

  
`status` Optional
  [`tabs.TabStatus`](tabstatus). Whether the tabs have completed loading.

  
`title` Optional
  `string`. Match page titles against a pattern. Requires the "tabs" permission or [host permissions](../../manifest.json/permissions#host_permissions) for the tab to match.

  
`url` Optional
  `string` or `array` of `string`. Match tabs against one or more [match patterns](../../match_patterns). Note that fragment identifiers are not matched. Requires the "tabs" permission or [host permissions](../../manifest.json/permissions#host_permissions) for the tab to match.

  
`windowId` Optional
  `integer`. The `id` of the parent window, or [`windows.WINDOW_ID_CURRENT`](../windows/window_id_current) for the current window.

  
`windowType` Optional
  [`tabs.WindowType`](windowtype). The type of window the tabs are in.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `array` of `[`tabs.Tab`](tab)` objects, containing information about each matching tab.

 If any error occurs, the promise will be rejected with an error message.


Examples
--------



Get all tabs:

 
```
function logTabs(tabs) {
  for (const tab of tabs) {
    // tab.url requires the `tabs` permission or a matching host permission.
    console.log(tab.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.tabs.query({}).then(logTabs, onError);

```
 Get all tabs in the current window:

 
```
function logTabs(tabs) {
  for (const tab of tabs) {
    // tab.url requires the `tabs` permission or a matching host permission.
    console.log(tab.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.tabs.query({ currentWindow: true }).then(logTabs, onError);

```
 Get the active tab in the current window:

 
```
function logTabs(tabs) {
  // tabs[0].url requires the `tabs` permission or a matching host permission.
  console.log(tabs[0].url);
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.tabs
  .query({ currentWindow: true, active: true })
  .then(logTabs, onError);

```
 Get tabs for all HTTP and HTTPS URLs under `"mozilla.org"` or any of its subdomains:

 
```
function logTabs(tabs) {
  for (const tab of tabs) {
    // tab.url requires the `tabs` permission or a matching host permission.
    console.log(tab.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.tabs.query({ url: "\*://\*.mozilla.org/\*" }).then(logTabs, onError);

```

### Example extensions


* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [list-cookies](https://github.com/mdn/webextensions-examples/tree/master/list-cookies)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `query` | Yes | 14The `panel`, `app`, `devtools` and `popup` values for `WindowType` are not supported. | 45 | ? | Yes | 14Pattern matching supports `*` and `?`. | ? | ? | 54 | ? | 15Pattern matching supports `*` and `?`. | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-query) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query>

theme
=====





|  |  |
| --- | --- |
| Type | `Object` |
| Mandatory | No |
| Manifest version | 2 or higher |
| Example | 
```
"theme": {
  "images": {
    "theme\_frame": "images/sun.jpg"
  },
  "colors": {
    "frame": "#CF723F",
    "tab\_background\_text": "#000"
  }
}
```
 |

 Use the theme key to define a static theme to apply to Firefox.

  **Note:** If you want to include a theme with an extension, please see the [`theme`](../api/theme) API.

   **Note:** Since May 2019, themes need to be signed to be installed ([Firefox bug 1545109](https://bugzil.la/1545109)). See [Signing and distributing your add-on](https://extensionworkshop.com/documentation/publish/signing-and-distribution-overview/#distributing-your-addon) for more details.

   **Note:** A new version of Firefox for Android, based on GeckoView, is under development. A [pre-release version](https://play.google.com/store/apps/details?id=org.mozilla.fenix) is available. The pre-release version does not support themes.

 

Image formats
-------------



The following image formats are supported in all theme image properties:

 * JPEG
* PNG
* APNG
* SVG (animated SVG is supported from Firefox 59)
* GIF (animated GIF isn't supported)


Syntax
------



The theme key is an object that takes the following properties:

 

| Name | Type | Description |
| --- | --- | --- |
| `images` | `Object` | Optional as of Firefox 60. Mandatory before Firefox 60.  A JSON object whose properties represent the images to display in various parts of the browser. See `[images](#images)` for details on the properties that this object can contain.  |
| `colors` | `Object` | Mandatory.  A JSON object whose properties represent the colors of various parts of the browser. See `[colors](#colors)` for details on the properties that this object can contain.  |
| `properties` | `Object` | Optional  This object has properties that affect how the `"additional_backgrounds"` images are displayed and color schemes are applied. See `[properties](#properties)` for details on the properties that this object can contain.  |


### images



All URLs are relative to the manifest.json file and cannot reference an external URL.

 Images should be 200 pixels high to ensure they always fill the header space vertically.

 

| Name | Type | Description |
| --- | --- | --- |
| `headerURL`  Deprecated  | `String` |   **Warning:** `headerURL` has been removed in Firefox 70. You will begin to get warnings in Firefox 65 and later if you load a theme that uses this property. Use `theme_frame` instead.    The URL of a foreground image to be added to the header area and anchored to the upper right corner of the header area.   Optional in desktop Firefox from Firefox 60 onwards. One of `theme_frame` or `headerURL` had to be specified before Firefox 60. Note also that in Firefox 60 onwards, any [`text-shadow`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) applied to the header text is removed if no `headerURL` is specified (see [Firefox bug 1404688](https://bugzil.la/1404688)).   In Firefox for Android, `headerURL` or `theme_frame` must be specified.  |
| `theme_frame` | `String` |  The URL of a foreground image to be added to the header area and anchored to the upper right corner of the header area.    **Note:** Chrome anchors the image to the top left of the header and if the image doesn't fill the header area tile the image.    Optional in desktop Firefox 60 onwards. One of `theme_frame` or `headerURL` had to be specified before Firefox 60.   In Firefox for Android, `headerURL` or `theme_frame` must be specified.  |
| `additional_backgrounds` | `Array` of `String` |   **Warning:** The `additional_backgrounds` property is experimental. It is currently accepted in release versions of Firefox, but its behavior is subject to change. It is not supported in Firefox for Android.    An array of URLs for additional background images to be added to the header area and displayed behind the `"theme_frame":` image. These images layer the first image in the array on top, the last image in the array at the bottom.  Optional.  By default all images are anchored to the upper right corner of the header area, but their alignment and repeat behavior can be controlled by properties of `"properties":`.  |


### colors



These properties define the colors used for different parts of the browser. They are all optional (but note that `"accentcolor"` and `"textcolor"` were mandatory in Firefox before version 63). How these properties affect the Firefox UI is shown here:

 

|  |
| --- |
|  Overview of the color properties and how they apply to Firefox UI components  |

  **Note:** Where a component is affected by multiple color properties, the properties are listed in order of precedence.

  All these properties can be specified as either a string containing any valid [CSS color string](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) (including hexadecimal), or an RGB array, such as `"tab_background_text": [ 107 , 99 , 23 ]`.

  **Note:** [In Chrome, colors may only be specified as RGB arrays](#chrome_compatibility).

 In Firefox for Android colors can be specified using:

 * full hexadecimal notation, that is #RRGGBB only. *alpha* and shortened syntax, as in #RGB[A], are not supported.
* [Functional notation](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb_syntax_variations) (RGB arrays) for themes targeting Firefox 68.2 or later.

 Colors for Firefox for Android themes cannot be specified using color names.

  

| Name | Description |
| --- | --- |
| `accentcolor`  Deprecated  |   **Warning:** `accentcolor` has been removed in Firefox 70. You will begin to get warnings in Firefox 65 and later if you load a theme that uses this property. Use the `frame` property instead.    The color of the header area background, displayed in the part of the header not covered or visible through the images specified in `"headerURL"` and `"additional_backgrounds"`.   See example 
```
"theme": {
  "colors": {
     "accentcolor": "red",
     "tab\_background\_text": "white"
  }
}
```
   Browser firefox is red with white text. Browsers tabs are lighter red, also with white text. URL bar is very light red with black text  |
| `bookmark_text` |  The color of text and icons in the bookmark and find bars. Also, if `tab_text` isn't defined it sets the color of the active tab text and if `icons` isn't defined the color of the toolbar icons. Provided as Chrome compatible alias for `toolbar_text`.    **Note:** Ensure any color used contrasts well with those used in `frame` and `frame_inactive` or `toolbar` if you're using that property.   Where `icons` isn't defined, also ensure good contrast with `button_background_active` and `button_background_hover`.    See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "tab\_text": "white",
    "toolbar": "black",
    "bookmark\_text": "red"
  }
}
```
   Browser Firefox is black. Browser's tab is black with white text. URL bar and the find in page bar are white with black text but all the browser and the find in page bar icons are red.  |
| `button_background_active` | The color of the background of the pressed toolbar buttons.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "button\_background\_active": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are grey with white text. The customize toolbar icon in the url bar in white with a red background is pressed and a popup is open displaying a short list of thing to add to the toolbar such as the browser's library and the sidebars.  |
| `button_background_hover` | The color of the background of the toolbar buttons on hover.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "button\_background\_hover": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are grey with white text. The go back one page icon is white with a red circle background.  |
| `icons` | The color of toolbar icons, excluding those in the find toolbar.   **Note:** Ensure the color used contrasts well with those used in `frame`, `frame_inactive`, `button_background_active`, and `button_background_hover`.    See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "icons": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are grey with white text. The URL bar and open a new tab icons are red. The red icons contrast well with the black background color of the header area.  |
| `icons_attention` |  The color of toolbar icons in attention state such as the starred bookmark icon or finished download icon.    **Note:** Ensure the color used contrasts well with those used in `frame`, `frame_inactive`, `button_background_active`, and `button_background_hover`.    See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "icons\_attention": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are grey with white text. The bookmark this page icon is red and pressed, an open popup name edit this bookmark is displayed. While in attention state, the toolbar icons contrast well with the black background of the header area.  |
| `frame` |  The color of the header area background, displayed in the part of the header not covered or visible through the images specified in `"theme_frame"` and `"additional_backgrounds"`.   See example 
```
"theme": {
  "colors": {
     "frame": "red",
     "tab\_background\_text": "white"
  }
}
```
   Browser firefox is red with white text. Browsers tabs are lighter red, also with white text. URL bar is very light red with black text  |
| `frame_inactive` |  The color of the header area background when the browser window is inactive, displayed in the part of the header not covered or visible through the images specified in `"theme_frame"` and `"additional_backgrounds"`.   See example 
```
"theme": {
  "colors": {
     "frame": "red",
     "frame\_inactive": "gray",
     "tab\_text": "white"
  }
}
```
   Browser firefox is grey. Browser's tabs and URL bar are lighter grey. The tab text is white and the URL bar icon are darker grey.  |
| `ntp_background` | The new tab page background color.  See example 
```
"theme": {
  "colors": {
     "ntp\_background": "red",
     "ntp\_text": "white"
  }
}
```
   Browser firefox is white. The new tab page background is red, with google search at the top, follow by top sites shortcut and recommended articles.  |
| `ntp_text` | The new tab page text color.   **Note:** Ensure the color used contrasts well with that used in `ntp_background`.    See example 
```
"theme": {
  "colors": {
     "ntp\_background": "red",
     "ntp\_text": "white"
  }
}
```
   Browser firefox is white. The new tab page background is red, with google search at the top, follow by top sites shortcut and recommended articles. The color of the text in the new tab page is white.  |
| `popup` |  The background color of popups (such as the URL bar dropdown and the arrow panels).   See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "popup": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are lighter grey with icons and text in white. The bookmark this page icon is blue and pressed, an open popup name 'edit this bookmark' is displayed with a red background. The background color of the popup is red.  |
| `popup_border` | The border color of popups.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "popup": "black",
     "popup\_text": "white",
     "popup\_border": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are lighter grey with icons and text in white. The bookmark this page icon is blue and pressed, an open popup name 'edit this bookmark' is displayed with a red outline and black background. The popup's border is red.  |
| `popup_highlight` |  The background color of items highlighted using the keyboard inside popups (such as the selected URL bar dropdown item).    **Note:** It's recommended to define `popup_highlight_text` to override the browser default text color on various platforms.    See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "popup\_highlight": "red",
     "popup\_highlight\_text": "white"
  }
}
```
   screenshot of firefox is black. Browser's tabs and URL bar are lighter grey with icons and text in white. A search results popup is displayed with a highlighted item's background in red. The background color of the highlighted item inside the popup is red.  |
| `popup_highlight_text` | The text color of items highlighted inside popups.   **Note:** Ensure the color used contrasts well with that used in `popup_highlight`.    See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "popup\_highlight": "black",
     "popup\_highlight\_text": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are lighter grey with icons and text in white. A search results popup is displayed with a highlighted item's text in red with a black background. The text color of the highlighted item contrasts well with the black background color of this item.  |
| `popup_text` | The text color of popups.   **Note:** Ensure the color used contrasts well with that used in `popup`.    See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "popup": "black",
     "popup\_text": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are lighter grey with icons and text in white. A search results popup is displayed with items texts in red. The text color contrasts well with the black background color of the popup.  |
| `sidebar` | The background color of the sidebar.  See example 
```
"theme": {
  "colors": {
     "sidebar": "red",
     "sidebar\_highlight": "white",
     "sidebar\_highlight\_text": "green",
     "sidebar\_text": "white"
  }
}
```
   A close-up screenshot of a browser windows's open sidebar. The background color of the sidebar is red.  |
| `sidebar_border` | The border and splitter color of the browser sidebar  See example 
```
"theme": {
  "colors": {
     "sidebar\_border": "red"
  }
}
```
   A closeup of the firefox browser bookmarks sidebar with a red horizontal separator between the sidebar title and the sidebar menu. The border and splitter color of the sidebar is red.  |
| `sidebar_highlight` | The background color of highlighted rows in built-in sidebars  See example 
```
"theme": {
  "colors": {
     "sidebar\_highlight": "red",
     "sidebar\_highlight\_text": "white"
  }
}
```
   A closeup of the firefox browser bookmarks sidebar with a highlighted item. The background color of a highlighted row in the sidebar is red with white text.  |
| `sidebar_highlight_text` | The text color of highlighted rows in sidebars.   **Note:** Ensure the color used contrasts well with that used in `sidebar_highlight`.    See example 
```
"theme": {
  "colors": {
    "sidebar\_highlight": "pink",
    "sidebar\_highlight\_text": "red",
  }
}
```
   A closeup of the firefox browser bookmarks sidebar with a highlighted item. The color of the text of a highlighted row in the sidebar is red. The text color contrasts well with the pink background color of the highlighted row.  |
| `sidebar_text` | The text color of sidebars.   **Note:** Ensure the color used contrasts well with that used in `sidebar`.    See example 
```
"theme": {
  "colors": {
     "sidebar": "red",
     "sidebar\_highlight": "white",
     "sidebar\_highlight\_text": "green",
     "sidebar\_text": "white"
  }
}
```
   A close-up screenshot of a browser windows's open sidebar. The color of the text inside the sidebar is white. The text color contrasts well with the red background of the sidebar.  |
| `tab_background_separator`  Deprecated  |   **Warning:** `tab_background_separator` is not supported starting with Firefox 89.   The color of the vertical separator of the background tabs.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "tab\_background\_separator": "red"
  }
}
```
   A closeup of browser tabs to highlight the separator.  |
| `tab_background_text` |  The color of the text displayed in the inactive page tabs. If `tab_text` or `bookmark_text` isn't specified, applies to the active tab text.    **Note:** Ensure the color used contrasts well with those used in `tab_selected` or `frame` and `frame_inactive`.    See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "white",
    "tab\_background\_text": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tabs and URL bar are white with red icons and red text. The color of the text in the open tab is red. The text color contrasts well with the black background color of the tab.  |
| `tab_line` | The color of the selected tab line.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "tab\_line": "red"
  }
}
```
   Browser firefox is black. Browser's tabs and URL bar are darker grey with lighter grey icons and white text. The selected tab has a red outline.  |
| `tab_loading` | The color of the tab loading indicator and the tab loading burst.  See example 
```
"theme": {
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "tab\_loading": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tabs and URL bar are darker grey with icons and text in white. Inside the selected tab an animated loading indicator is red.  |
| `tab_selected` |  The background color of the selected tab. When not in use selected tab color is set by `frame` and the `frame_inactive`.   See example 
```
"theme": {
  "images": {
  "theme\_frame": "weta.png"
},
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "tab\_selected": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tabs and URL bar are darker grey with icons and text in white. The selected tab has red background and white text.  |
| `tab_text` |  From Firefox 59, it represents the text color for the selected tab. If `tab_line` isn't specified, it also defines the color of the selected tab line.    **Note:** Ensure the color used contrasts well with those used in `tab_selected` or `frame` and `frame_inactive`.    From Firefox 55 to 58, it is incorrectly implemented as alias for `"textcolor"`   See example 
```
"theme": {
  "images": {
  "theme\_frame": "weta.png"
},
  "colors": {
     "frame": "black",
     "tab\_background\_text": "white",
     "tab\_selected": "white",
     "tab\_text": "red"
  }
}
```
   Browser firefox has a picture of an insect theme. URL bar is lighter grey with white icons. The selected tab text is red with white background.  |
| `textcolor`  Deprecated  |   **Warning:** `textcolor` has been removed in Firefox 70. You will begin to get warnings in Firefox 65 and later if you load a theme that uses this property. Use `tab_background_text` instead.   The color of the text displayed in the header area.  See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "white",
    "textcolor": "red"
  }
}
```
   Browser firefox is black. Browser's tab and URL bar are white with red text and red icons.  |
| `toolbar` |  The background color for the navigation bar, the bookmarks bar, and the selected tab.  This also sets the background color of the "Find" bar.  See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "red",
    "tab\_background\_text": "white"
  }
}
```
   Browser firefox is black. Browser's tab, find in page bar and URL bar are red with white text and icons, except for the find in page bar where the text and icon are black.  |
| `toolbar_bottom_separator` |  The color of the line separating the bottom of the toolbar from the region below.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "toolbar\_bottom\_separator": "red"
  }
}
```
   Browser firefox is black. Browser's tab and URL bar are lighter grey with white text and icons. A horizontal red line separates the bottom of the toolbar and the beginning of the display of the web page.  |
| `toolbar_field` | The background color for fields in the toolbar, such as the URL bar.  This also sets the background color of the **Find in page** field.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "red"
  }
}
```
   Browser firefox is black. Browser's tab, find in page bar and URL bar are lighter grey with white text and icons. The background color of the URL bar is red. The find in page bar is white with black text. The find in page field is red with black text.  |
| `toolbar_field_border` | The border color for fields in the toolbar.  This also sets the border color of the **Find in page** field.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "black",
    "toolbar\_field\_text": "white",
    "toolbar\_field\_border": "red"
  }
}
```
   Browser firefox is black. Browser's tab, find in page and URL bar are black with white text and icons. The URL bar and find in page fields are outlined in red.  |
| `toolbar_field_border_focus` | The focused border color for fields in the toolbar.  See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "black",
    "toolbar\_field\_text": "white",
    "toolbar\_field\_border\_focus": "red"
  }
}
```
   Browser firefox is black. Browser's tab and URL bar are black with white text and icons. The url bar field is focused and outlined in red.  |
| `toolbar_field_focus` |  The focused background color for fields in the toolbar, such as the URL bar.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "black",
    "toolbar\_field\_text": "white",
    "toolbar\_field\_focus": "red"
  }
}
```
   Browser firefox is black. Browser's tab, find in page and URL bar are black with white text and icons. The background color of the focused URL bar is red and the text is white.  |
| `toolbar_field_highlight` |  The background color used to indicate the current selection of text in the URL bar (and the search bar, if it's configured to be separate).  See example 
```
"theme": {
  "colors": {
    "toolbar\_field": "rgba(255, 255, 255, 0.91)",
    "toolbar\_field\_text": "rgb(0, 100, 0)",
    "toolbar\_field\_highlight": "rgb(180, 240, 180, 0.9)",
    "toolbar\_field\_highlight\_text": "rgb(0, 80, 0)"
  }
}
```
   Browser firefox is white. Browser's tab and URL bar are white with text and icons in black. The URL bar field is focused and outlined in blue and URL bar text is selected.   Here, the `toolbar_field_highlight` field specifies that the highlight color is a light green, while the text is set to a dark-to-medium green using `toolbar_field_highlight_text`.  |
| `toolbar_field_highlight_text` |  The color used to draw text that's currently selected in the URL bar (and the search bar, if it's configured to be separate box).    **Note:** Ensure the color used contrasts well with those used in `toolbar_field_highlight`.    See example 
```
"theme": {
  "colors": {
    "toolbar\_field": "rgba(255, 255, 255, 0.91)",
    "toolbar\_field\_text": "rgb(0, 100, 0)",
    "toolbar\_field\_highlight": "rgb(180, 240, 180, 0.9)",
    "toolbar\_field\_highlight\_text": "rgb(0, 80, 0)"
  }
}
```
   Browser firefox is white. Browser's tab and URL bar are white with text and icons in black. The URL bar field is focused and outlined in blue and URL bar text is selected.   Here, the `toolbar_field_highlight_text` field is used to set the text color to a dark medium-dark green, while the highlight color is a light green.  |
| `toolbar_field_separator`  Deprecated  |   **Warning:** `toolbar_field_separator` is not supported starting with Firefox 89.    The color of separators inside the URL bar. In Firefox 58 this was implemented as `toolbar_vertical_separator`.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field\_separator": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser firefox is black. Browser's tab and URL bar are black with text and icons in white. Inside the white URL bar field, after the reader mode icon a red vertical line separating the rest of URL bar icons. The color of the vertical separator line inside the URL bar is red.   In this screenshot, `"toolbar_vertical_separator"` is the red vertical line in the URL bar dividing the Reader Mode icon from the other icons.  |
| `toolbar_field_text` |  The color of text in fields in the toolbar, such as the URL bar. This also sets the color of text in the **Find in page** field.    **Note:** Ensure the color used contrasts well with those used in `toolbar_field`.    See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "black",
    "toolbar\_field\_text": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tab and URL bar are black with white text and icons. The text inside the URL bar is red. The icons and find in page field have red text with black background.  |
| `toolbar_field_text_focus` |  The color of text in focused fields in the toolbar, such as the URL bar.    **Note:** Ensure the color used contrasts well with those used in `toolbar_field_focus`.    See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "toolbar": "black",
    "tab\_background\_text": "white",
    "toolbar\_field": "black",
    "toolbar\_field\_text": "white",
    "toolbar\_field\_text\_focus": "red"
  }
}
```
   A screenshot of a browser window with two open tabs. Browser is black. Browser's tab and URL bar are black with text and icons in white. The URL bar has focus; the bar's text and icons are red with black background.  |
| `toolbar_text` |  The color of toolbar text. This also sets the color of text in the "Find" bar.    **Note:** For compatibility with Chrome, use the alias `bookmark_text`.    See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "toolbar": "black",
    "toolbar\_text": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tab, find in page bar, and URL bar are black with red text and icons. The text inside the active tab, the navigator bar and the find bar is red.  |
| `toolbar_top_separator` |  The color of the line separating the top of the toolbar from the region above.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "toolbar": "black",
    "toolbar\_top\_separator": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tab and URL bar are black with white text and icons. A red line separates the top of the URL bar from the browser.  |
| `toolbar_vertical_separator` |  The color of the separator in the bookmarks toolbar. In Firefox 58, it corresponds to the color of separators inside the URL bar.   See example 
```
"theme": {
  "colors": {
    "frame": "black",
    "tab\_background\_text": "white",
    "toolbar": "black",
    "toolbar\_vertical\_separator": "red"
  }
}
```
   A screenshot of a browser window with one open tab. Browser is black. Browser's tab and URL bar are black with text and icons in white. The color of the vertical line separating the bookmarks toolbar from the content to the right is red.  |

 #### Aliases

 Additionally, this key accepts various properties that are aliases for one of the properties above. These are provided for compatibility with Chrome. If an alias is given, and the non-alias version is also given, then the value will be taken from the non-alias version.

  **Warning:** Beginning Firefox 70, the following properties are removed: `accentcolor` and `textcolor`. Use `frame` and `tab_background_text` instead. Using these values in themes loaded into Firefox 65 or later will raise warnings.

  

| Name | Alias for |
| --- | --- |
| `bookmark_text` | `toolbar_text` |
| `frame` | `accentcolor`  Deprecated  |
| `frame_inactive` | `accentcolor`  Deprecated  |
| `tab_background_text` | `textcolor`  Deprecated  |


### properties




| Name | Type | Description |
| --- | --- | --- |
| `additional_backgrounds_alignment` | `Array` of `String` | Optional  An array of enumeration values defining the alignment of the corresponding `"additional_backgrounds":` array item.The alignment options include: * `"bottom"`
* `"center"`
* `"left"`
* `"right"`
* `"top"`
* `"center bottom"`
* `"center center"`
* `"center top"`
* `"left bottom"`
* `"left center"`
* `"left top"`
* `"right bottom"`
* `"right center"`
* `"right top"`.

If not specified, defaults to `"right top"`. |
| `additional_backgrounds_tiling` | `Array` of `String` | Optional  An array of enumeration values defining how the corresponding `"additional_backgrounds":` array item repeats. Options include: * `"no-repeat"`
* `"repeat"`
* `"repeat-x"`
* `"repeat-y"`

If not specified, defaults to `"no-repeat"`. |
| `color_scheme` | `String` | Optional  Determines which color scheme is applied to the chrome (for example, context menus) and content (for example, built-in pages and the preferred color scheme for web pages). Options include: * `"auto"` – a light or dark scheme based automatically on the theme.
* `"light"` – a light scheme.
* `"dark"` – a dark scheme.
* `"system"` – uses the system scheme.

If not specified, defaults to `"auto"`. |
| `content_color_scheme` | `String` | Optional  Determines which color scheme is applied to the content (for example, built-in pages and preferred color scheme for web pages). Overrides `color_scheme`. Options include: * `"auto"` – a light or dark scheme based automatically on the theme.
* `"light"` – a light scheme.
* `"dark"` – a dark scheme.
* `"system"` – the system scheme.

If not specified, defaults to `"auto"`. |

Examples
--------



A basic theme must define an image to add to the header, the accent color to use in the header, and the color of text used in the header:

 
```
 "theme": {
   "images": {
     "theme\_frame": "images/sun.jpg"
   },
   "colors": {
     "frame": "#CF723F",
     "tab\_background\_text": "#000"
   }
 }

```
 Multiple images can be used to fill the header. Before Firefox version 60, use a blank or transparent header image to gain control over the placement of each additional image:

 
```
 "theme": {
   "images": {
     "additional\_backgrounds": [ "images/left.png", "images/middle.png", "images/right.png"]
   },
   "properties": {
     "additional\_backgrounds\_alignment": [ "left top", "top", "right top"]
   },
   "colors": {
     "frame": "blue",
     "tab\_background\_text": "#ffffff"
   }
 }

```
 You can also fill the header with a repeated image, or images, in this case a single image anchored in the middle top of the header and repeated across the rest of the header:

 
```
 "theme": {
   "images": {
     "additional\_backgrounds": [ "images/logo.png"]
   },
   "properties": {
     "additional\_backgrounds\_alignment": [ "top" ],
     "additional\_backgrounds\_tiling": [ "repeat"  ]
   },
   "colors": {
     "frame": "green",
     "tab\_background\_text": "#000"
   }
 }

```
 The following example uses most of the different values for `theme.colors`:

 
```
  "theme": {
    "images": {
      "theme\_frame": "weta.png"
    },

    "colors": {
       "frame": "darkgreen",
       "tab\_background\_text": "white",
       "toolbar": "blue",
       "bookmark\_text": "cyan",
       "toolbar\_field": "orange",
       "toolbar\_field\_border": "white",
       "toolbar\_field\_text": "green",
       "toolbar\_top\_separator": "red",
       "toolbar\_bottom\_separator": "white",
       "toolbar\_vertical\_separator": "white"
    }
  }

```
 It will give you a browser that looks like this:

  ![A browser window with two open tabs and dark green background color in the header area. The inactive tab has a white text color. The active tab and the toolbar have a blue background color with cyan-colored text. The URL bar has an orange background with white borders, a green text color and a white-colored vertical line separator. A red-colored line is used to separate the tabs on the top and a white line to separate the tabs from the content bellow them.] 

 In this screenshot, `"toolbar_vertical_separator"` is the white vertical line in the URL bar dividing the Reader Mode icon from the other icons.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `theme` | Yes | 79 | 55 | ? | No | No | ? | ? | Yes | ? | No | ? |
| `colors` | Yes | 79 | 55 | ? | No | No | ? | ? | 65 | ? | No | ? |
| `images` | Yes | 79 | 55Before Firefox 60, this property was required. | ? | No | No | ? | ? | Yes | ? | No | ? |
| `properties` | Yes | 79 | 55 | ? | No | No | ? | ? | No | ? | No | ? |


### Chrome compatibility



In Chrome:

 * `colors/toolbar_text` is not used, use `colors/bookmark_text` instead.
* `images/theme_frame` anchors the image to the top left of the header and if the image doesn't fill the header area tile the image.
* all colors must be specified as an array of RGB values, like this: 
```
"theme": {
  "colors": {
     "frame": [255, 0, 0],
     "tab\_background\_text": [0, 255, 0],
     "bookmark\_text": [0, 0, 255]
  }
}

```
From Firefox 59 onward, both the array form and the CSS color form are accepted for all properties. Before that, `colors/frame` and `colors/tab_background_text` required the array form, while other properties required the CSS color form.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/theme>

downloads.download()
====================



The `download()` function of the [`downloads`](../downloads) API downloads a file, given its URL and other optional preferences.

 If the URL uses the HTTP or HTTPS protocol, the request includes all the relevant cookies, that is, those cookies set for the URL's hostname, secure flag, path, and so on. The default cookies, the cookies from the normal browsing session, are used unless:

 * the `incognito` option is used, then the private browsing cookies are used.
* the `cookieStoreId` option is used, then the cookies from the specified store are used.

 If both `filename` and `saveAs` are specified, the Save As dialog is displayed, populated with the `filename`.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let downloading = browser.downloads.download(
  options                   // object
)

```
### Parameters


 `options`  An `object` specifying what file you wish to download, and any other preferences you wish to set concerning the download. It can contain the following properties:

  
`allowHttpErrors` Optional
  A `boolean` flag that enables downloads to continue even if they encounter HTTP errors. Using this flag, for example, enables the download of server error pages. Default value `false`. When set to:

 * `false`, the download is canceled when it encounters an HTTP error.
* `true`, the download continues when an HTTP error is encountered and the HTTP server error is not reported. However, if the download fails due to file-related, network-related, user-related, or other error, that error is reported.

  
`body` Optional
  A `string` representing the post body of the request.

  
`conflictAction` Optional
  A string representing the action you want taken if there is a filename conflict, as defined in the [`downloads.FilenameConflictAction`](filenameconflictaction) type (defaults to "uniquify" when it is not specified).

  
`cookieStoreId` Optional
  The cookie store ID of the [contextual identity](../../work_with_contextual_identities) the download is associated with. If omitted, the default cookie store is used. Use requires the "cookies" [API permission](../../manifest.json/permissions#api_permissions).

  
`filename` Optional
  A `string` representing a file path relative to the default downloads directory — this provides the location where you want the file to be saved, and what filename you want to use. Absolute paths, empty paths, path components that start and/or end with a dot (.), and paths containing back-references (`../`) will cause an error. If omitted, this value will default to the filename already given to the download file, and a location immediately inside the downloads directory.

  
`headers` Optional
  If the URL uses the HTTP or HTTPS protocols, an `array` of `objects` representing additional HTTP headers to send with the request. Each header is represented as a dictionary object containing the keys `name` and either `value` or `binaryValue`. The headers that are forbidden by `XMLHttpRequest` and `fetch` cannot be specified, however, Firefox 70 and later enables the use of the `Referer` header. Attempting to use a forbidden header throws an error.

  
`incognito` Optional
  A `boolean`: if present and set to true, then associate this download with a private browsing session. This means that it will only appear in the download manager for any private windows that are currently open.

  
`method` Optional
  A `string` representing the HTTP method to use if the `url` uses the HTTP[S] protocol. This may be either "GET" or "POST".

  
`saveAs` Optional
  A `boolean` that specifies whether to provide a file chooser dialog to allow the user to select a filename (`true`), or not (`false`).

 If this option is omitted, the browser will show the file chooser or not based on the general user preference for this behavior (in Firefox this preference is labeled "Always ask you where to save files" in about:preferences, or `browser.download.useDownloadDir` in about:config).

  **Note:** Firefox for Android raises an error if `saveAs` is set to `true`. The parameter is ignored when `saveAs` is `false` or not included.

   `url`  A `string` representing the URL to download.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the download started successfully, the promise will be fulfilled with the `id` of the new [`downloads.DownloadItem`](downloaditem). Otherwise, the promise will be rejected with an error message taken from [`downloads.InterruptReason`](interruptreason).

 If you use [URL.createObjectURL()](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL) to download data created in JavaScript and you want to revoke the object URL (with [revokeObjectURL](https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL)) later (as it is strongly recommended), you need to do that after the download has been completed. To do so, listen to the [downloads.onChanged](onchanged) event.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `download` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `allowHttpErrors` | No | No | 71 | ? | No | No | ? | ? | No | ? | No | ? |
| `body` | Yes | 79 | 52 | ? | Yes | No | ? | ? | 52–79 | ? | No | ? |
| `conflictAction` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `cookieStoreId` | No | No | 92 | ? | No | No | ? | ? | No | ? | No | ? |
| `filename` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `headers` | Yes | 79 | 47`Referer` headers supported from version 70. | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `incognito` | No | No | 57 | ? | No | No | ? | ? | 57–79 | ? | No | ? |
| `method` | Yes | 79 | 47POST is supported from version 52. | ? | Yes | No | ? | ? | 48–79POST is supported from version 52. | ? | No | ? |
| `saveAs` | Yes | 79 | 52Before version 58, if this option was omitted, Firefox would never show the file chooser, regardless of the value of the browser's preference. | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



The following snippet attempts to download an example file, also specifying a filename and location to save it in, and `uniquify` as the value of the `conflictAction` option.

 
```
function onStartedDownload(id) {
  console.log(`Started downloading: ${id}`);
}

function onFailed(error) {
  console.log(`Download failed: ${error}`);
}

let downloadUrl = "https://example.org/image.png";

let downloading = browser.downloads.download({
  url : downloadUrl,
  filename : 'my-image-again.png',
  conflictAction : 'uniquify'
});

downloading.then(onStartedDownload, onFailed);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-download) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/download>

browserAction
=============



Adds a button to the browser's toolbar.

 A [browser action](../user_interface/browser_action) is a button in the browser's toolbar.

 You can associate a popup with the button. The popup is specified using HTML, CSS and JavaScript, just like a normal web page. JavaScript running in the popup gets access to all the same WebExtension APIs as your background scripts, but its global context is the popup, not the current page displayed in the browser. To affect web pages you need to communicate with them via [messages](../modify_a_web_page#messaging).

 If you specify a popup, it will be shown — and the content will be loaded — when the user clicks the icon. If you do not specify a popup, then when the user clicks the icon an event is dispatched to your extension.

 You can define most of a browser action's properties declaratively using the [`browser_action`](../manifest.json/browser_action) key in the manifest.json.

 With the `browserAction` API, you can:

 * use [`browserAction.onClicked`](browseraction/onclicked) to listen for clicks on the icon.
* get and set the icon's properties — icon, title, popup, and so on. You can get and set these globally across all tabs, or for a specific tab by passing the tab ID as an additional argument.



Types
-----


 [`browserAction.ColorArray`](browseraction/colorarray)  An array of four integers in the range 0-255 defining an RGBA color.

  [`browserAction.ImageDataType`](browseraction/imagedatatype)  Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).

  Functions
---------


 [`browserAction.setTitle()`](browseraction/settitle)  Sets the browser action's title. This will be displayed in a tooltip.

  [`browserAction.getTitle()`](browseraction/gettitle)  Gets the browser action's title.

  [`browserAction.setIcon()`](browseraction/seticon)  Sets the browser action's icon.

  [`browserAction.setPopup()`](browseraction/setpopup)  Sets the HTML document to be opened as a popup when the user clicks on the browser action's icon.

  [`browserAction.getPopup()`](browseraction/getpopup)  Gets the HTML document set as the browser action's popup.

  [`browserAction.openPopup()`](browseraction/openpopup)  Open the browser action's popup.

  [`browserAction.setBadgeText()`](browseraction/setbadgetext)  Sets the browser action's badge text. The badge is displayed on top of the icon.

  [`browserAction.getBadgeText()`](browseraction/getbadgetext)  Gets the browser action's badge text.

  [`browserAction.setBadgeBackgroundColor()`](browseraction/setbadgebackgroundcolor)  Sets the badge's background color.

  [`browserAction.getBadgeBackgroundColor()`](browseraction/getbadgebackgroundcolor)  Gets the badge's background color.

  [`browserAction.setBadgeTextColor()`](browseraction/setbadgetextcolor)  Sets the badge's text color.

  [`browserAction.getBadgeTextColor()`](browseraction/getbadgetextcolor)  Gets the badge's text color.

  [`browserAction.enable()`](browseraction/enable)  Enables the browser action for a tab. By default, browser actions are enabled for all tabs.

  [`browserAction.disable()`](browseraction/disable)  Disables the browser action for a tab, meaning that it cannot be clicked when that tab is active.

  [`browserAction.isEnabled()`](browseraction/isenabled)  Checks whether the browser action is enabled or not.

  Events
------


 [`browserAction.onClicked`](browseraction/onclicked)  Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ColorArray` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `ImageDataType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `disable` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `enable` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `getBadgeBackgroundColor` | Yes | 14 | 45 | ? | Yes | 14Always returns a red `ColorArray`. | ? | ? | 79 | ? | 15Always returns a red `ColorArray`. | ? |
| `getBadgeText` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `getBadgeTextColor` | No | No | 63 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `getPopup` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 57 | ? | 15 | ? |
| `getTitle` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 55 | ? | 15The API exists, but the title not visible in the UI. | ? |
| `isEnabled` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `onClicked` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `openPopup` | 67 | 79 | 57["Since Firefox 108, user interaction is no longer required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)).", "Support for the `windowId` parameter was added in Firefox 108."] | ? | 54 | 16 | ? | ? | 79 | ? | 16 | ? |
| `setBadgeBackgroundColor` | Yes | 14 | 4545–58Tab-specific badge background color is not cleared when a new page is loaded. | ? | Yes | 14The API exists, but has no effect. | ? | ? | 79 | ? | 15The API exists, but has no effect. | ? |
| `setBadgeText` | Yes | 14 | 4545–58Tab-specific badge text is not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `setBadgeTextColor` | No | No | 63 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `setIcon` | YesBefore Chrome 23, `path` couldn't specify multiple icon files, but had to be a string specifying a single icon path. | 14["This call is not persisted.", "The `imageData` parameter is not accepted.", "The `path` parameter is required."] | 4545–58Tab-specific icons are not cleared when a new page is loaded. | ? | 15 | 14 | ? | ? | 79 | ? | 15 | ? |
| `setPopup` | Yes | 14 | 4545–58Tab-specific popups are not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 5757–58Tab-specific popups are not cleared when a new page is loaded. | ? | 15 | ? |
| `setTitle` | Yes | 15 | 4545–58Tab-specific titles are not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 5555–58Tab-specific titles are not cleared when a new page is loaded. | ? | 15The API exists, but the title not visible in the UI. | ? |


Example extensions
------------------



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)
* [native-messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging)
* [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)
* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)

  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction>

storage
=======



Enables extensions to store and retrieve data, and listen for changes to stored items.

 The storage system is based on the [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API), with a few differences. Among other differences, these include:

 * It's asynchronous.
* Values are scoped to the extension, not to a specific domain (i.e. the same set of key/value pairs are available to all scripts in the background context and content scripts).
* The values stored can be any JSON-ifiable value, not just [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). Among other things, this includes: [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) and [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), but only when their contents can be represented as JSON, which does not include DOM nodes. You don't need to convert your values to JSON `Strings` prior to storing them, but they are represented as JSON internally, thus the requirement that they be JSON-ifiable.
* Multiple key/value pairs can be set or retrieved in the same API call.

 To use this API you need to include the `"storage"` [permission](../manifest.json/permissions) in your [`manifest.json`](../manifest.json) file.

 Each extension has its own storage area, which can be split into different types of storage.

 Although this API is similar to [`Window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) it is recommended that you don't use `Window.localStorage` in the extension code to store extension-related data. Firefox will clear data stored by extensions using the localStorage API in various scenarios where users clear their browsing history and data for privacy reasons, while data saved using the [`storage.local`](storage/local) API will be correctly persisted in these scenarios.

 You can examine the stored data under the Extension Storage item in the [Storage Inspector](https://firefox-source-docs.mozilla.org/devtools-user/storage_inspector/index.html) tab of the [developer toolbox](https://extensionworkshop.com/documentation/develop/debugging/), accessible from `about:debugging`.

  **Note:** The storage area is not encrypted and shouldn't be used for storing confidential user information.

 

Types
-----


 [`storage.StorageArea`](storage/storagearea)  An object representing a storage area.

  [`storage.StorageChange`](storage/storagechange)  An object representing a change to a storage area.

  Properties
----------



`storage` has four properties, which represent the different types of available storage area.

  [`storage.local`](storage/local)  Represents the `local` storage area. Items in `local` storage are local to the machine the extension was installed on.

  [`storage.managed`](storage/managed)  Represents the `managed` storage area. Items in `managed` storage are set by the domain administrator and are read-only for the extension. Trying to modify this namespace results in an error.

  [`storage.session`](storage/session)  Represents the `session` storage area. Items in `session` storage are stored in memory and are not persisted to disk.

  [`storage.sync`](storage/sync)  Represents the `sync` storage area. Items in `sync` storage are synced by the browser, and are available across all instances of that browser that the user is logged into, across different devices.

  
Events
------


 [`storage.onChanged`](storage/onchanged)  Fired when one or more items change in any of the storage areas.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `StorageArea` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `StorageChange` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `local` | Yes | 14 | 45The storage API is supported in content scripts from version 48. | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `managed` | Yes | 79 | 57["Platform-specific storage backends, such as Windows registry keys, are not supported.", "Enforcement of extension-provided storage schemas is not supported.", "The `onChanged` event is not supported."] | ? | No | No | ? | ? | No | ? | No | ? |
| `onChanged` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `session` | 102Before version 112, storage quota limits were 1MB. | 102Before version 112, storage quota limits were 1MB. | No | ? | 88Before version 98, storage quota limits were 1MB. | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `sync` | Yes | 15 | 53Before version 79, storage quota limits are not enforced. | ? | No | 14["Safari does not sync items saved in the `sync` storage area, i.e. it behaves the same as the `local` storage area.", "Safari 15 and 15.1 erroneously store sync items in the `local` storage area. If unable to locate sync items, check for sync items in the `local` storage area and do a one-time migration to the `sync` storage area."] | ? | ? | No | ? | 15["Safari does not sync items saved in the `sync` storage area, i.e. it behaves the same as the `local` storage area.", "Safari 15 and 15.1 erroneously store sync items in the `local` storage area. If unable to locate sync items, check for sync items in the `local` storage area and do a one-time migration to the `sync` storage area."] | ? |


Example extensions
------------------



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats)
* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)
* [quicknote](https://github.com/mdn/webextensions-examples/tree/master/quicknote)
* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)

  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage>

runtime.Port
============



A `Port` object represents one end of a connection between two specific contexts, which can be used to exchange messages.

 One side initiates the connection, using a `connect()` API. This returns a `Port` object. The other side listens for connection attempts using an `onConnect` listener. This is passed a corresponding `Port` object.

 Once both sides have `Port` objects, they can exchange messages using `Port.postMessage()` and `Port.onMessage`. When they are finished, either end can disconnect using `Port.disconnect()`, which will generate a `Port.onDisconnect` event at the other end, enabling the other end to do any cleanup required.

 A `Port` can also become disconnected in response to various events. See [Lifecycle](#lifecycle).

 You can use this pattern to communicate between:

 * different parts of your extension (for example, between [content scripts](../../content_scripts) and [background scripts](../../anatomy_of_a_webextension#background_scripts))
* between your extension and a [native application running on the user's computer](../../native_messaging).
* between your extension and a different extension

 You need to use different connection APIs for different sorts of connections, as detailed in the table below.

 

| Connection type | Initiate connection attempt | Handle connection attempt |
| --- | --- | --- |
| Background script to content script | [`tabs.connect()`](../tabs/connect) | [`runtime.onConnect`](onconnect) |
| Content script to background script | [`runtime.connect()`](connect) | [`runtime.onConnect`](onconnect) |
| Extension to native application | [`runtime.connectNative()`](connectnative) |  Not applicable (see [Native messaging](../../native_messaging)).  |
| Extension to Extension | [`runtime.connect()`](connect) | [`runtime.onConnectExternal`](onconnectexternal) |



Type
----



Values of this type are objects. They contain the following properties:

  `name`  `string`. The port's name, defined in the [`runtime.connect()`](connect) or [`tabs.connect()`](../tabs/connect) call that created it. If this port is connected to a native application, its name is the name of the native application.

  `disconnect`  `function`. Disconnects a port. Either end can call this when they have finished with the port. It will cause `onDisconnect` to be fired at the other end. This is useful if the other end is maintaining some state relating to this port, which can be cleaned up on disconnect. If this port is connected to a native application, this function will close the native application.

  `error`  `object`. If the port was disconnected due to an error, this will be set to an object with a string property `message`, giving you more information about the error. See `onDisconnect`.

  `onDisconnect`  `object`. This contains the `addListener()` and `removeListener()` functions common to all events for extensions built using WebExtension APIs. Listener functions will be called when the other end has called `Port.disconnect()`. This event will only be fired once for each port. The listener function will be passed the `Port` object. If the port was disconnected due to an error, then the `Port` argument will contain an `error` property giving more information about the error:

 
```
port.onDisconnect.addListener((p) => {
  if (p.error) {
    console.log(`Disconnected due to an error: ${p.error.message}`);
  }
});

```
 Note that in Google Chrome `port.error` is not supported: instead, use [`runtime.lastError`](lasterror) to get the error message.

  `onMessage`  `object`. This contains the `addListener()` and `removeListener()` functions common to all events for extensions built using WebExtension APIs. Listener functions will be called when the other end has sent this port a message. The listener will be passed the value that the other end sent.

  `postMessage`  `function`. Send a message to the other end. This takes one argument, which is a serializable value (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)) representing the message to send. It will be delivered to any script listening to the port's `onMessage` event, or to the native application if this port is connected to a native application.

  
`sender` Optional
  [`runtime.MessageSender`](messagesender). Contains information about the sender of the message. This property will only be present on ports passed to `onConnect`/`onConnectExternal` listeners.

  
Lifecycle
---------



The lifecycle of a `Port` is described [in the Chrome docs](https://developer.chrome.com/docs/extensions/mv3/messaging/#port-lifetime).

 There is, however, one important difference between Firefox and Chrome, stemming from the fact that the `runtime.connect` and `tabs.connect` APIs are broadcast channels. This means that there may be potentially more than one recipient, and this results in ambiguity when one of the contexts with a `runtime.onConnect` call is closed. In Chrome, a port stays active as long as there is any other recipient. In Firefox, the port closes when any of the contexts unloads. In other words, the disconnection condition,

 * All frames that received the port (via `runtime.onConnect`) have unloaded.

 which holds in Chrome, is replaced by

 * *Any* frame that received the port (via `runtime.onConnect`) has unloaded.

 in Firefox (see [bug 1465514](https://bugzil.la/1465514)).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Port` | 26 | 15 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `error` | No | No | 52 | ? | No | No | ? | ? | 52 | ? | No | ? |


Examples
--------


### Connecting from content scripts



This content script:

 * connects to the background script and stores the `Port` in a variable called `myPort`.
* listens for messages on `myPort` and logs them.
* sends messages to the background script, using `myPort`, when the user clicks the document.

 
```
// content-script.js

let myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({greeting: "they clicked the page!"});
});

```
 The corresponding background script:

 * listens for connection attempts from the content script.
* when it receives a connection attempt:
	+ stores the port in a variable named `portFromCS`.
	+ sends the content script a message using the port.
	+ starts listening to messages received on the port, and logs them.
* sends messages to the content script, using `portFromCS`, when the user clicks the extension's browser action.

 
```
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({greeting: "hi there content script!"});
  portFromCS.onMessage.addListener((m) => {
    console.log("In background script, received message from content script")
    console.log(m.greeting);
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({greeting: "they clicked the button!"});
});

```
 #### Multiple content scripts

 If you have multiple content scripts communicating at the same time, you might want to store each connection in an array.

 
```
// background-script.js

let ports = []

function connected(p) {
  ports[p.sender.tab.id]    = p
  // …
}

browser.runtime.onConnect.addListener(connected)

browser.browserAction.onClicked.addListener(() => {
  ports.forEach((p) => {
        p.postMessage({greeting: "they clicked the button!"})
    })
});

```

### Connecting to native applications



This example connects to the native application "ping\_pong" and starts listening for messages from it. It also sends the native application a message when the user clicks a browser action icon:

 
```
/\*
On startup, connect to the "ping\_pong" app.
\*/
let port = browser.runtime.connectNative("ping\_pong");

/\*
Listen for messages from the app.
\*/
port.onMessage.addListener((response) => {
  console.log(`Received: ${response}`);
});

/\*
On a click on the browser action, send the app a message.
\*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending: ping");
  port.postMessage("ping");
});

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-Port) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port>

tabs.connect()
==============



Call this function to set up a connection between the extension's background scripts (or other privileged scripts, such as popup scripts or options page scripts) and any [content scripts](../../content_scripts) that belong to this extension and are running in the specified tab. This function returns a [`runtime.Port`](../runtime/port) object.

 When this is called, the [`runtime.onConnect`](../runtime/onconnect) event will be fired in any content script belonging to this extension that are running in the specified tab. The event listener will be passed another [`runtime.Port`](../runtime/port) object. The two sides can then use the `Port` objects to exchange messages.

 For more details, see [connection-based messaging](../../content_scripts#connection-based_messaging). You can message without creating a connection, for advice on choosing between the options, see [Choosing between one-off messages and connection-based messaging](../../content_scripts#choosing_between_one-off_messages_and_connection-based_messaging).



Syntax
------



```
browser.tabs.connect(
  tabId,      // integer
  connectInfo // optional object
)

```
### Parameters


 `tabId`  `integer`. ID of the tab whose content scripts we want to connect to.

  
`connectInfo` Optional
  An object with the following properties:

  
`name` Optional
  `string`. Will be passed into [`runtime.onConnect`](../runtime/onconnect) event listeners in content scripts belonging to this extension and running in the specified tab.

  
`frameId` Optional
  `integer`. Open a port to a specific frame identified by `frameId` instead of all frames in the tab.

    ### Return value


[`runtime.Port`](../runtime/port). A port that can be used to communicate with the content scripts running in the specified tab.

Examples
--------



In this example a background script listens for a click on a [browser action](../../anatomy_of_a_webextension#browser_actions_2), then connects to the currently active tab, then sends a message using the `Port` that's returned from `connect()`:

 
```
function connectToTab(tabs) {
  if (tabs.length > 0) {
    let examplePort = browser.tabs.connect(
      tabs[0].id,
      {name: "tabs-connect-example"}
    );
    examplePort.postMessage({greeting: "Hi from background script"});
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingActive = browser.tabs.query({
    currentWindow: true, active: true
  });
  gettingActive.then(connectToTab, onError);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `connect` | 5 | 79 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-connect) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/connect>

tabs.executeScript()
====================



Injects JavaScript code into a page.

  **Note:** When using Manifest V3 or higher, use [`scripting.executeScript()`](../scripting/executescript) to execute scripts.

  You can inject code into pages whose URL can be expressed using a [match pattern](../../match_patterns). To do so, its scheme must be one of: `http`, `https`, or `file`.

 You must have the permission for the page's URL—either explicitly, as a [host permission](../../manifest.json/permissions#host_permissions)—or, via the [activeTab permission](../../manifest.json/permissions#activetab_permission). Note that some special pages do not allow this permission, including reader view, view-source, and PDF viewer pages.

 You can also inject code into pages packaged with your own extension:

 
```
browser.tabs.create({url: "/my-page.html"}).then(() => {
  browser.tabs.executeScript({
    code: `console.log('location:', window.location.href);`
  });
});

```
 You don't need any special permissions to do this.

 You *cannot* inject code into any of the browser's built-in pages, such as: `about:debugging`, `about:addons`, or the page that opens when you open a new empty tab.

 The scripts you inject are called [content scripts](../../content_scripts).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let executing = browser.tabs.executeScript(
  tabId,                 // optional integer
  details                // object
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab in which to run the script.

 Defaults to the active tab of the current window.

  `details`  An object describing the script to run.

 It contains the following properties:

  
`allFrames` Optional
  `boolean`. If `true`, the code will be injected into all frames of the current page.

 If `true` and `frameId` is set, then it will raise an error. (`frameId` and `allFrames` are mutually exclusive.)

 If it is `false`, code is only injected into the top frame.

 Defaults to `false`.

  
`code` Optional
  `string`. Code to inject, as a text string.

  **Warning:** Don't use this property to interpolate untrusted data into JavaScript, as this could lead to a security issue.

   
`file` Optional
  `string`. Path to a file containing the code to inject.

 * In Firefox, relative URLs not starting at the extension root are resolved relative to the current page URL.
* In Chrome, these URLs are resolved relative to the extension's base URL.

 To work cross-browser, you can specify the path as a relative URL, starting at the extension's root, like this: `"/path/to/script.js"`.

  
`frameId` Optional
  `integer`. The frame where the code should be injected.

 Defaults to `0` (the top-level frame).

  
`matchAboutBlank` Optional
  `boolean`. If `true`, the code will be injected into embedded `about:blank` and `about:srcdoc` frames if your extension has access to their parent document. The code cannot be inserted in top-level `about:` frames.

 Defaults to `false`.

  
`runAt` Optional
  [`extensionTypes.RunAt`](../extensiontypes/runat). The soonest that the code will be injected into the tab.

 Defaults to `"document_idle"`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will resolve to an array of objects. The array's values represent the result of the script in every injected frame.

 The result of the script is the last evaluated statement, which is similar to what would be output (the results, not any `console.log()` output) if you executed the script in the [Web Console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html). For example, consider a script like this:

 
```
let foo='my result'; foo;

```
 Here the results array will contain the string "`my result`" as an element.

 The result values must be [structured cloneable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)).

  **Note:** The last statement may be also a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), but this feature is unsupported by [webextension-polyfill](https://github.com/mozilla/webextension-polyfill#tabsexecutescript) library.

  If any error occurs, the promise will be rejected with an error message.


Examples
--------



This example executes a one-line code snippet in the currently active tab:

 
```
function onExecuted(result) {
  console.log(`We made it green`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

const makeItGreen = 'document.body.style.border = "5px solid green"';

const executing = browser.tabs.executeScript({
  code: makeItGreen
});
executing.then(onExecuted, onError);

```
 This example executes a script from a file (packaged with the extension) called `"content-script.js"`. The script is executed in the currently active tab. The script is executed in subframes as well as the main document:

 
```
function onExecuted(result) {
  console.log(`We executed in all subframes`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

const executing = browser.tabs.executeScript({
  file: "/content-script.js",
  allFrames: true
});
executing.then(onExecuted, onError);

```
 This example executes a script from a file (packaged with the extension) called `"content-script.js"`. The script is executed in the tab with an ID of `2`:

 
```
function onExecuted(result) {
  console.log(`We executed in tab 2`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

const executing = browser.tabs.executeScript(
  2, {
    file: "/content-script.js"
});
executing.then(onExecuted, onError);

```

### Example extensions


* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [context-menu-copy-link-with-types](https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types)
* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `executeScript` | 5["Extensions can't inject scripts into their own pages using this API.", "Available for use in Manifest V2 only."] | 14Available for use in Manifest V2 only. | 43["Before version 50, Firefox would pass a single result value into its callback rather than an array, unless 'allFrames' had been set.", "Available for use in Manifest V2 only."] | ? | 15["Extensions can't inject scripts into their own pages using this API.", "Available for use in Manifest V2 only."] | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |
| `frameId` | 39 | 79 | 43'allFrames' and 'frameId' can't both be set at the same time. | ? | 26 | 14 | ? | ? | 54'allFrames' and 'frameId' can't both be set at the same time. | ? | 15 | ? |
| `matchAboutBlank` | 39 | 14 | 53 | ? | 26 | No | ? | ? | 54 | ? | No | ? |
| `runAt` | 20 | 79 | 43 | ? | 15 | No | ? | ? | 54 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-executeScript) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript>

Modify a web page
=================



One of the most common use cases for an extension is to modify a web page. For example, an extension might want to change the style applied to a page, hide particular DOM nodes, or inject extra DOM nodes into the page.

 There are two ways to do this with WebExtensions APIs:

 * **Declaratively**: Define a pattern that matches a set of URLs, and load a set of scripts into pages whose URL matches that pattern.
* **Programmatically**: Using a JavaScript API, load a script into the page hosted by a particular tab.

 Either way, these scripts are called *content scripts*, and are different from the other scripts that make up an extension:

 * They only get access to a small subset of the WebExtension APIs.
* They get direct access to the web page in which they are loaded.
* They communicate with the rest of the extension using a messaging API.

 In this article we'll look at both methods of loading a script.



Modifying pages that match a URL pattern
----------------------------------------



First of all, create a new directory called "modify-page". In that directory, create a file called "manifest.json", with the following contents:

 
```
{

  "manifest\_version": 2,
  "name": "modify-page",
  "version": "1.0",

  "content\_scripts": [
    {
      "matches": ["https://developer.mozilla.org/\*"],
      "js": ["page-eater.js"]
    }
  ]

}

```
 The [`content_scripts`](manifest.json/content_scripts) key is how you load scripts into pages that match URL patterns. In this case, `content_scripts` instructs the browser to load a script called "page-eater.js" into all pages under <https://developer.mozilla.org/>.

  **Note:** Since the `"js"` property of `content_scripts` is an array, you can use it to inject more than one script into matching pages. If you do this the pages share the same scope, just like multiple scripts loaded by a page, and they are loaded in the order that they are listed in the array.

   **Note:** The `content_scripts` key also has a `"css"` property that you can use to inject CSS stylesheets.

  Next, create a file called "page-eater.js" inside the "modify-page" directory, and give it the following contents:

 
```
document.body.textContent = "";

let header = document.createElement('h1');
header.textContent = "This page has been eaten";
document.body.appendChild(header);

```
 Now [install the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/), and visit <https://developer.mozilla.org/>. The page should look like this:

  ![developer.mozilla.org page "eaten" by the script] 


Modifying pages programmatically
--------------------------------



What if you still want to eat pages, but only when the user asks you to? Let's update this example so we inject the content script when the user clicks a context menu item.

 First, update "manifest.json" so it has the following contents:

 
```
{

  "manifest\_version": 2,
  "name": "modify-page",
  "version": "1.0",

  "permissions": [
    "activeTab",
    "contextMenus"
  ],

  "background": {
    "scripts": ["background.js"]
  }

}

```
 Here, we've removed the `content_scripts` key, and added two new keys:

 * [`permissions`](manifest.json/permissions): To inject scripts into pages we need permissions for the page we're modifying. The [`activeTab` permission](manifest.json/permissions#activetab_permission) is a way to get this temporarily for the currently active tab. We also need the `contextMenus` permission to be able to add context menu items.
* [`background`](manifest.json/background): We're using this to load a persistent ["background script"](anatomy_of_a_webextension#background_scripts) called `background.js`, in which we'll set up the context menu and inject the content script.

 Let's create this file. Create a new file called `background.js` in the `modify-page` directory, and give it the following contents:

 
```
browser.contextMenus.create({
  id: "eat-page",
  title: "Eat this page"
});

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "eat-page") {
    browser.tabs.executeScript({
      file: "page-eater.js"
    });
  }
});

```
 In this script we're creating a [context menu item](api/menus/create), giving it a specific id and title (the text to be displayed in the context menu). Then we set up an event listener so that when the user clicks a context menu item, we check to see if it is our `eat-page` item. If it is, we inject "page-eater.js" into the current tab using the [`tabs.executeScript()`](api/tabs/executescript) API. This API optionally takes a tab ID as an argument: we've omitted the tab ID, which means that the script is injected into the currently active tab.

 At this point the extension should look like this:

 
```
modify-page/
    background.js
    manifest.json
    page-eater.js

```
 Now [reload the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/#reloading_a_temporary_add-on), open a page (any page, this time) activate the context menu, and select "Eat this page":

  ![Option to eat a page on the context menu](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page/eat_from_menu.png) 


Messaging
---------



Content scripts and background scripts can't directly access each other's state. However, they can communicate by sending messages. One end sets up a message listener, and the other end can then send it a message. The following table summarizes the APIs involved on each side:

 

|  | In content script | In background script |
| --- | --- | --- |
| Send a message | `[browser.runtime.sendMessage()](api/runtime#sendmessage())` | `[browser.tabs.sendMessage()](api/tabs/sendmessage)` |
| Receive a message | `[browser.runtime.onMessage](api/runtime/onmessage)` | `[browser.runtime.onMessage](api/runtime#onmessage)` |

  **Note:** In addition to this method of communication, which sends one-off messages, you can also use a [connection-based approach to exchange messages](content_scripts#connection-based_messaging). For advice on choosing between the options, see [Choosing between one-off messages and connection-based messaging](content_scripts#choosing_between_one-off_messages_and_connection-based_messaging).

  Let's update our example to show how to send a message from the background script.

 First, edit `background.js` so that it has these contents:

 
```
browser.contextMenus.create({
  id: "eat-page",
  title: "Eat this page"
});

function messageTab(tabs) {
  browser.tabs.sendMessage(tabs[0].id, {
    replacement: "Message from the extension!"
  });
}

function onExecuted(result) {
    let querying = browser.tabs.query({
        active: true,
        currentWindow: true
    });
    querying.then(messageTab);
}

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "eat-page") {
    let executing = browser.tabs.executeScript({
      file: "page-eater.js"
    });
    executing.then(onExecuted);
  }
});

```
 Now, after injecting `page-eater.js`, we use [`tabs.query()`](api/tabs/query) to get the currently active tab, and then use [`tabs.sendMessage()`](api/tabs/sendmessage) to send a message to the content scripts loaded into that tab. The message has the payload `{replacement: "Message from the extension!"}`.

 Next, update `page-eater.js` like this:

 
```
function eatPageReceiver(request, sender, sendResponse) {
  document.body.textContent = "";
  let header = document.createElement('h1');
  header.textContent = request.replacement;
  document.body.appendChild(header);
}
browser.runtime.onMessage.addListener(eatPageReceiver);

```
 Now, instead of just eating the page right away, the content script listens for a message using [`runtime.onMessage`](api/runtime/onmessage). When a message arrives, the content script runs essentially the same code as before, except that the replacement text is taken from `request.replacement`.

 Since [`tabs.executeScript()`](api/tabs/executescript) is an asynchronous function, and to ensure we send message only after listener has been added in `page-eater.js`, we use `onExecuted()` which will be called after `page-eater.js` executed.

  **Note:** Press `Ctrl`+`Shift`+`J` (or `Cmd`+`Shift`+`J` on macOS) OR `web-ext run --bc` to open [Browser Console](https://firefox-source-docs.mozilla.org/devtools-user/browser_console/index.html) to view `console.log` in background script.

 Alternatively, use [Add-on Debugger](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Add-on_Debugger) which allows you set breakpoint. There is currently no way to [start Add-on Debugger directly from web-ext](https://github.com/mozilla/web-ext/issues/759).

  If we want send messages back from the content script to the background page, we would use [`runtime.sendMessage()`](api/runtime/sendmessage) instead of [`tabs.sendMessage()`](api/tabs/sendmessage), e.g.:

 
```
browser.runtime.sendMessage({
    title: "from page-eater.js"
});

```
  **Note:** These examples all inject JavaScript; you can also inject CSS programmatically using the [`tabs.insertCSS()`](api/tabs/insertcss) function.

 
Learn more
----------


* [Content scripts](content_scripts) guide
* [`content_scripts`](manifest.json/content_scripts) manifest key
* [`permissions`](manifest.json/permissions) manifest key
* [`tabs.executeScript()`](api/tabs/executescript)
* [`tabs.insertCSS()`](api/tabs/insertcss)
* [`tabs.sendMessage()`](api/tabs/sendmessage)
* [`runtime.sendMessage()`](api/runtime/sendmessage)
* [`runtime.onMessage`](api/runtime/onmessage)
* Examples using `content_scripts`:
	+ [borderify](https://github.com/mdn/webextensions-examples/tree/master/borderify)
	+ [emoji-substitution](https://github.com/mdn/webextensions-examples/tree/master/emoji-substitution)
	+ [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
	+ [page-to-extension-messaging](https://github.com/mdn/webextensions-examples/tree/master/page-to-extension-messaging)
* Examples using `tabs.executeScript()`:
	+ [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
	+ [context-menu-copy-link-with-types](https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page>

tabs.getCurrent()
=================



Get a [`tabs.Tab`](tab) containing information about the tab that this script is running in.

  **Note:** This function is only useful in contexts where there is a browser tab, such as an [options page](../../anatomy_of_a_webextension#options_pages).

 If you call it from a background script or a popup, it will return `undefined`.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
const gettingCurrent = browser.tabs.getCurrent()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing information about the current tab. If any error occurs the promise will be rejected with an error message.

Examples
--------



Get information about the current tab:

 
```
function onGot(tabInfo) {
  console.log(tabInfo);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

const gettingCurrent = browser.tabs.getCurrent();
gettingCurrent.then(onGot, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getCurrent` | 6 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getCurrent) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getCurrent>

tabs.get()
==========



Given a tab ID, get the tab's details as a [`tabs.Tab`](tab) object.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.tabs.get(
  tabId              // integer
)

```
### Parameters


 `tabId`  `integer`. ID of the tab to get.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing information about the tab. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Examples
--------



Get information about a tab when it is activated:

 
```
async function logListener(info) {
  try {
    let tabInfo = await browser.tabs.get(info.tabId);
    console.log(tabInfo);
  } catch (error) {
    console.error(error);
  }
}

browser.tabs.onActivated.addListener(logListener);

```

### Example extensions


* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-get) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/get>

tabs.duplicate()
================



Duplicates a tab, given its ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let duplicating = browser.tabs.duplicate(
  tabId,              // integer
  duplicateProperties // optional object
)

```
### Parameters


 `tabId`  `integer`. The ID of the tab to be duplicated.

  
`duplicateProperties` Optional  `object`. An object describing how the tab is duplicated. It contains the following properties:

  
`index` Optional  `integer`. The position of the new tab in the window. The value is constrained to the range zero to the number of tabs in the window.

  
`active` Optional  `boolean`. Whether the tab becomes the active tab in the window. Does not affect whether the window is focused. Defaults to `true`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing details about the duplicated tab. The `Tab` object only contains `url`, `title` and `favIconUrl` if the extension has the [`"tabs"` permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions). If any error occurs the promise will be rejected with an error message.

  **Note:** Beginning with Firefox 68, the promise returned by browser.tabs.duplicate() resolves as soon as the tab has been duplicated. Previously, the promise only resolved once the tab had fully been loaded.

 
Examples
--------



Duplicate the first tab, and then log the ID of the newly created tab:

 
```
function onDuplicated(tabInfo) {
  console.log(tabInfo.id);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

// Duplicate the first tab in the array
function duplicateFirstTab(tabs) {
  console.log(tabs);
  if (tabs.length > 0) {
    let duplicating = browser.tabs.duplicate(tabs[0].id);
    duplicating.then(onDuplicated, onError);
  }
}

// Query for all open tabs
let querying = browser.tabs.query({});
querying.then(duplicateFirstTab, onError);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `duplicate` | 23 | 79 | 47 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `duplicateProperties` | No | No | 77 | ? | No | No | ? | ? | No | ? | No | ? |
| `tabId` | 23 | 79 | 47 | ? | 15 | Yes | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-duplicate) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/duplicate>

tabs.sendMessage()
==================



Sends a single message from the extension's background scripts (or other privileged scripts, such as popup scripts or options page scripts) to any [content scripts](../../content_scripts) or extension pages/iframes that belong to the extension and are running in the specified tab.

 The message will be received in the extension context by any listeners to the [`runtime.onMessage`](../runtime/onmessage) event. Listeners may then optionally return something as a response back to the sender.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** You can also use a [connection-based approach to exchange messages](../../content_scripts#connection-based_messaging).

 

Syntax
------



```
const sending = browser.tabs.sendMessage(
  tabId,     // integer
  message,   // any
  options    // optional object
)

```
### Parameters


 `tabId`  `integer`. ID of the tab whose content scripts we want to send a message to.

  `message`  `any`. An object that can be serialized (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)).

  
`options` Optional
  `object`.

  
`frameId` Optional
  `integer`. Sends the message to a specific frame identified by `frameId` instead of all frames in the tab. Whether the content script is executed in all frames depends on the `all_frames` setting in the [`content_scripts`](../../manifest.json/content_scripts) section of `manifest.json`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the response object sent by the handler of the message in the content script, or with no arguments if the content script did not send a response.

 If an error occurs while connecting to the specified tab or any other error occurs, the promise will be rejected with an error message.

 If several frames respond to the message, the promise is resolved to one of answers.


Examples
--------



Here's an example of a background script that sends a message to the content scripts running in the active tab when the user clicks the browser action. The background script also expects the content script to send a response:

 
```
// background-script.js
"use strict";

function onError(error) {
  console.error(`Error: ${error}`);
}

function sendMessageToTabs(tabs) {
  for (const tab of tabs) {
    browser.tabs
      .sendMessage(tab.id, { greeting: "Hi from background script" })
      .then((response) => {
        console.log("Message from the content script:");
        console.log(response.response);
      })
      .catch(onError);
  }
}

browser.browserAction.onClicked.addListener(() => {
  browser.tabs
    .query({
      currentWindow: true,
      active: true,
    })
    .then(sendMessageToTabs)
    .catch(onError);
});

```
 Here's the corresponding content script:

 
```
// content-script.js
"use strict";

browser.runtime.onMessage.addListener((request) => {
  console.log("Message from the background script:");
  console.log(request.greeting);
  return Promise.resolve({ response: "Hi from content script" });
});

```

### Example extensions


* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sendMessage` | Yes | 14No response is sent after the receiving tab is refreshed if there is no `runtime.onMessage` listener. | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-sendMessage) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage>

tabs.insertCSS()
================



Injects CSS into a page.

  **Note:** When using Manifest V3 or higher, use [`scripting.insertCSS()`](../scripting/insertcss) and [`scripting.removeCSS()`](../scripting/removecss) to insert and remove CSS.

  To use this API you must have the permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions), or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 You can only inject CSS into pages whose URL can be expressed using a [match pattern](../../match_patterns): meaning, its scheme must be one of "http", "https", or "file". This means that you can't inject CSS into any of the browser's built-in pages, such as about:debugging, about:addons, or the page that opens when you open a new empty tab.

  **Note:** Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.

  The inserted CSS may be removed again by calling [`tabs.removeCSS()`](removecss).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) (on Firefox only).



Syntax
------



```
let inserting = browser.tabs.insertCSS(
  tabId,           // optional integer
  details          // object
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab in which to insert the CSS. Defaults to the active tab of the current window.

  `details`  An object describing the CSS to insert. It contains the following properties:

  
`allFrames` Optional
  `boolean`. If `true`, the CSS will be injected into all frames of the current page. If it is `false`, CSS is only injected into the top frame. Defaults to `false`.

  
`code` Optional
  `string`. Code to inject, as a text string.

  
`cssOrigin` Optional
  `string`. This can take one of two values: "user", to add the CSS as a user stylesheet or "author" to add it as an author stylesheet. If this option is omitted, the CSS is added as an author stylesheet.

 * "user" enables you to prevent websites from overriding the CSS you insert: see [Cascading order](https://developer.mozilla.org/en-US/docs/Web/CSS/Cascade#cascading_order).
* "author" stylesheets behave as if they appear after all author rules specified by the web page. This behavior includes any author stylesheets added dynamically by the page's scripts, even if that addition happens after the `insertCSS` call completes.

  
`file` Optional
  `string`. Path to a file containing the code to inject. In Firefox, relative URLs are resolved relative to the current page URL. In Chrome, these URLs are resolved relative to the extension's base URL. To work cross-browser, you can specify the path as an absolute URL, starting at the extension's root, like this: `"/path/to/stylesheet.css"`.

  
`frameId` Optional
  `integer`. The frame where the CSS should be injected. Defaults to `0` (the top-level frame).

  
`matchAboutBlank` Optional
  `boolean`. If `true`, the code will be injected into embedded "about:blank" and "about:srcdoc" frames if your extension has access to their parent document. The code cannot be inserted in top-level about: frames. Defaults to `false`.

  
`runAt` Optional
  [`extensionTypes.RunAt`](../extensiontypes/runat). The soonest that the code will be injected into the tab. Defaults to "document\_idle".

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when all the CSS has been inserted. If any error occurs, the promise will be rejected with an error message.

Examples
--------



This example inserts into the currently active tab CSS which is taken from a string.

 
```
let css = "body { border: 20px dotted pink; }";

browser.browserAction.onClicked.addListener(() => {

  function onError(error) {
    console.log(`Error: ${error}`);
  }

  let insertingCSS = browser.tabs.insertCSS({code: css});
  insertingCSS.then(null, onError);
});

```
 This example inserts CSS which is loaded from a file packaged with the extension. The CSS is inserted into the tab whose ID is 2:

 
```
browser.browserAction.onClicked.addListener(() => {

  function onError(error) {
    console.log(`Error: ${error}`);
  }

  let insertingCSS = browser.tabs.insertCSS(2, {file: "content-style.css"});
  insertingCSS.then(null, onError);
});

```

### Example extensions


* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `insertCSS` | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | 47Available for use in Manifest V2 only. | ? | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |
| `cssOrigin` | 39 | 79 | 53 | ? | No | No | ? | ? | 54 | ? | No | ? |
| `frameId` | 39 | 14 | 47 | ? | 26 | No | ? | ? | 54 | ? | No | ? |
| `matchAboutBlank` | 39 | 14 | No | ? | 26 | No | ? | ? | No | ? | No | ? |
| `runAt` | 20 | 79 | 47 | ? | 15 | No | ? | ? | 54 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-insertCSS) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS>

tabs.Tab
========


The type `tabs.Tab` contains information about a tab. This provides access to information about what content is in the tab, how large the content is, what special states or restrictions are in effect, and so forth.


Type
----



Values of this type are objects. They contain the following properties:

  `active`  `boolean`. Whether the tab is active in its window. This may be true even if the tab's window is not currently focused.

 The active tab is usually the selected one. However, on Firefox for Android, extension popups open in a new tab. When this popup tab is selected, the active tab will instead be the one in which the popup opened.

  
`attention` Optional
  `boolean`. Indicates whether the tab is drawing attention. For example, when the tab displays a modal dialog, `attention` will be `true`.

  
`audible` Optional
  `boolean`. Indicates whether the tab is producing sound. However, the user will not hear the sound if the tab is muted (see the `mutedInfo` property).

  
`autoDiscardable` Optional
  `boolean`. Whether the tab can be discarded automatically by the browser when resources are low.

  
`cookieStoreId` Optional
  `string`. The cookie store of the tab. If different tabs can have different cookie stores (for example, to support [contextual identity](https://wiki.mozilla.org/Security/Contextual_Identity_Project/Containers)), you can pass this as the `storeId` option into various methods of the [`cookies`](../cookies) API, to set and get cookies associated with this tab's cookie store. Only present if the extension has the `"cookies"` [permission](../../manifest.json/permissions).

  
`discarded` Optional
  `boolean`. Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content gets reloaded the next time it's activated.

  
`favIconUrl` Optional
  `string`. The URL of the tab's favicon. Only present if the extension has the `"tabs"` [permission](../../manifest.json/permissions) or [host permissions](../../manifest.json/permissions#host_permissions). It may also be `undefined` if the page has no favicon, or an empty string if the tab is loading.

  
`height` Optional
  `integer`. The height of the tab in pixels.

  `hidden`  `boolean`. Whether the tab is hidden.

  `highlighted`  `boolean`. Whether the tab is highlighted, i.e. part of the current tab selection. An active tab is always highlighted, but some browsers may allow additional tabs to be highlighted, for example by clicking them while holding `Ctrl`, `Shift` or `⌘ Command` keys.

 Firefox for Android doesn't support highlighting multiple tabs, and Firefox desktop requires the `browser.tabs.multiselect` preference (enabled by default).

  
`id` Optional
  `integer`. The tab's ID. Tab IDs are unique within a browser session. The tab ID may also be set to [`tabs.TAB_ID_NONE`](tab_id_none) for browser windows that don't host content tabs (for example, devtools windows).

  `incognito`  `boolean`. Whether the tab is in a private browsing window.

  `index`  `integer`. The zero-based index of the tab within its window.

  `isArticle`  `boolean`. True if the tab can be [rendered in Reader Mode](togglereadermode), false otherwise.

  `isInReaderMode`  `boolean`. True if the tab is currently being [rendered in Reader Mode](togglereadermode), false otherwise.

  `lastAccessed`  `double`. Time at which the tab was last accessed, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  
`mutedInfo` Optional
  [`tabs.MutedInfo`](mutedinfo). The current muted state for the tab and the reason for the last state change.

  
`openerTabId` Optional
  `integer`. The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists and is in the same window.

  `pinned`  `boolean`. Whether the tab is pinned.

  
`selected`  Deprecated 
  `boolean`. Whether the tab is selected. This property has been replaced by `active` and `highlighted`.

  
`sessionId` Optional
  `string`. The session ID used to uniquely identify a `Tab` obtained from the [`sessions`](../sessions) API.

  
`status` Optional
  `string`. Either *loading* or *complete*.

  
`successorTabId` Optional
  `integer` The ID of the tab's successor.

  
`title` Optional
  `string`. The title of the tab. Only present if the extension has the `"tabs"` [permission](../../manifest.json/permissions) or [host permissions](../../manifest.json/permissions#host_permissions) that matches the tab's URL.

  
`url` Optional
  `string`. The URL of the document that the tab is displaying. Only present if the extension has the `"tabs"` [permission](../../manifest.json/permissions) or a matching [host permissions](../../manifest.json/permissions#host_permissions).

  
`width` Optional
  `integer`. The width of the tab in pixels.

  `windowId`  `integer`. The ID of the window that hosts this tab.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `active` | 16 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `audible` | 45 | 79 | 45 | ? | 32 | 14 | ? | ? | 54 | ? | 15 | ? |
| `autoDiscardable` | 54 | 79 | No | ? | 41 | No | ? | ? | No | ? | No | ? |
| `cookieStoreId` | No | No | 52 | ? | No | No | ? | ? | No | ? | No | ? |
| `discarded` | 54 | 79 | 57 | ? | 41 | No | ? | ? | 57–79 | ? | No | ? |
| `favIconUrl` | 5 | 14 | 45 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `height` | 31 | 79 | 45 | ? | 18 | 14 | ? | ? | 54 | ? | 15 | ? |
| `highlighted` | 16 | 79 | 45 | ? | 15 | 14 | ? | ? | 54–79 | ? | 15 | ? |
| `id` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `incognito` | 16 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `index` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `isArticle` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `isInReaderMode` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `lastAccessed` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |
| `mutedInfo` | 46 | 79 | 45 | ? | 33 | 14`reason` and `extensionId` will not be populated. | ? | ? | 54 | ? | No | ? |
| `openerTabId` | 18 | 79 | 57 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `pinned` | 9 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | No | ? |
| `selected` | 5 | 79 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `sessionId` | 31 | 79 | 52 | ? | 18 | No | ? | ? | No | ? | No | ? |
| `status` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `successorTabId` | No | No | 65 | ? | No | No | ? | ? | No | ? | No | ? |
| `title` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `url` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `width` | 31 | 79 | 45 | ? | 18 | 14 | ? | ? | 54 | ? | 15 | ? |
| `windowId` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


### Example extensions



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)

  **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-Tab) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab>

tabs.remove()
=============



Closes one or more tabs.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.tabs.remove(
  tabIds          // integer or integer array
)

```
### Parameters


 `tabIds`  `integer` or `array` of `integer` The ids of the tab or tabs to close.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when all the specified tabs have been removed or their `beforeunload` prompts have been handled. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Close a single tab:

 
```
function onRemoved() {
  console.log(`Removed`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let removing = browser.tabs.remove(2);
removing.then(onRemoved, onError);

```
 Close multiple tabs:

 
```
function onRemoved() {
  console.log(`Removed`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let removing = browser.tabs.remove([15, 14, 1]);
removing.then(onRemoved, onError);

```

### Example extensions


* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-remove) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/remove>

tabs.update()
=============



Navigate the tab to a new URL, or modify other properties of the tab.

 To use this function, pass the ID of the tab to update, and an `updateProperties` object containing the properties you want to update. Properties that are not specified in `updateProperties` are not modified.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let updating = browser.tabs.update(
  tabId,              // optional integer
  updateProperties    // object
)

```
### Parameters


 
`tabId` Optional
  `integer`. Defaults to the selected tab of the current window.

  `updateProperties`  `object`. The set of properties to update for this tab. To learn more about these properties, see the [`tabs.Tab`](tab) documentation.

  
`active` Optional
  `boolean`. Whether the tab should become active. Does not affect whether the window is focused (see [`windows.update`](../windows/update)). If `true`, non-active highlighted tabs will stop being highlighted. If `false`, does nothing.

  
`autoDiscardable` Optional
  `boolean`. Whether the tab should be discarded automatically by the browser when resources are low.

  
`highlighted` Optional
  `boolean`. Adds or removes the tab from the current selection. If `true` and the tab is not highlighted, it will become active by default.

 If you only want to highlight the tab without activating it, Firefox accepts setting `highlighted` to `true` and `active` to `false`. Other browsers may activate the tab even in this case.

  
`loadReplace` Optional
  `boolean`. Whether the new URL should replace the old URL in the tab's navigation history, as accessed via the "Back" button.

 For example, suppose the user creates a new tab using Ctrl+T. By default, in Firefox, this would load "about:newtab". If your extension then updates this page using [`tabs.update`](update), without `loadReplace`, the "Back" button will be enabled and will take the user back to "about:newtab". If the extension sets `loadReplace`, then the "Back" button will be disabled and it will be just as if the URL supplied by the extension was the first page visited in that tab.

 Note though that the original URL will still appear in the browser's global history.

  
`muted` Optional
  `boolean`. Whether the tab should be muted.

  
`openerTabId` Optional
  `integer`. The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as this tab.

  
`pinned` Optional
  `boolean`. Whether the tab should be pinned.

  
`selected`  Deprecated  Optional
  `boolean`. Whether the tab should be selected. This property has been replaced by `active` and `highlighted`.

  
`successorTabId` Optional
  `integer`. The id of the tab's successor.

  
`url` Optional
  `string`. A URL to navigate the tab to.

 For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail, with [`runtime.lastError`](../runtime/lasterror) being set to an error message:

 * chrome: URLs
* javascript: URLs
* data: URLs
* file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below)
* privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`, `about:newtab`). Non-privileged URLs (e.g., `about:blank`) are allowed.

 To load a page that's packaged with your extension, specify an absolute URL starting at the extension's manifest.json file. For example: '/path/to/my-page.html'. If you omit the leading '/', the URL is treated as a relative URL, and different browsers may construct different absolute URLs.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing details about the updated tab. The [`tabs.Tab`](tab) object doesn't contain `url`, `title` and `favIconUrl` unless matching [host permissions](../../manifest.json/permissions#host_permissions) or the `"tabs"` permission has been requested. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Examples
--------



Navigate the active tab in the current window to `https://developer.mozilla.org`:

 
```
function onUpdated(tab) {
  console.log(`Updated tab: ${tab.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let updating = browser.tabs.update({url: "https://developer.mozilla.org"});
updating.then(onUpdated, onError);

```
 Activate the first tab in the current window, and navigate it to `https://developer.mozilla.org`:

 
```
function onUpdated(tab) {
  console.log(`Updated tab: ${tab.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function updateFirstTab(tabs) {
  let updating = browser.tabs.update(tabs[0].id, {
    active: true,
    url: "https://developer.mozilla.org"
  });
  updating.then(onUpdated, onError);
}

let querying = browser.tabs.query({currentWindow:true});
querying.then(updateFirstTab, onError);

```

### Example extensions


* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `active_value` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `autoDiscardable_value` | 54 | 79 | No | ? | 41 | No | ? | ? | No | ? | No | ? |
| `highlighted_value` | Yes | 79 | 63 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `loadReplace_value` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `muted_value` | 45 | 79 | 45 | ? | 32 | 14 | ? | ? | No | ? | No | ? |
| `openerTabId_value` | 18 | 79 | 57 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `pinned_value` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 54–79 | ? | No | ? |
| `selected_value` | Yes | 79 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `url_value` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-update) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/update>

tabs.reload()
=============



Reload a tab, optionally bypassing the local web cache.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let reloading = browser.tabs.reload(
  tabId,            // optional integer
  reloadProperties  // optional object
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to reload. Defaults to the selected tab of the current window.

  
`reloadProperties` Optional
  An object with the following properties:

  
`bypassCache` Optional
  `boolean`. Bypass the local web cache. Default is `false`.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the tab has been reloaded. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Reload the active tab of the current window:

 
```
browser.tabs.reload();

```
 Reload the active tab of the current window, bypassing the cache:

 
```
browser.tabs.reload({bypassCache: true});

```
 Reload the tab whose ID is 2, bypassing the cache and calling a callback when done:

 
```
function onReloaded() {
  console.log(`Reloaded`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let reloading = browser.tabs.reload(2, {bypassCache: true});
reloading.then(onReloaded, onError);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `reload` | Yes | 17 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-reload) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/reload>

tabs.getZoom()
==============



Gets the current zoom factor for the specified tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingZoom = browser.tabs.getZoom(
  tabId                     // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to get the current zoom factor from. Defaults to the active tab of the current window.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the tab's current zoom factor, as a number between 0.3 and 5. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Examples
--------



Get the zoom factor for the current tab:

 
```
function onGot(zoom) {
  console.log(zoom);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let gettingZoom = browser.tabs.getZoom();
gettingZoom.then(onGot, onError);

```
 Get the zoom factor for the tab whose ID is 2:

 
```
function onGot(zoom) {
  console.log(zoom);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let gettingZoom = browser.tabs.getZoom(2);
gettingZoom.then(onGot, onError);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getZoom` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoom) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getZoom>

tabs.setZoom()
==============



Zooms the specified tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let zooming = browser.tabs.setZoom(
  tabId,           // optional integer
  zoomFactor       // number
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to zoom. Defaults to the active tab of the current window.

  `zoomFactor`  `number`. The new zoom factor. Use a value of 0 here to set the tab to its current default zoom factor. Otherwise, this must be a number between 0.3 and 5, specifying a zoom factor.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments after the zoom factor has been changed. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Examples
--------



Set the zoom factor for the current tab to 2:

 
```
function onError(error) {
  console.log(`Error: ${error}`);
}

let setting = browser.tabs.setZoom(2);
setting.then(null, onError);

```
 Set the zoom factor for the tab whose ID is 16 tab to 0.5:

 
```
function onError(error) {
  console.log(`Error: ${error}`);
}

let setting = browser.tabs.setZoom(16, 0.5);
setting.then(null, onError);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setZoom` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-setZoom) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/setZoom>

tabs.move()
===========



Moves one or more tabs to a new position in the same window or to a different window.

 You can only move tabs to and from windows whose [`WindowType`](../windows/windowtype) is `"normal"`.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let moving = browser.tabs.move(
  tabIds,              // integer or integer array
  moveProperties       // object
)

```
### Parameters


 `tabIds`  `integer` or `array` of `integer`. ID of the [`tab`](tab) to move, or an array of tab IDs.

  `moveProperties`  `object`. An object that specifies where to move the tab(s).

  
`windowId` Optional
  `integer`. The ID of the window to which you want to move the tab(s). If you omit this, then each tab in `tabIds` will be moved to `index` in its current window. If you include this, and `tabIds` contains more than one tab, then the first tab in `tabIds` will be moved to `index`, and the other tabs will follow it in the order given in `tabIds`.

  `index`  `integer`. The index position to move the tab to, starting at 0. A value of -1 will place the tab at the end of the window.

 If you pass a value less than -1, the function will throw an error.

 Note that you can't move pinned tabs to a position after any unpinned tabs in a window, or move any unpinned tabs to a position before any pinned tabs. For example, if you have one or more pinned tabs in the target window and `tabIds` refers to an unpinned tab, then you can't pass 0 here. If you try to do this, the function will silently fail (it will not throw an error).

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a `[`tabs.Tab`](tab)` object or an `array` of `[`tabs.Tab`](tab)` objects, containing details about the moved tabs. If no tabs were moved (for example, because you tried to move an unpinned tab before a pinned tab) this will be an empty array. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Move the first tab in the current window to the last position in the current window:

 
```
function onMoved(tab) {
  console.log(`Moved: ${tab}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function firstToLast(windowInfo) {
  if (windowInfo.tabs.length === 0) {
    return;
  }
  let moving = browser.tabs.move(windowInfo.tabs[0].id, {index: -1});
  moving.then(onMoved, onError);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingCurrent = browser.windows.getCurrent({populate: true});
  gettingCurrent.then(firstToLast, onError);
});

```
 Move all tabs served over HTTP or HTTPS from \*.mozilla.org to the end of their window:

 
```
function onMoved(tab) {
  console.log(`Moved: ${tab}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function moveMoz(tabs) {
  let mozTabIds = tabs.map((tabInfo) => tabInfo.id);
  let moving = browser.tabs.move(mozTabIds, {index: -1});
  moving.then(onMoved, onError);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingMozTabs = browser.tabs.query({url:"\*://\*.mozilla.org/\*"});
  gettingMozTabs.then(moveMoz, onError);
});

```
 Move all tabs served over HTTP or HTTPS from \*.mozilla.org to the window that hosts the first such tab, starting at position 0:

 
```
function onMoved(tab) {
  console.log(`Moved: ${tab}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function moveMoz(tabs) {
  let mozTabIds = tabs.map((tabInfo) => tabInfo.id);
  let targetWindow = tabs[0].windowId;
  let moving = browser.tabs.move(mozTabIds, {windowId: targetWindow, index: 0});
  moving.then(onMoved, onError);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingMozTabs = browser.tabs.query({url:"\*://\*.mozilla.org/\*"});
  gettingMozTabs.then(moveMoz, onError);
});

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `move` | Yes | 79 | 46 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-move) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.getZoom

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/move>

tabs.getZoomSettings()
======================



Gets the current zoom settings for a specified tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingZoomSettings = browser.tabs.getZoomSettings(
  tabId                       // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to get the current zoom settings from. Defaults to the active tab of the current window.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.ZoomSettings`](zoomsettings) object representing the tab's current zoom settings. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Examples
--------



Get the zoom settings for the current tab:

 
```
function onGot(settings) {
  console.log(settings);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let gettingZoomSettings = browser.tabs.getZoomSettings();
gettingZoomSettings.then(onGot, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getZoomSettings` | 42 | 79 | 45 | ? | 29 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoomSettings) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getZoomSettings>

tabs.setZoomSettings()
======================



Sets zoom settings for the specified tab. These settings are reset to the default settings upon navigating the tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let settingZoomSettings = browser.tabs.setZoomSettings(
  tabId,           // optional integer
  zoomSettings     // ZoomSettings
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to change the zoom settings for. Defaults to the active tab of the current window.

  `zoomSettings`  [`tabs.ZoomSettings`](zoomsettings). Defines how zoom changes are handled and at what scope.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments after the zoom settings have been changed. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.getZoom

Examples
--------



Disable zooming for the current tab:

 
```
function onSet() {
  console.log(`Set zoom factor`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let setting = browser.tabs.setZoomSettings({mode:"disabled"});
setting.then(onSet, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setZoomSettings` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-setZoomSettings) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/setZoomSettings>

tabs.captureVisibleTab()
========================



Creates a data URL encoding the image of an area of the currently active tab in the specified window. You must have the `<all_urls>` [permission](../../manifest.json/permissions) to use this method. (Alternately, Chrome allows use of this method with the `activeTab` [permission](../../manifest.json/permissions) and a qualifying user gesture).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let capturing = browser.tabs.captureVisibleTab(
  windowId,               // optional integer
  options                 // optional extensionTypes.ImageDetails
)

```
### Parameters


 
`windowId` Optional
  `integer`. The target window. Defaults to the current window.

  
`options` Optional
  [`extensionTypes.ImageDetails`](../extensiontypes/imagedetails).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a data URL which encodes the captured image. May be assigned to the 'src' property of an HTML Image element for display. If any error occurs the promise will be rejected with an error message.

Examples
--------



Capture an image of the active tab in the current window, with default settings:

 
```
function onCaptured(imageUri) {
  console.log(imageUri);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(() => {
  let capturing = browser.tabs.captureVisibleTab();
  capturing.then(onCaptured, onError);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `captureVisibleTab` | 5The default file format is 'jpeg'. | 15 | 47 | ? | 15The default file format is 'jpeg'. | 14["The default file format is 'jpeg'.", "`<all_urls>` permission is optional."] | ? | ? | 54 | ? | 15["The default file format is 'jpeg'.", "`<all_urls>` permission is optional."] | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-captureVisibleTab) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/captureVisibleTab>

tabs
====



Interact with the browser's tab system.

  **Note:** When using Manifest V3 or higher, the methods to execute scripts, insert CSS, and remove CSS are provided by the [`scripting`](scripting) API through the [`scripting.executeScript()`](scripting/executescript), [`scripting.insertCSS()`](scripting/insertcss) and [`scripting.removeCSS()`](scripting/removecss) methods.

  You can use this API to get a list of opened tabs, filtered by various criteria, and to open, update, move, reload, and remove tabs. You can't directly access the content hosted by tabs using this API, but you can insert JavaScript and CSS into tabs using the [`tabs.executeScript()`](tabs/executescript) or [`tabs.insertCSS()`](tabs/insertcss) APIs.

 You can use most of this API without any special permission. However:

 * To access `Tab.url`, `Tab.title`, and `Tab.favIconUrl` (or to filter by these properties via [`tabs.query()`](tabs/query)), you need to have the `"tabs"` [permission](../manifest.json/permissions), or have [host permissions](../manifest.json/permissions#host_permissions) that match `Tab.url`.
	+ Access to these properties by host permissions is supported since Firefox 86 and Chrome 50. In Firefox 85 and earlier, the "tabs" permission was required instead.
* To use [`tabs.executeScript()`](tabs/executescript) or [`tabs.insertCSS()`](tabs/insertcss), you must have the [host permission](../manifest.json/permissions#host_permissions) for the tab

 Alternatively, you can get these permissions temporarily, only for the currently active tab and only in response to an explicit user action, by asking for the [`"activeTab"` permission](../manifest.json/permissions#activetab_permission).

 Many tab operations use a Tab `id`. Tab `id`s are guaranteed to be unique to a single tab only within a browser session. If the browser is restarted, then it can and will reuse tab `id`s. To associate information with a tab across browser restarts, use [`sessions.setTabValue()`](sessions/settabvalue).



Types
-----


 [`tabs.MutedInfoReason`](tabs/mutedinforeason)  Specifies the reason a tab was muted or unmuted.

  [`tabs.MutedInfo`](tabs/mutedinfo)  This object contains a boolean indicating whether the tab is muted, and the reason for the last state change.

  [`tabs.PageSettings`](tabs/pagesettings)  Used to control how a tab is rendered as a PDF by the [`tabs.saveAsPDF()`](tabs/saveaspdf) method.

  [`tabs.Tab`](tabs/tab)  This type contains information about a tab.

  [`tabs.TabStatus`](tabs/tabstatus)  Indicates whether the tab has finished loading.

  [`tabs.WindowType`](tabs/windowtype)  The type of window that hosts this tab.

  [`tabs.ZoomSettingsMode`](tabs/zoomsettingsmode)  Defines whether zoom changes are handled by the browser, by the extension, or are disabled.

  [`tabs.ZoomSettingsScope`](tabs/zoomsettingsscope)  Defines whether zoom changes will persist for the page's origin, or only take effect in this tab.

  [`tabs.ZoomSettings`](tabs/zoomsettings)  Defines zoom settings [`mode`](tabs/zoomsettingsmode), [`scope`](tabs/zoomsettingsscope), and default zoom factor.

  Properties
----------


 [`tabs.TAB_ID_NONE`](tabs/tab_id_none)  A special ID value given to tabs that are not browser tabs (for example, tabs in devtools windows).

  Functions
---------


 [`tabs.captureTab()`](tabs/capturetab)  Creates a data URL encoding an image of the visible area of the given tab.

  [`tabs.captureVisibleTab()`](tabs/capturevisibletab)  Creates a data URL encoding an image of the visible area of the currently active tab in the specified window.

  [`tabs.connect()`](tabs/connect)  Sets up a messaging connection between the extension's background scripts (or other privileged scripts, such as popup scripts or options page scripts) and any [content scripts](../content_scripts) running in the specified tab.

  [`tabs.create()`](tabs/create)  Creates a new tab.

  [`tabs.detectLanguage()`](tabs/detectlanguage)  Detects the primary language of the content in a tab.

  [`tabs.discard()`](tabs/discard)  Discards one or more tabs.

  [`tabs.duplicate()`](tabs/duplicate)  Duplicates a tab.

  
[`tabs.executeScript()`](tabs/executescript) (Manifest V2 only)  Injects JavaScript code into a page.

  [`tabs.get()`](tabs/get)  Retrieves details about the specified tab.

  
[`tabs.getAllInWindow()`](tabs/getallinwindow)  Deprecated 
  Gets details about all tabs in the specified window.

  [`tabs.getCurrent()`](tabs/getcurrent)  Gets information about the tab that this script is running in, as a [`tabs.Tab`](tabs/tab) object.

  
[`tabs.getSelected()`](tabs/getselected)  Deprecated 
  Gets the tab that is selected in the specified window. **Deprecated: use [`tabs.query({active: true})`](tabs/query) instead.**

  [`tabs.getZoom()`](tabs/getzoom)  Gets the current zoom factor of the specified tab.

  [`tabs.getZoomSettings()`](tabs/getzoomsettings)  Gets the current zoom settings for the specified tab.

  [`tabs.goForward()`](tabs/goforward)  Go forward to the next page, if one is available.

  [`tabs.goBack()`](tabs/goback)  Go back to the previous page, if one is available.

  
[`tabs.hide()`](tabs/hide)  Experimental 
  Hides one or more tabs.

  [`tabs.highlight()`](tabs/highlight)  Highlights one or more tabs.

  
[`tabs.insertCSS()`](tabs/insertcss) (Manifest V2 only)  Injects CSS into a page.

  [`tabs.move()`](tabs/move)  Moves one or more tabs to a new position in the same window or to a different window.

  [`tabs.moveInSuccession()`](tabs/moveinsuccession)  Modifies the succession relationship for a group of tabs.

  [`tabs.print()`](tabs/print)  Prints the contents of the active tab.

  [`tabs.printPreview()`](tabs/printpreview)  Opens print preview for the active tab.

  [`tabs.query()`](tabs/query)  Gets all tabs that have the specified properties, or all tabs if no properties are specified.

  [`tabs.reload()`](tabs/reload)  Reload a tab, optionally bypassing the local web cache.

  [`tabs.remove()`](tabs/remove)  Closes one or more tabs.

  
[`tabs.removeCSS()`](tabs/removecss) (Manifest V2 only)  Removes from a page CSS which was previously injected by calling [`tabs.insertCSS()`](tabs/insertcss).

  [`tabs.saveAsPDF()`](tabs/saveaspdf)  Saves the current page as a PDF.

  [`tabs.sendMessage()`](tabs/sendmessage)  Sends a single message to the content script(s) in the specified tab.

  
[`tabs.sendRequest()`](tabs/sendrequest)  Deprecated 
  Sends a single request to the content script(s) in the specified tab. **Deprecated**: use [`tabs.sendMessage()`](tabs/sendmessage) instead.

  [`tabs.setZoom()`](tabs/setzoom)  Zooms the specified tab.

  [`tabs.setZoomSettings()`](tabs/setzoomsettings)  Sets the zoom settings for the specified tab.

  
[`tabs.show()`](tabs/show)  Experimental 
  Shows one or more tabs that have been [`hidden`](tabs/hide).

  [`tabs.toggleReaderMode()`](tabs/togglereadermode)  Toggles Reader mode for the specified tab.

  [`tabs.update()`](tabs/update)  Navigate the tab to a new URL, or modify other properties of the tab.

  [`tabs.warmup()`](tabs/warmup)  Prepare the tab to make a potential following switch faster.

  Events
------


 [`tabs.onActivated`](tabs/onactivated)  Fires when the active tab in a window changes. Note that the tab's URL may not be set at the time this event fired.

  
[`tabs.onActiveChanged`](tabs/onactivechanged)  Deprecated 
  Fires when the selected tab in a window changes. **Deprecated:** use [`tabs.onActivated`](tabs/onactivated) instead.

  [`tabs.onAttached`](tabs/onattached)  Fired when a tab is attached to a window, for example because it was moved between windows.

  [`tabs.onCreated`](tabs/oncreated)  Fired when a tab is created. Note that the tab's URL may not be set at the time this event fired.

  [`tabs.onDetached`](tabs/ondetached)  Fired when a tab is detached from a window, for example because it is being moved between windows.

  
[`tabs.onHighlightChanged`](tabs/onhighlightchanged)  Deprecated 
  Fired when the highlighted or selected tabs in a window change. **Deprecated:** use [`tabs.onHighlighted`](tabs/onhighlighted) instead.

  [`tabs.onHighlighted`](tabs/onhighlighted)  Fired when the highlighted or selected tabs in a window change.

  [`tabs.onMoved`](tabs/onmoved)  Fired when a tab is moved within a window.

  [`tabs.onRemoved`](tabs/onremoved)  Fired when a tab is closed.

  [`tabs.onReplaced`](tabs/onreplaced)  Fired when a tab is replaced with another tab due to prerendering.

  
[`tabs.onSelectionChanged`](tabs/onselectionchanged)  Deprecated 
  Fires when the selected tab in a window changes. **Deprecated:** use [`tabs.onActivated`](tabs/onactivated) instead.

  [`tabs.onUpdated`](tabs/onupdated)  Fired when a tab is updated.

  [`tabs.onZoomChange`](tabs/onzoomchange)  Fired when a tab is zoomed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MutedInfo` | 46 | 79 | 47 | ? | 33 | 14`reason` and `extensionId` will not be populated. | ? | ? | No | ? | No | ? |
| `MutedInfoReason` | 46 | 79 | 47 | ? | 33 | No | ? | ? | No | ? | No | ? |
| `PageSettings` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `TAB_ID_NONE` | 46 | 14 | 45 | ? | 33 | 14 | ? | ? | 54 | ? | 15 | ? |
| `TabStatus` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `WindowType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `ZoomSettings` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |
| `ZoomSettingsMode` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |
| `ZoomSettingsScope` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |
| `captureTab` | No | No | 59 | ? | No | No | ? | ? | 82 | ? | No | ? |
| `captureVisibleTab` | 5The default file format is 'jpeg'. | 15 | 47 | ? | 15The default file format is 'jpeg'. | 14["The default file format is 'jpeg'.", "`<all_urls>` permission is optional."] | ? | ? | 54 | ? | 15["The default file format is 'jpeg'.", "`<all_urls>` permission is optional."] | ? |
| `connect` | 5 | 79 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `create` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `detectLanguage` | 5 | 14 | 45 | ? | 15 | 14["Will return `und` (undefined language) for OS lower than 11.", "Locale identifier will include the country code more often."] | ? | ? | No | ? | 15 | ? |
| `discard` | 54["Only accepts a single tab ID as a parameter, not an array.", "The tab ID argument is optional: if it is omitted, the browser discards the least important tab.", "The callback is passed a `Tab` object representing the tab that was discarded.", "Tabs whose document contains a [`beforeunload`](https://developer.mozilla.org/docs/Web/API/BeforeUnloadEvent) listener that displays a prompt will be discarded."] | 14 | 58 | ? | 41["Only accepts a single tab ID as a parameter, not an array.", "The tab ID argument is optional: if it is omitted, the browser discards the least important tab.", "The callback is passed a `Tab` object representing the tab that was discarded.", "Tabs whose document contains a [`beforeunload`](https://developer.mozilla.org/docs/Web/API/BeforeUnloadEvent) listener that displays a prompt will be discarded."] | No | ? | ? | No | ? | No | ? |
| `duplicate` | 23 | 79 | 47 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `executeScript` | 5["Extensions can't inject scripts into their own pages using this API.", "Available for use in Manifest V2 only."] | 14Available for use in Manifest V2 only. | 43["Before version 50, Firefox would pass a single result value into its callback rather than an array, unless 'allFrames' had been set.", "Available for use in Manifest V2 only."] | ? | 15["Extensions can't inject scripts into their own pages using this API.", "Available for use in Manifest V2 only."] | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |
| `get` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `getAllInWindow` | 5 | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `getCurrent` | 6 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |
| `getSelected` | Yes | 79 | No | ? | No | 14 | ? | ? | No | ? | 15 | ? |
| `getZoom` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getZoomSettings` | 42 | 79 | 45 | ? | 29 | No | ? | ? | No | ? | No | ? |
| `goBack` | 72 | 79 | 77 | ? | 60 | 14 | ? | ? | 79 | ? | 15 | ? |
| `goForward` | 72 | 79 | 77 | ? | 60 | 14 | ? | ? | 79 | ? | 15 | ? |
| `hide` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |
| `highlight` | Yes | 79 | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `insertCSS` | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | 47Available for use in Manifest V2 only. | ? | YesAvailable for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |
| `move` | Yes | 79 | 46 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `moveInSuccession` | No | No | 65 | ? | No | No | ? | ? | No | ? | No | ? |
| `onActivated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onActiveChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `onAttached` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onCreated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onDetached` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onHighlightChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `onHighlighted` | Yes | 79 | 6345–62Implemented as an alias for `onActivated`. | ? | No | 14 | ? | ? | 54Implemented as an alias for `onActivated`. | ? | 15 | ? |
| `onMoved` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `onRemoved` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onReplaced` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onSelectionChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `onUpdated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `onZoomChange` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `print` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `printPreview` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `query` | Yes | 14The `panel`, `app`, `devtools` and `popup` values for `WindowType` are not supported. | 45 | ? | Yes | 14Pattern matching supports `*` and `?`. | ? | ? | 54 | ? | 15Pattern matching supports `*` and `?`. | ? |
| `reload` | Yes | 17 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `remove` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `removeCSS` | 87Available for use in Manifest V2 only. | 87Available for use in Manifest V2 only. | 49Available for use in Manifest V2 only. | ? | 73Available for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |
| `saveAsPDF` | No | No | 8156–81This function does not work on macOS. | ? | No | No | ? | ? | No | ? | No | ? |
| `sendMessage` | Yes | 14No response is sent after the receiving tab is refreshed if there is no `runtime.onMessage` listener. | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `sendRequest` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `setZoom` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `setZoomSettings` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `show` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |
| `toggleReaderMode` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `update` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `warmup` | No | No | 79 | ? | No | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)
* [context-menu-copy-link-with-types](https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types)
* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)
* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [list-cookies](https://github.com/mdn/webextensions-examples/tree/master/list-cookies)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
* [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)

  **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs>

pageAction
==========



A [page action](../user_interface/page_actions) is a clickable icon inside the browser's address bar.

  ![Paw print icon representing a page action](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/page-action.png) 

 You can listen for clicks on the icon, or specify a [popup](../user_interface/popups) that will open when the icon is clicked.

 If you specify a popup, you can define its contents and behavior using HTML, CSS, and JavaScript—just like a normal web page. JavaScript running in the popup gets access to all the same WebExtension APIs as your background scripts.

 You can define most of a page action's properties declaratively using the [`page_action` key](../manifest.json/page_action) in your [`manifest.json`](../manifest.json), but can also redefine them programmatically using this API.

 Page actions are for actions that are only relevant to particular pages (such as "bookmark the current tab"). If they are relevant to the browser as a whole (such as "show all bookmarks"), use a browser action instead.



Types
-----


 [`pageAction.ImageDataType`](pageaction/imagedatatype)  Pixel data for an image.

  Functions
---------


 [`pageAction.show()`](pageaction/show)  Shows the page action for a given tab.

  [`pageAction.hide()`](pageaction/hide)  Hides the page action for a given tab.

  [`pageAction.isShown()`](pageaction/isshown)  Checks whether the page action is shown or not.

  [`pageAction.setTitle()`](pageaction/settitle)  Sets the page action's title. This is displayed in a tooltip over the page action.

  [`pageAction.getTitle()`](pageaction/gettitle)  Gets the page action's title.

  [`pageAction.setIcon()`](pageaction/seticon)  Sets the page action's icon.

  [`pageAction.setPopup()`](pageaction/setpopup)  Sets the URL for the page action's popup.

  [`pageAction.getPopup()`](pageaction/getpopup)  Gets the URL for the page action's popup.

  [`pageAction.openPopup()`](pageaction/openpopup)  Opens the page action's popup.

  Events
------


 [`pageAction.onClicked`](pageaction/onclicked)  Fired when a page action icon is clicked. This event will not fire if the page action has a popup.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `getPopup` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50The 'tabId' parameter is ignored: the page action popup is the same for all tabs. | ? | 15 | ? |
| `getTitle` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15The API exists, but the title not visible in the UI. | ? |
| `hide` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 50Before version 56, the 'tabId' parameter was ignored, and the page action was hidden for all tabs. | ? | No | ? |
| `isShown` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `onClicked` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50 | ? | 15 | ? |
| `openPopup` | No | No | 57 | ? | No | 16 | ? | ? | 79 | ? | 16 | ? |
| `setIcon` | YesBefore Chrome 23, `path` couldn't specify multiple icon files, but had to be a string specifying a single icon path. | 14 | 45 | ? | 15 | 14 | ? | ? | 79 | ? | 15 | ? |
| `setPopup` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50The 'tabId' parameter is ignored, and the popup is set for all tabs. | ? | 15 | ? |
| `setTitle` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15The API exists, but the title not visible in the UI. | ? |
| `show` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 50Before version 56, the 'tabId' parameter was ignored, and the page action was shown for all tabs. | ? | No | ? |


Example extensions
------------------



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)

  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction>

contextualIdentities
====================



Work with contextual identities: list, create, remove, and update contextual identities.

 "Contextual identities", also known as "containers", are a browser feature which addresses the idea that users assume multiple identities when browsing the web, and wish to maintain some separation between these identities. For example, a user might consider their "work identity" separate from their "personal identity", and not want to share cookies between these two contexts.

 With the contextual identities feature, each contextual identity has a name, a color, and an icon. New tabs can be assigned to an identity, and the name, icon, and color will appear in the address bar. Internally, each identity gets its own cookie store which is not shared with other tabs.

  ![A context menu with "open in new container tab" submenu highlighted. The submenu shows personal, work, banking, and shopping contextual identities.]Contextual identities are an experimental feature in Firefox and are only enabled by default in Firefox Nightly. To enable them in other versions of Firefox, set the `privacy.userContext.enabled` preference to `true`. Note that although contextual identities are available in Firefox for Android, there's no UI to work with them in this version of the browser. 

 Before Firefox 57, the `contextualIdentities` API is only available if the contextual identities feature is itself enabled. If an extension tried to use the `contextualIdentities` API without the feature being enabled, then method calls would resolve their promises with `false`.

 From Firefox 57 onwards, if an extension that uses the `contextualIdentities` API is installed, then the contextual identities feature will be enabled automatically. Note though that it's still possible for the user to disable the feature using the "privacy.userContext.enabled" preference. If this happens, then `contextualIdentities` method calls will reject their promises with an error message.

 For more information about contextual identities in Firefox, see [this guide](https://wiki.mozilla.org/Security/Contextual_Identity_Project/Containers).

 Contextual identities are not currently supported in any other browsers.

 To use this API you need to include the "contextualIdentities" and "cookies" [permissions](../manifest.json/permissions) in your [manifest.json](../manifest.json) file.



Types
-----


 [`contextualIdentities.ContextualIdentity`](contextualidentities/contextualidentity)  Contains information about a contextual identity.

  Functions
---------


 [`contextualIdentities.create()`](contextualidentities/create)  Creates a new contextual identity.

  [`contextualIdentities.get()`](contextualidentities/get)  Retrieves a single contextual identity, given its cookie store ID.

  [`contextualIdentities.query()`](contextualidentities/query)  Retrieves all contextual identities, or all contextual identities with a particular name.

  [`contextualIdentities.update()`](contextualidentities/update)  Updates properties of an existing contextual identity.

  [`contextualIdentities.remove()`](contextualidentities/remove)  Deletes a contextual identity.

  Events
------


 [`contextualIdentities.onCreated`](contextualidentities/oncreated)  Fired when a contextual identity is created.

  [`contextualIdentities.onRemoved`](contextualidentities/onremoved)  Fired when a contextual identity is removed.

  [`contextualIdentities.onUpdated`](contextualidentities/onupdated)  Fired when one or more properties of a contextual identity is updated.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | No | No | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | No | ? | ? | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | ? |
| `get` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |
| `onCreated` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `onRemoved` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `onUpdated` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `query` | No | No | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | No | ? | ? | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | ? |
| `remove` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |
| `update` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |


Example extensions
------------------


* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities>

Chrome incompatibilities
========================



Extensions built with WebExtension APIs are designed to be compatible with Chrome and Opera extensions. As far as possible, extensions written for those browsers should run on Firefox with minimal changes.

 However, there are significant differences between Chrome, Firefox, and Edge. In particular:

 * Support for JavaScript APIs differs across browsers. See [Browser support for JavaScript APIs](browser_support_for_javascript_apis) for more details.
* Support for `manifest.json` keys differs across browsers. See the ["Browser compatibility" section](manifest.json#browser_compatibility) in the [`manifest.json`](manifest.json) page for more details.
* JavaScript APIs:
	+ **In Firefox:** JavaScript APIs are accessed under the `browser` namespace.
	+ **In Chrome and Edge:** JavaScript APIs are accessed under the `chrome` namespace. (cf. [Chrome bug 798169](https://crbug.com/798169))
* Asynchronous APIs:
	+ **In Firefox:** Asynchronous APIs are implemented using promises.
	+ **In Chrome and Edge:** Asynchronous APIs are implemented using callbacks. (cf. [Chrome bug 328932](https://crbug.com/328932))

 The rest of this page summarizes these and other incompatibilities.



JavaScript APIs
---------------


### chrome.\* and browser.\* namespace


* **In Firefox:** The equivalent APIs are accessed using the `browser` namespace. 
```
browser.browserAction.setIcon({path: "path/to/icon.png"});

```
* **In Chrome:** Extensions access privileged JavaScript APIs using the `chrome` namespace. 
```
chrome.browserAction.setIcon({path: "path/to/icon.png"});

```
### Callbacks and promises


* **In Firefox:** Asynchronous APIs use [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to return values instead. 
```
function logCookie(c) {
  console.log(c);
}

function logError(e) {
  console.error(e);
}

let setCookie = browser.cookies.set(
  {url: "https://developer.mozilla.org/"}
);
setCookie.then(logCookie, logError);

```
* **In Chrome:** Asynchronous APIs use callbacks to return values, and [`runtime.lastError`](api/runtime/lasterror) to communicate errors. 
```
function logCookie(c) {
  if (chrome.runtime.lastError) {
    console.error(chrome.runtime.lastError);
  } else {
    console.log(c);
  }
}

chrome.cookies.set(
  {url: "https://developer.mozilla.org/"},
  logCookie
);

```
### Firefox supports both the chrome and browser namespaces



As a porting aid, the Firefox implementation of WebExtensions supports `chrome`, using callbacks, as well as `browser`, using promises. This means that many Chrome extensions will just work in Firefox without any changes.

  **Note:** However, this is *not* part of the WebExtensions standard and may not be supported by all compliant browsers.

  If you choose to write your extension to use `browser` and promises, then Firefox also provides a polyfill that will enable it to run in Chrome: <https://github.com/mozilla/webextension-polyfill>.


### Partially supported APIs



The page [Browser support for JavaScript APIs](browser_support_for_javascript_apis) includes compatibility tables for all APIs that have any support in Firefox. Where there are caveats around support for a given API item, this is indicated in these tables with an asterisk "\*" and in the reference page for the API item, the caveats are explained.

 These tables are generated from compatibility data stored as [JSON files in GitHub](https://github.com/mdn/browser-compat-data).

 The rest of this section describes compatibility issues that are not already captured in the tables.

 #### Notifications API

 For `notifications.create()`, with `type "basic"`:

 * **In Firefox**: `iconUrl` is optional.
* **In Chrome**: `iconUrl` is required.

 When the user clicks on a notification:

 * **In Firefox**: The notification is cleared immediately.
* **In Chrome**: This is not the case.

 If you call `notifications.create()` more than once in rapid succession:

 * **In Firefox**: In Firefox, the notifications may not display at all. Waiting to make subsequent calls until within the `chrome.notifications.create()` callback function is not a sufficient delay to prevent this.

 #### Proxy API

 Firefox's [`proxy`](api/proxy) API followed a completely different design from Chrome's Proxy API.

 * **In Firefox**: An extension can register a PAC file.
* **In Chrome**: An extension can register a PAC file, but can also define explicit proxying rules.

 Because this API is incompatible with Chrome's `proxy` API, the Firefox proxy API is only available through the `browser` namespace.

 #### Tabs API

 When using `tabs.executeScript()` or `tabs.insertCSS()`:

 * **In Firefox**: Relative URLs passed are resolved relative to the current page URL.
* **In Chrome**: These URLs are resolved relative to the extension's base URL.

 To work cross-browser, you can specify the path as an absolute URL, starting at the extension's root, like this:

 
```
/path/to/script.js

```
 When querying tabs by URL `tabs.query()`:

 * **In Firefox**: Extensions must have the `"tabs"` permission.
* **In Chrome**: Extensions do not need the `"tabs"` permission, but only tabs whose URLs match the extension's host permissions will be included in the results.

 When calling `tabs.remove()`:

 * **In Firefox**: The `tabs.remove()` promise is fulfilled after the `beforeunload` event.
* **In Chrome**: The callback does not wait for `beforeunload`.

 #### WebRequest API

 * **In Firefox:**
	+ Requests can be redirected only if their original URL uses the `http:` or `https:` scheme.
	+ The `activeTab` permission does not allow intercepting network requests in the current tab. (See [bug 1617479](https://bugzil.la/1617479))
	+ Events are not fired for system requests (for example, extension upgrades or search bar suggestions).
		- **From Firefox 57 onwards:** Firefox makes an exception for extensions that need to intercept [`webRequest.onAuthRequired`](api/webrequest/onauthrequired) for proxy authorization. See the documentation for [`webRequest.onAuthRequired`](api/webrequest/onauthrequired).
	+ If an extension wants to redirect a public (e.g., HTTPS) URL to an [extension page](user_interface/extension_pages), the extension's `manifest.json` file must contain a [`web_accessible_resources`](manifest.json/web_accessible_resources) key with the URL of the extension page.
		- **Note:** *Any* website may then link or redirect to that URL, and extensions should treat any input (POST data, for example) as if it came from an untrusted source, just as a normal web page should.
	+ Some of the `browser.webRequest.*` APIs allow returning Promises that resolves `webRequest.BlockingResponse` asynchronously.
* **In Chrome:** Only `webRequest.onAuthRequired` supports asynchronous `webRequest.BlockingResponse` via supplying `'asyncBlocking'`.

 #### Windows API

 * **In Firefox:** `onFocusChanged` of the [`windows`](api/windows) API, will trigger multiple times for a given focus change.


### Unsupported APIs



#### DeclarativeContent API

 * **In Firefox:** Chrome's [declarativeContent](https://developer.chrome.com/docs/extensions/reference/declarativeContent/) API [has not yet been implemented](https://bugzil.la/1435864). In addition, Firefox [will not be supporting](https://bugzil.la/1323433#c16) the `declarativeContent.RequestContentScript` API (which is rarely used, and is unavailable in stable releases of Chrome).


### Miscellaneous incompatibilities



#### URLs in CSS

 * **In Firefox:** URLs in injected CSS files are resolved relative to *the CSS file itself*.
* **In Chrome:** URLs in injected CSS files are resolved relative to *the page they are injected into*.

 #### Support for dialogs in background pages

 * **In Firefox:** [`alert()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert), [`confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm), and [`prompt()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) are not supported in background pages:

 #### web\_accessible\_resources

 * **In Firefox:** Resources are assigned a random [UUID](https://developer.mozilla.org/en-US/docs/Glossary/UUID) that changes for every instance of Firefox: `moz-extension://«random-UUID»/«path»`. This randomness can prevent you from doing a few things, such as add your specific extension's URL to another domain's CSP policy.
* **In Chrome:** When a resource is listed in `web_accessible_resources`, it is accessible as `chrome-extension://«your-extension-id»/«path»`. The extension ID is fixed for a given extension.

 #### Manifest "key" property

 * **In Firefox:** Since Firefox uses random UUIDs for `web_accessible_resources`, this property is unsupported.
* **In Chrome:** When working with an unpacked extension, the manifest may include a [`"key"` property](https://developer.chrome.com/docs/extensions/mv3/manifest/key/) to pin the extension ID across different machines. This is mainly useful when working with `web_accessible_resources`.

 #### Content script HTTP(S) requests

 * **In Firefox:** When a content script makes an HTTP(S) request, you *must* provide absolute URLs.
* **In Chrome:** When a content script makes a request (for example, using [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)) to a relative URL (like `/api`), it will be sent to `https://example.com/api`.

 #### Content script environment

 * **In Firefox:** The global scope of the [content script environment](content_scripts#content_script_environment) is not strictly equal to `window` ([Firefox bug 1208775](https://bugzil.la/1208775)). More specifically, the global scope (`globalThis`) is composed of standard JavaScript features as usual, plus `window` as the prototype of the global scope. Most DOM APIs are inherit from the page through `window`, through [Xray vision](sharing_objects_with_page_scripts#xray_vision_in_firefox) to shield the content script from modifications by the web page. Content scripts may encounter JavaScript objects from its own global scope or Xray-wrapped versions from the web page.
* **In Chrome:** The global scope is `window` and the available DOM APIs are generally independent of the web page (other than sharing the underlying DOM). Content scripts cannot directly access JavaScript objects from the web page.

 #### Executing code in web page from content script

 * **In Firefox:** [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) runs code in the context of the content script, and `window.eval` runs code in the context of the page. See [Using `eval` in content scripts](content_scripts#using_eval_in_content_scripts).
* **In Chrome:** [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) and `window.eval` always runs code in the context of the content script, not in the context of the page.

 #### Sharing variables between content scripts

 * **In Firefox:** You cannot share variables between content scripts by assigning them to `this.{variableName}` in one script and then attempting to access them using `window.{variableName}` in another. This is a limitation created by the sandbox environment in Firefox. This limitation may be removed, see [Firefox bug 1208775](https://bugzil.la/1208775).

 #### Content script lifecycle during navigation

 * **In Firefox:** Content scripts remain injected in a web page after the user has navigated away, however, window object properties are destroyed. For example, if a content script sets `window.prop1 = "prop"` and the user then navigates away and returns to the page `window.prop1` is undefined. This issue is tracked in [Firefox bug 1525400](https://bugzil.la/1525400). To mimic the behavior of Chrome, listen for the [pageshow](https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event) and [pagehide](https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event) events. Then simulate the injection or destruction of the content script.
* **In Chrome:** Content scripts are destroyed when the user navigates away from a web page. If the user then returns to the page through history, by clicking the back button, the content script is injected into the web page again.

 #### "per-tab" zoom behavior

 * **In Firefox:** The zoom level persists across page loads and navigation within the tab.
* **In Chrome:** Zoom changes are reset on navigation; navigating a tab will always load pages with their per-origin zoom factors.

 See [`tabs.ZoomSettingsScope`](api/tabs/zoomsettingsscope).


manifest.json keys
------------------



The main [`manifest.json`](manifest.json) page includes a table describing browser support for `manifest.json` keys. Where there are caveats around support for a given key, this is indicated in the table with an asterisk "\*" and in the reference page for the key, the caveats are explained.

 These tables are generated from compatibility data stored as [JSON files in GitHub](https://github.com/mdn/browser-compat-data).


Native messaging
----------------


### Connection-based messaging arguments



**On Linux and Mac:** Chrome passes one argument to the native app, which is the origin of the extension that started it, in the form: `chrome-extension://«extensionID/»` (trailing slash required). This enables the app to identify the extension.

 **On Windows:** Chrome passes two arguments:

 1. The origin of the extension
2. A handle to the Chrome native window that started the app


### allowed\_extensions


* **In Firefox:** The manifest key is called `allowed_extensions`.
* **In Chrome:** The manifest key is called `allowed_origins` instead.
### App manifest location


* **In Chrome:** The app manifest is expected in a different place. See [Native messaging host location](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location) in the Chrome docs.
### App persistance


* **In Firefox:** When a native messaging connection is closed, Firefox kills the subprocesses if they do not break away. On Windows, the browser puts the native application's process into a [Job object](https://msdn.microsoft.com/library/windows/desktop/ms684161(v=vs.85).aspx) and kills the job. Suppose the native application launches other processes and wants them to remain open after the native application is killed. In that case, the native application must use `CreateProcess`, instead of `ShellExecute`, to launch the additional process with the [`CREATE_BREAKAWAY_FROM_JOB`](https://msdn.microsoft.com/library/windows/desktop/ms684863(v=vs.85).aspx) flag.
Data cloning algorithm
----------------------



Some extension APIs allow an extension to send data from one part of the extension to another, such as [`runtime.sendMessage()`](api/runtime/sendmessage), [`tabs.sendMessage()`](api/tabs/sendmessage), [`runtime.onMessage`](api/runtime/onmessage), the `postMessage()` method of [`runtime.port`](api/runtime/port), and [`tabs.executeScript()`](api/tabs/executescript).

 * **In Firefox:** The [Structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) is used.
* **In Chrome:** The [JSON serialization algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description) is used. It may switch to structured cloning in the future ([issue 248548](https://crbug.com/248548)).

 The Structured clone algorithm supports more types than the JSON serialization algorithm. A notable exception are (DOM) objects with a `toJSON` method. DOM objects are not cloneable nor JSON-serializable by default, but with a `toJSON()` method, these can be JSON-serialized (but still not cloned with the structured cloning algorithm). Examples of JSON-serializable objects that are not structured cloneable include instances of [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) and [`PerformanceEntry`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry).

 Extension that rely on the `toJSON()` method of the JSON serialization algorithm can use [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) followed by [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) to ensure that a message can be exchanged, because a parsed JSON value is always structurally cloneable.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities>

action
======



Adds a button to the browser's toolbar.

  **Note:** This API is available in Manifest V3 or higher.

  A [browser action](../user_interface/browser_action) is a button in the browser's toolbar.

 You can associate a popup with the button. The popup is specified using HTML, CSS and JavaScript, just like a normal web page. JavaScript running in the popup gets access to all the same WebExtension APIs as your background scripts, but its global context is the popup, not the current page displayed in the browser. To affect web pages you need to communicate with them via [messages](../modify_a_web_page#messaging).

 If you specify a popup, it will be shown — and the content will be loaded — when the user clicks the icon. If you do not specify a popup, then when the user clicks the icon an event is dispatched to your extension.

 You can define most of a browser action's properties declaratively using the [`browser_action`](../manifest.json/browser_action) key in the manifest.json.

 With the `action` API, you can:

 * use [`action.onClicked`](action/onclicked) to listen for clicks on the icon.
* get and set the icon's properties — icon, title, popup, and so on. You can get and set these globally across all tabs, or for a specific tab by passing the tab ID as an additional argument.



Types
-----


 [`action.ColorArray`](action/colorarray)  An array of four integers in the range 0-255 defining an RGBA color.

  [`action.ImageDataType`](action/imagedatatype)  Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).

  Functions
---------


 [`action.setTitle()`](action/settitle)  Sets the browser action's title. This will be displayed in a tooltip.

  [`action.getTitle()`](action/gettitle)  Gets the browser action's title.

  [`action.setIcon()`](action/seticon)  Sets the browser action's icon.

  [`action.setPopup()`](action/setpopup)  Sets the HTML document to be opened as a popup when the user clicks on the browser action's icon.

  [`action.getPopup()`](action/getpopup)  Gets the HTML document set as the browser action's popup.

  [`action.openPopup()`](action/openpopup)  Open the browser action's popup.

  [`action.setBadgeText()`](action/setbadgetext)  Sets the browser action's badge text. The badge is displayed on top of the icon.

  [`action.getBadgeText()`](action/getbadgetext)  Gets the browser action's badge text.

  [`action.setBadgeBackgroundColor()`](action/setbadgebackgroundcolor)  Sets the badge's background color.

  [`action.getBadgeBackgroundColor()`](action/getbadgebackgroundcolor)  Gets the badge's background color.

  [`action.setBadgeTextColor()`](action/setbadgetextcolor)  Sets the badge's text color.

  [`action.getBadgeTextColor()`](action/getbadgetextcolor)  Gets the badge's text color.

  [`action.enable()`](action/enable)  Enables the browser action for a tab. By default, browser actions are enabled for all tabs.

  [`action.disable()`](action/disable)  Disables the browser action for a tab, meaning that it cannot be clicked when that tab is active.

  [`action.isEnabled()`](action/isenabled)  Checks whether the browser action is enabled or not.

  Events
------


 [`action.onClicked`](action/onclicked)  Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ColorArray` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `ImageDataType` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `action` | 88 | 88 | 109 | ? | 74 | 16 | ? | ? | 109 | ? | 16 | ? |
| `disable` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `enable` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `getBadgeBackgroundColor` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `getBadgeText` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `getBadgeTextColor` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |
| `getPopup` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `getTitle` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `isEnabled` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |
| `onClicked` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `openPopup` | 88 | 88 | 109User interaction is not required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)). | ? | 74 | 16 | ? | ? | 109User interaction is not required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)). | ? | 16 | ? |
| `setBadgeBackgroundColor` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `setBadgeText` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `setBadgeTextColor` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |
| `setIcon` | 88 | 88["This call is not persisted.", "The `imageData` parameter is not accepted.", "The `path` parameter is required."] | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `setPopup` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |
| `setTitle` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action>

tabs.removeCSS()
================



Removes from a page CSS which was previously injected by a call to [`tabs.insertCSS()`](insertcss).

  **Note:** When using Manifest V3 or higher, use [`scripting.insertCSS()`](../scripting/insertcss) and [`scripting.removeCSS()`](../scripting/removecss) to insert and remove CSS.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.tabs.removeCSS(
  tabId,           // optional integer
  details          // object
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab from which to remove the CSS. Defaults to the active tab of the current window.

  `details`  An object describing the CSS to remove from the page. It contains the following properties:

  
`allFrames` Optional
  `boolean`. If `true`, the code will be removed from all frames of the current page. If it is `false`, code is only removed from the top frame. Defaults to `false`.

  
`code` Optional
  `string`. CSS to remove, as a text string. This must exactly match a CSS string previously inserted into the page using [`tabs.insertCSS()`](insertcss).

  
`cssOrigin` Optional
  `string`. This can take one of two values: "user", for CSS added as a user stylesheet, or "author" for CSS added as an author stylesheet. If this option was set previously by [`tabs.insertCSS()`](insertcss), then it must exactly match.

  
`file` Optional
  `string`. Path to a file containing the CSS to remove. This must exactly match a CSS file previously inserted into the page using [`tabs.insertCSS()`](insertcss).

  
`frameId` Optional
  `integer`. The frame from which to remove the CSS. Defaults to `0` (the top-level frame).

  
`matchAboutBlank` Optional
  `boolean`. If `true`, the CSS will be removed from embedded "about:blank" and "about:srcdoc" frames if your extension has access to their parent document. Defaults to `false`.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when all the CSS has been removed. If any error occurs, the promise will be rejected with an error message.

Examples
--------



This example adds some CSS using [`tabs.insertCSS`](insertcss), then removes it again when the user clicks a browser action:

 
```
let css = "body { border: 20px dotted pink; }";

function onError(error) {
  console.log(`Error: ${error}`);
}

let insertingCSS = browser.tabs.insertCSS(2, {code: css});
insertingCSS.then(null, onError);

browser.browserAction.onClicked.addListener(() => {
  let removing = browser.tabs.removeCSS(2, {code: css});
  removing.then(null, onError);
});

```

### Example extensions


* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeCSS` | 87Available for use in Manifest V2 only. | 87Available for use in Manifest V2 only. | 49Available for use in Manifest V2 only. | ? | 73Available for use in Manifest V2 only. | 14Available for use in Manifest V2 only. | ? | ? | 54Available for use in Manifest V2 only. | ? | 15Available for use in Manifest V2 only. | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-insertCSS) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/removeCSS>

tabs.onUpdated
==============



Fired when a tab is updated.

 When the user navigates to a new URL in a tab, this typically generates several `onUpdated` events as various properties of the [`tabs.Tab`](tab) object are updated. This includes the `url`, but also potentially the `title` and `favIconUrl` properties. The `status` property will cycle through `"loading"` and `"complete"`.

 This event also fires for changes to a tab's properties that don't involve navigation, such as pinning and unpinning (which updates the `pinned` property) and muting or unmuting (which updates the `audible` and `mutedInfo` properties).

 You can filter this event, making it only fire for tabs whose URLs match specific [patterns](../../match_patterns), changes to particular properties, changes to a tab or window, or any combinations of these restrictions.



Syntax
------




```
browser.tabs.onUpdated.addListener(listener[, extraParameters])
browser.tabs.onUpdated.removeListener(listener)
browser.tabs.onUpdated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback[, extraParameters])`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  The function called when this event occurs. The function is passed these arguments:

  `tabId`  `integer`. The ID of the updated tab.

  `changeInfo`  `object`. Properties of the tab that changed. See the [changeInfo](#changeinfo_2) section for more details.

  `tab`  [`tabs.Tab`](tab). The new state of the tab.

    
`extraParameters` Optional
  `object`. A set of filters that restrict the events sent to this listener. This object can have one or more of these properties. Events are only sent if they satisfy all the filters provided.

  `urls`  `Array`. An array of [match patterns](../../match_patterns). Fires the event only for tabs whose current `url` property matches any one of the patterns.

  `properties`  `Array`. An array of strings consisting of supported [`tabs.Tab`](tab) object property names. Fires the event only for changes to one of the properties named in the array. These properties can be used:

 * "attention"
* "audible"
* "discarded"
* "favIconUrl"
* "hidden"
* "isArticle"
* "mutedInfo"
* "pinned"
* "status"
* "title"
* "url"

  **Note:** The "url" value has been supported since Firefox 88. In Firefox 87 and earlier, "url" changes can be observed by filtering by "status".

   `tabId`  `Integer`. Fires this event only for the tab identified by this ID.

  `windowId`  `Integer`. Fires this event only for tabs in the window identified by this ID.

    Additional objects
------------------


### changeInfo



Lists the changes to the state of the tab that is updated. To learn more about these properties, see the [`tabs.Tab`](tab) documentation. Note that not all [`tabs.Tab`](tab) properties are supported.

  
`attention` Optional
  `boolean`. Indicates whether the tab is drawing attention. For example, `attention` is `true` when the tab displays a modal dialog.

  
`audible` Optional
  `boolean`. The tab's new audible state.

  
`discarded` Optional
  `boolean`. Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory but is visible in the tab strip. Its content gets reloaded the next time it's activated.

  
`favIconUrl` Optional
  `string`. The tab's new favicon URL. Not included when a tab loses its favicon (navigating from a page with a favicon to a page without one). Check `favIconUrl` in [tab](#tab) instead.

  
`hidden` Optional
  `boolean`. True if the tab is [`hidden`](hide).

  
`isArticle` Optional
  `boolean`. True if the tab is an article and is therefore eligible for display in [`Reader Mode`](togglereadermode).

  
`mutedInfo` Optional
  [`tabs.MutedInfo`](mutedinfo). The tab's new muted state and the reason for the change.

  
`pinned` Optional
  `boolean`. The tab's new pinned state.

  
`status` Optional
  `string`. The status of the tab. Can be either *loading* or *complete*.

  
`title` Optional
  `string`. The tab's new title.

  
`url` Optional
  `string`. The tab's URL, if it has changed.

  
Examples
--------



Listen for and log all the change info and new state:

 
```
function handleUpdated(tabId, changeInfo, tabInfo) {
  console.log(`Updated tab: ${tabId}`);
  console.log("Changed attributes: ", changeInfo);
  console.log("New tab Info: ", tabInfo);
}

browser.tabs.onUpdated.addListener(handleUpdated);

```
 Log changes to URLs:

 
```
function handleUpdated(tabId, changeInfo, tabInfo) {
  if (changeInfo.url) {
    console.log(`Tab: ${tabId} URL changed to ${changeInfo.url}`);
  }
}

browser.tabs.onUpdated.addListener(handleUpdated);

```

### Filtering examples



Log changes only to tabs whose `url` property is [matched](../../match_patterns) by `https://developer.mozilla.org/*` or `https://twitter.com/mozdevnet`:

 
```
const pattern1 = "https://developer.mozilla.org/\*";
const pattern2 = "https://twitter.com/mozdevnet";

const filter = {
  urls: [pattern1, pattern2]
}

function handleUpdated(tabId, changeInfo, tabInfo) {
  console.log(`Updated tab: ${tabId}`);
  console.log("Changed attributes: ", changeInfo);
  console.log("New tab Info: ", tabInfo);
}

browser.tabs.onUpdated.addListener(handleUpdated, filter);

```
 Log changes only to the `pinned` property of tabs (that is, pin and unpin actions):

 
```
const filter = {
  properties: ["pinned"]
}

function handleUpdated(tabId, changeInfo, tabInfo) {
  console.log(`Updated tab: ${tabId}`);
  console.log("Changed attributes: ", changeInfo);
  console.log("New tab Info: ", tabInfo);
}

browser.tabs.onUpdated.addListener(handleUpdated, filter);

```
 Combine both the previous filters, log only when the `pinned` property of tabs changes for tabs whose `url` property is [matched](../../match_patterns) by `https://developer.mozilla.org/*` or `https://twitter.com/mozdevnet`:

 
```
const pattern1 = "https://developer.mozilla.org/\*";
const pattern2 = "https://twitter.com/mozdevnet";

const filter = {
  urls: [pattern1, pattern2],
  properties: ["pinned"]
}

function handleUpdated(tabId, changeInfo, tabInfo) {
  console.log(`Updated tab: ${tabId}`);
  console.log("Changed attributes: ", changeInfo);
  console.log("New tab Info: ", tabInfo);
}

browser.tabs.onUpdated.addListener(
  handleUpdated,
  filter);

```
 Log changes only when the `pinned` property of tabs changes for tabs whose `url` property is [matched](../../match_patterns) by `https://developer.mozilla.org/*` or `https://twitter.com/mozdevnet` where the tab was part of the current browser window when the update event fired:

 
```
const pattern1 = "https://developer.mozilla.org/\*";
const pattern2 = "https://twitter.com/mozdevnet";

const filter = {
  urls: [pattern1, pattern2],
  properties: ["pinned"],
  windowId: browser.windows.WINDOW\_ID\_CURRENT
}

function handleUpdated(tabId, changeInfo, tabInfo) {
  console.log(`Updated tab: ${tabId}`);
  console.log("Changed attributes: ", changeInfo);
  console.log("New tab Info: ", tabInfo);
}

browser.tabs.onUpdated.addListener(
  handleUpdated,
  filter);

```

### Example extensions


* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onUpdated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |
| `extraParameters` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onUpdated) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onUpdated>

tabs.detectLanguage()
=====================



Detects the primary language of the content in a tab, using the [Compact Language Detector](https://github.com/CLD2Owners/cld2) (CLD).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let detecting = browser.tabs.detectLanguage(
  tabId,                  // optional integer
  callback                // optional function
)

```
### Parameters


 
`tabId` Optional
  `integer`. Defaults to the active tab of the current window.

  
`callback` Optional
  `function`. Currently, if a `tabId` is specified, this method uses this callback to return the results instead of returning a promise. The callback receives as its only input parameter a string containing the detected language code such as `en` or `fr`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string representing an ISO language code such as `en` or `fr`. For a complete list of languages supported by this method, see [kLanguageInfoTable](https://src.chromium.org/viewvc/chrome/trunk/src/third_party/cld/languages/internal/languages.cc#l23). For an unknown language, `"und"` will be returned (but see [bug 1288263](https://bugzil.la/1288263)). If any error occurs the promise will be rejected with an error message.

Examples
--------



Detect and log the language of the active tab when the user clicks a browser action:

 
```
function onLanguageDetected(lang) {
  console.log(`Language is: ${lang}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(() => {
  browser.tabs.detectLanguage().then(onLanguageDetected, onError);
});

```
 Detect and log the language of every open tab when the user clicks a browser action (note that this example requires the "tabs" [permission](../../manifest.json/permissions)):

 
```
function onLanguageDetected(url, lang) {
  console.log(`Language in ${url} is: ${lang}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function detectLanguages(tabs) {
  for (const tab of tabs) {
    browser.tabs
      .detectLanguage(tab.id)
      .then((lang) => onLanguageDetected(tab.url, lang), onError);
  }
}

browser.browserAction.onClicked.addListener(() => {
  browser.tabs.query({}).then(detectLanguages, onError);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `detectLanguage` | 5 | 14 | 45 | ? | 15 | 14["Will return `und` (undefined language) for OS lower than 11.", "Locale identifier will include the country code more often."] | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-detectLanguage) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/detectLanguage>

alarms
======



Schedule code to run at a specific time in the future. This is like [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) and [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval), except that those functions don't work with background pages that are loaded on demand.

 Alarms do not persist across browser sessions. They are created globally across all contexts of a single extension. E.g. alarm created in background script will fire [`onAlarm`](alarms/onalarm) event in background script, options page, popup page and extension tabs (and vice versa). Alarms API is not available in [`Content scripts`](../content_scripts#webextension_apis).

 To use this API you need to have the "alarms" [permission](../manifest.json/permissions).



Types
-----


 [`alarms.Alarm`](alarms/alarm)  Information about a particular alarm.

  Methods
-------


 [`alarms.clear()`](alarms/clear)  Clear a specific alarm, given its name.

  [`alarms.clearAll()`](alarms/clearall)  Clear all scheduled alarms.

  [`alarms.create()`](alarms/create)  Create a new alarm.

  [`alarms.get()`](alarms/get)  Retrieves a specific alarm, given its name.

  [`alarms.getAll()`](alarms/getall)  Retrieve all scheduled alarms.

  Events
------


 [`alarms.onAlarm`](alarms/onalarm)  Fired when an alarm goes off.

  Example extensions
------------------


* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [dynamic-theme](https://github.com/mdn/webextensions-examples/tree/master/dynamic-theme)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Alarm` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `clear` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `clearAll` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `create` | Yes | 79 | 4545–64Alarms scheduled for a time in the past never fire. | ? | Yes | 14 | ? | ? | 4848–64Alarms scheduled for a time in the past never fire. | ? | 15 | ? |
| `get` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `getAll` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `onAlarm` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms>

browserSettings
===============



Enables an extension to modify certain global browser settings. Each property of this API is a [`BrowserSetting`](types/browsersetting) object, providing the ability to modify a particular setting.

 Because these are global settings, it's possible for extensions to conflict. See the documentation for [`BrowserSetting.set()`](types/browsersetting/set) for details of how conflicts are handled.

 To use this API you need to have the "browserSettings" [permission](../manifest.json/permissions).



Properties
----------


 [`browserSettings.allowPopupsForUserEvents`](browsersettings/allowpopupsforuserevents)  Determines whether code running in web pages can display popups in response to user events.

  [`browserSettings.cacheEnabled`](browsersettings/cacheenabled)  Determines whether the browser cache is enabled or not.

  [`browserSettings.closeTabsByDoubleClick`](browsersettings/closetabsbydoubleclick)  Determines whether the selected tab can be closed with a double click.

  [`browserSettings.colorManagement`](browsersettings/colormanagement)  Determines various settings for color management.

  [`browserSettings.contextMenuShowEvent`](browsersettings/contextmenushowevent)  Determines the mouse event that triggers a context menu popup.

  [`browserSettings.ftpProtocolEnabled`](browsersettings/ftpprotocolenabled)  Determines whether the FTP protocol is enabled.

  [`browserSettings.homepageOverride`](browsersettings/homepageoverride)  Read the value of the browser's home page.

  [`browserSettings.imageAnimationBehavior`](browsersettings/imageanimationbehavior)  Determines how the browser treats animated images.

  [`browserSettings.newTabPageOverride`](browsersettings/newtabpageoverride)  Reads the value of the browser's new tab page.

  [`browserSettings.newTabPosition`](browsersettings/newtabposition)  Controls the position of newly opened tabs relative to already open tabs.

  [`browserSettings.openBookmarksInNewTabs`](browsersettings/openbookmarksinnewtabs)  Determines whether bookmarks are opened in the current tab or a new tab.

  [`browserSettings.openSearchResultsInNewTabs`](browsersettings/opensearchresultsinnewtabs)  Determines whether search results are opened in the current tab or a new tab.

  [`browserSettings.openUrlbarResultsInNewTabs`](browsersettings/openurlbarresultsinnewtabs)  Determines whether address bar autocomplete suggestions are opened in the current tab or a new tab.

  [`browserSettings.overrideContentColorScheme`](browsersettings/overridecontentcolorscheme)  Controls whether to override the browser theme (light or dark) when setting pages' preferred color scheme.

  [`browserSettings.overrideDocumentColors`](browsersettings/overridedocumentcolors)  Controls whether the user-chosen colors override the page's colors.

  [`browserSettings.tlsVersionRestrictionConfig`](browsersettings/tlsversionrestrictionconfig)  Read the highest and lowest versions of TLS supported by the browser.

  [`browserSettings.useDocumentFonts`](browsersettings/usedocumentfonts)  Controls whether the browser will use the fonts specified by a web page or use only built-in fonts.

  [`browserSettings.webNotificationsDisabled`](browsersettings/webnotificationsdisabled)  Prevents websites from showing notifications using the [`Notification`](https://developer.mozilla.org/en-US/docs/Web/API/Notification) Web API.

  [`browserSettings.zoomFullPage`](browsersettings/zoomfullpage)  Controls whether zoom is applied to the entire page or to text only.

  [`browserSettings.zoomSiteSpecific`](browsersettings/zoomsitespecific)  Controls whether page zoom is applied on a per-site or per-tab basis. If [`privacy.websites`](privacy/websites)`.resistFingerprinting` is true, this setting has no effect and zoom is applied on a per-tab basis.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `allowPopupsForUserEvents` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `cacheEnabled` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |
| `closeTabsByDoubleClick` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |
| `colorManagement` | No | No | 91 | ? | No | No | ? | ? | 91 | ? | No | ? |
| `contextMenuShowEvent` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `ftpProtocolEnabled` | No | No | 72From version 88, this setting is read-only (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | No | ? | ? | 79From version 88, this setting is read-only (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | ? |
| `homepageOverride` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `imageAnimationBehavior` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `newTabPageOverride` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `newTabPosition` | No | No | 61 | ? | No | No | ? | ? | 61This setting can be changed but has no effect. | ? | No | ? |
| `openBookmarksInNewTabs` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `openSearchResultsInNewTabs` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `openUrlbarResultsInNewTabs` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |
| `overrideContentColorScheme` | No | No | 95 | ? | No | No | ? | ? | 95 | ? | No | ? |
| `overrideDocumentColors` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |
| `tlsVersionRestrictionConfig` | No | No | 72 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `useDocumentFonts` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |
| `webNotificationsDisabled` | No | No | 58 | ? | No | No | ? | ? | 58 | ? | No | ? |
| `zoomFullPage` | No | No | 75 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `zoomSiteSpecific` | No | No | 75 | ? | No | No | ? | ? | 79 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings>

captivePortal
=============



Determine the captive portal state of the user's connection. A captive portal is a web page displayed when a user first connects to a Wi-Fi network. The user provides information or acts on the captive portal web page to gain broader access to network resources, such as accepting terms and conditions or making a payment.

 To use this API you need to have the "captivePortal" [permission](../manifest.json/permissions).



Properties
----------


 [`captivePortal.canonicalURL`](captiveportal/canonicalurl)  Return the canonical URL of the captive-portal detection page. Read-only.

  Functions
---------


 [`captivePortal.getLastChecked()`](captiveportal/getlastchecked)  Returns the time, in milliseconds, since the last request was completed.

  [`captivePortal.getState()`](captiveportal/getstate)  Returns the portal state as one of `unknown`, `not_captive`, `unlocked_portal`, or `locked_portal`.

  Events
------


 [`captivePortal.onConnectivityAvailable`](captiveportal/onconnectivityavailable)  Fires when the captive portal service determines that the user can connect to the internet.

  [`captivePortal.onStateChanged`](captiveportal/onstatechanged)  Fires when the captive portal state changes.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `canonicalURL` | No | No | 72 | ? | No | No | ? | ? | No | ? | No | ? |
| `getLastChecked` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |
| `getState` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |
| `onConnectivityAvailable` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |
| `onStateChanged` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal>

clipboard
=========



The WebExtension `clipboard` API (which is different from the [standard Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)) enables an extension to copy items to the system clipboard. Currently the WebExtension `clipboard` API only supports copying images, but it's intended to support copying text and HTML in the future.

 The WebExtension `clipboard` API exists primarily because the standard Clipboard API [doesn't support writing images to the clipboard](https://w3c.github.io/clipboard-apis/#writing-to-clipboard). The WebExtension `clipboard` API may be deprecated once the standard Clipboard API's support for non-text clipboard contents has entered general use.

 Reading from the clipboard is not supported by this API, because the clipboard can already be read using the standard web platform APIs. See [Interacting with the clipboard](../interact_with_the_clipboard#reading_from_the_clipboard).

 This API is based on Chrome's [`clipboard`](https://developer.chrome.com/docs/extensions/reference/clipboard/) API, but that API is only available for Chrome apps, not extensions.

 To use this API you need the `"clipboardWrite"` extension [permission](../manifest.json/permissions).



Functions
---------


 [`clipboard.setImageData()`](clipboard/setimagedata)  Copy an image to the clipboard.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setImageData` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


 **Note:**

 This API is based on Chromium's [`chrome.clipboard`](https://developer.chrome.com/docs/extensions/reference/clipboard/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/clipboard>

commands
========


Listen for the user executing commands that you have registered using the [`commands` manifest.json key](../manifest.json/commands).


Types
-----


 [`commands.Command`](commands/command)  Object representing a command. This contains the information specified for the command in the [`commands` manifest.json key](../manifest.json/commands).

  Functions
---------


 [`commands.getAll`](commands/getall)  Gets all registered commands for this extension.

  [`commands.reset`](commands/reset)  Reset the given command's description and shortcut to the values given in the manifest key.

  [`commands.update`](commands/update)  Change the description or shortcut for the given command.

  Events
------


 [`commands.onCommand`](commands/oncommand)  Fired when a command is executed using its associated keyboard shortcut.

  Example extensions
------------------


* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Command` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getAll` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `onCommand` | Yes | 79 | 48Before version 63, the `onCommand` listener was not treated as a [handler for a user action](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/User_actions). | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `reset` | No | No | 60 | ? | No | No | ? | ? | No | ? | No | ? |
| `update` | No | No | 60 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:**

 This API is based on Chromium's [`chrome.commands`](https://developer.chrome.com/docs/extensions/reference/commands/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands>

bookmarks
=========



The [WebExtensions](../index) [`bookmarks`](bookmarks) API lets an extension interact with and manipulate the browser's bookmarking system. You can use it to bookmark pages, retrieve existing bookmarks, and edit, remove, and organize bookmarks.

 To use this API, an extension must request the "bookmarks" [permission](../manifest.json/permissions) in its [`manifest.json`](../manifest.json) file.

 Extensions cannot create, modify, or delete bookmarks in the root node of the bookmarks tree. Doing so causes an error with the message: "*The bookmark root cannot be modified*"



Types
-----


 [`bookmarks.BookmarkTreeNode`](bookmarks/bookmarktreenode)  Represents a bookmark or folder in the bookmarks tree.

  [`bookmarks.BookmarkTreeNodeType`](bookmarks/bookmarktreenodetype)  A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) enum which describes whether a node in the tree is a bookmark, a folder, or a separator.

  [`bookmarks.BookmarkTreeNodeUnmodifiable`](bookmarks/bookmarktreenodeunmodifiable)  A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) enum which specifies why a bookmark or folder is unmodifiable.

  [`bookmarks.CreateDetails`](bookmarks/createdetails)  Contains information which is passed to the [`bookmarks.create()`](bookmarks/create) function when creating a new bookmark.

  Functions
---------


 [`bookmarks.create()`](bookmarks/create)  Creates a bookmark or folder.

  [`bookmarks.get()`](bookmarks/get)  Retrieves one or more [`BookmarkTreeNode`](bookmarks/bookmarktreenode)s, given a bookmark's ID or an array of bookmark IDs.

  [`bookmarks.getChildren()`](bookmarks/getchildren)  Retrieves the children of the specified [`BookmarkTreeNode`](bookmarks/bookmarktreenode).

  [`bookmarks.getRecent()`](bookmarks/getrecent)  Retrieves a requested number of recently added bookmarks.

  [`bookmarks.getSubTree()`](bookmarks/getsubtree)  Retrieves part of the bookmarks tree, starting at the specified node.

  [`bookmarks.getTree()`](bookmarks/gettree)  Retrieves the entire bookmarks tree into an array of [`BookmarkTreeNode`](bookmarks/bookmarktreenode) objects.

  [`bookmarks.move()`](bookmarks/move)  Moves the specified [`BookmarkTreeNode`](bookmarks/bookmarktreenode) to a new location in the bookmark tree.

  [`bookmarks.remove()`](bookmarks/remove)  Removes a bookmark or an empty bookmark folder, given the node's ID.

  [`bookmarks.removeTree()`](bookmarks/removetree)  Recursively removes a bookmark folder; that is, given the ID of a folder node, removes that node and all its descendants.

  [`bookmarks.search()`](bookmarks/search)  Searches for [`BookmarkTreeNode`](bookmarks/bookmarktreenode)s matching a specified set of criteria.

  [`bookmarks.update()`](bookmarks/update)  Updates the title and/or URL of a bookmark, or the name of a bookmark folder, given the bookmark's ID.

  Events
------


 [`bookmarks.onCreated`](bookmarks/oncreated)  Fired when a bookmark or folder is created.

  [`bookmarks.onRemoved`](bookmarks/onremoved)  Fired when a bookmark or folder is removed. When a folder is removed recursively, a single notification is fired for the folder, and none for its contents.

  [`bookmarks.onChanged`](bookmarks/onchanged)  Fired when a bookmark or folder changes. Currently, only `title` and `url` changes trigger this.

  [`bookmarks.onMoved`](bookmarks/onmoved)  Fired when a bookmark or folder is moved to a different parent folder or to a new offset within its folder.

  [`bookmarks.onChildrenReordered`](bookmarks/onchildrenreordered)  Fired when the user has sorted the children of a folder in the browser's UI. This is not called as a result of a [`move()`](bookmarks/move).

  [`bookmarks.onImportBegan`](bookmarks/onimportbegan)  Fired when a bookmark import session is begun. Expensive observers should ignore [`bookmarks.onCreated`](bookmarks/oncreated) updates until [`bookmarks.onImportEnded`](bookmarks/onimportended) is fired. Observers should still handle other notifications immediately.

  [`bookmarks.onImportEnded`](bookmarks/onimportended)  Fired when a bookmark import session has finished.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BookmarkTreeNode` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `BookmarkTreeNodeType` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `BookmarkTreeNodeUnmodifiable` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `CreateDetails` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `create` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `get` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getChildren` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getRecent` | Yes | 79 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getSubTree` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getTree` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `move` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onChanged` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onChildrenReordered` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onCreated` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onImportBegan` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onImportEnded` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onMoved` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onRemoved` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `remove` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `removeTree` | Yes | 15 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `search` | Yes | 79 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `update` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)

  **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks>

browsingData
============



Enables extensions to clear the data that is accumulated while the user is browsing.

 In the `browsingData` API, browsing data is divided into types:

 * browser cache
* cookies
* downloads
* history
* local storage
* plugin data
* saved form data
* saved passwords

 You can use the [`browsingData.remove()`](browsingdata/remove) function to remove any combination of these types. There are also dedicated functions to remove each particular type of data, such as [`removePasswords()`](browsingdata/removepasswords), [`removeHistory()`](browsingdata/removehistory) and so on.

 All the `browsingData.remove[X]()` functions take a [`browsingData.RemovalOptions`](browsingdata/removaloptions) object, which you can use to control two further aspects of data removal:

 * how far back in time to remove data
* whether to remove data only from normal web pages, or also from hosted web apps and add-ons. Note that this option is not yet supported in Firefox.

 Finally, this API gives you a [`browsingData.settings()`](browsingdata/settings) function that gives you the current value of the settings for the browser's built-in "Clear History" feature.

 To use this API you must have the "browsingData" [API permission](../manifest.json/permissions#api_permissions).



Types
-----


 [`browsingData.DataTypeSet`](browsingdata/datatypeset)  Object used to specify the type of data to remove: for example, history, downloads, passwords, and so on.

  [`browsingData.RemovalOptions`](browsingdata/removaloptions)  Object used to specify how far back in time to remove data, and whether to remove data added through normal web browsing, by hosted apps, or by add-ons.

  Methods
-------


 [`browsingData.remove()`](browsingdata/remove)  Removes browsing data for the data types specified.

  [`browsingData.removeCache()`](browsingdata/removecache)  Clears the browser's cache.

  [`browsingData.removeCookies()`](browsingdata/removecookies)  Removes cookies.

  [`browsingData.removeDownloads()`](browsingdata/removedownloads)  Removes the list of downloaded files.

  [`browsingData.removeFormData()`](browsingdata/removeformdata)  Clears saved form data.

  [`browsingData.removeHistory()`](browsingdata/removehistory)  Clears the browser's history.

  [`browsingData.removeLocalStorage()`](browsingdata/removelocalstorage)  Clears any [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) created by websites.

  [`browsingData.removePasswords()`](browsingdata/removepasswords)  Clears saved passwords.

  [`browsingData.removePluginData()`](browsingdata/removeplugindata)  Clears data associated with plugins.

  [`browsingData.settings()`](browsingdata/settings)  Gets the current value of settings in the browser's "Clear History" feature.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 79 | 53Specifying `dataTypes.history` will also remove download history and service workers. | ? | Yes | No | ? | ? | 85Specifying `dataTypes.history` will also remove download history and service workers.57–79Specifying `dataTypes.history` will also remove download history and service workers. | ? | No | ? |
| `removeCache` | Yes | 79 | 53`removalOptions.since` is not supported. | ? | Yes | No | ? | ? | 85`removalOptions.since` is not supported.57–79`removalOptions.since` is not supported. | ? | No | ? |
| `removeCookies` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `removeDownloads` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 57–79 | ? | No | ? |
| `removeFormData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 57–79 | ? | No | ? |
| `removeHistory` | Yes | 79 | 53This function also removes download history and service workers. | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `removeLocalStorage` | Yes | 79 | 57`removalOptions.since` is not supported. | ? | Yes | No | ? | ? | 85`removalOptions.since` is not supported. | ? | No | ? |
| `removePasswords` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | ? | ? |
| `removePluginData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `settings` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |


Example extensions
------------------



* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)

  **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData>

contentScripts
==============



Use this API to register content scripts. Registering a content script instructs the browser to insert the given content scripts into pages that match the given URL patterns.

  **Note:** When using Manifest V3 or higher, use [`scripting.registerContentScripts()`](scripting/registercontentscripts) to register scripts.

  This API is very similar to the [`"content_scripts"`](../manifest.json/content_scripts) [`manifest.json`](../manifest.json) key, except that with `"content_scripts"`, the set of content scripts and associated patterns is fixed at install time. With the `contentScripts` API, an extension can register and unregister scripts at runtime.

 To use the API, call [`contentScripts.register()`](contentscripts/register) passing in an object defining the scripts to register, the URL patterns, and other options. This returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with a [`contentScripts.RegisteredContentScript`](contentscripts/registeredcontentscript) object.

 The `RegisteredContentScript` object represents the scripts that were registered in the `register()` call. It defines an `unregister()` method that you can use to unregister the content scripts. Content scripts are also unregistered automatically when the page that created them is destroyed. For example, if they are registered from the background page they will be unregistered automatically when the background page is destroyed, and if they are registered from a sidebar or a popup, they will be unregistered automatically when the sidebar or popup is closed.

 There is no `contentScripts` API permission, but an extension must have the appropriate [host permissions](../manifest.json/permissions#host_permissions) for any patterns it passes to `register()`.



Types
-----


 [`contentScripts.RegisteredContentScript`](contentscripts/registeredcontentscript)  An object of this type is returned by the [`contentScripts.register()`](contentscripts/register) function. It represents the content scripts that were registered by that call, and can be used to unregister the content script.

  Functions
---------


 [`contentScripts.register()`](contentscripts/register)  Registers the given content scripts.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RegisteredContentScript` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `register` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Example extensions
------------------


* [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts>

declarativeNetRequest
=====================


This API enables extensions to obtain information about and modify declarative rules that block or modify network requests. The use of declarative rules means that extensions don't intercept and view the content of requests, providing more privacy.


Permissions
-----------



To use this API, an extension must request the `"declarativeNetRequest"` or `"declarativeNetRequestWithHostAccess"` [permissions](../manifest.json/permissions) in its [`manifest.json`](../manifest.json) file.

 The `"declarativeNetRequest"` permission allows extensions to block and upgrade requests without any [host permissions](../manifest.json/permissions#host_permissions). Host permissions are required if the extension wants to redirect a request or modify headers on a request. The `"declarativeNetRequestWithHostAccess"` permission requires host permissions to the request URL and initiator to act on a request.

 The `"declarativeNetRequestFeedback"` permission is required to use [`getMatchedRules`](declarativenetrequest/getmatchedrules) and [`onRuleMatchedDebug`](declarativenetrequest/onrulematcheddebug) as they return information on declarative rules matched. See [Testing](#testing) for more information.


Rules
-----



The declarative rules are defined by four fields:

 * `id` – An ID that uniquely identifies a rule within a ruleset. Mandatory and should be >= 1.
* `priority` – The rule priority. When specified, it should be >= 1. Defaults to 1. See [Matching precedents](#matching_precedents) for details on how priority affects which rules are applied.
* `condition` – The [`condition`](declarativenetrequest/rulecondition) under which this rule is triggered.
* `action` – The [`action`](declarativenetrequest/ruleaction) to take when the rule is matched. Rules can do one of these things:
	+ block a network request.
	+ redirect a network request.
	+ modify headers from a network request.
	+ prevent another matching rule from being applied.

 This is an example rule that blocks all script requests originating from `"foo.com"` to any URL with `"abc"` as a substring:

 
```
{
  "id" : 1,
  "priority": 1,
  "action" : { "type" : "block" },
  "condition" : 
  {
    "urlFilter" : "abc",
    "domains" : ["foo.com"],
    "resourceTypes" : ["script"]
  }
}

```
 The `urlFilter` field of a rule condition is used to specify the pattern matched against the request URL. See [`RuleCondition`](declarativenetrequest/rulecondition) for details. Some examples of URL filters are:

 

| `urlFilter` | Matches | Does not match |
| --- | --- | --- |
| `"abc"` | https://abcd.comhttps://example.com/abcd | https://ab.com |
| `"abc*d"` | https://abcd.comhttps://example.com/abcxyzd | https://abc.com |
| `"||a.example.com"` | https://a.example.com/https://b.a.example.com/xyz | https://example.com/ |
| `"|https*"` | https://example.com | http://example.com/http://https.com |


Rulesets
--------



Rules are organized into rulesets:

 * **static rulesets**: collections of rules defined with the [`"declarative_net_request"`](../manifest.json/declarative_net_request) manifest key and stored in the extension. An extension can enable and disable static rulesets using [`updateEnabledRulesets`](declarativenetrequest/updateenabledrulesets). The set of enabled static rulesets is persisted across sessions but not across extension updates. The static rulesets enabled on extension installation and update are determined by the content of the `"declarative_net_request"` manifest key.
* **dynamic ruleset**: rules added or removed using [`updateDynamicRules`](declarativenetrequest/updatedynamicrules). These rules persist across sessions and extension updates.
* **session ruleset**: rules added or removed using [`updateSessionRules`](declarativenetrequest/updatesessionrules). These rules do not persist across browser sessions.

   **Note:** Errors and warnings about invalid static rules are only displayed during [testing](#testing). Invalid static rules in permanently installed extensions are ignored. Therefore, it's important to verify that your static rulesets are valid by testing. 

 
Limits
------


### Static ruleset limits



An extension can:

 * specify static rulesets as part of the [`"declarative_net_request"`](../manifest.json/declarative_net_request) manifest key up to the value of [`MAX_NUMBER_OF_STATIC_RULESETS`](declarativenetrequest/max_number_of_static_rulesets).
* enable static rulesets up to at least the value of [`GUARANTEED_MINIMUM_STATIC_RULES`](declarativenetrequest/guaranteed_minimum_static_rules), and the number of enabled static rulesets must not exceed the value of [[`MAX_NUMBER_OF_ENABLED_STATIC_RULESETS`](declarativenetrequest/max_number_of_enabled_static_rulesets). In addition, the number of rules in enabled static rulesets for all extensions must not exceed the global limit. Extensions shouldn't depend on the global limit having a specific value and should instead use [`getAvailableStaticRuleCount`](declarativenetrequest/getavailablestaticrulecount) to find the number of additional rules they can enable.


### Dynamic and session-scoped rules


The number of dynamic and session-scoped rules an extension can add is limited to the value of [`MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES`](declarativenetrequest/max_number_of_dynamic_and_session_rules).

Matching precedents
-------------------



When the browser evaluates how to handle requests, it checks each extension's rules that have a condition that matches the request and chooses the one to consider applying as follows:

 1. the rule priority, where 1 is the lowest priority (and rules default to 1 where priority is not set) If this doesn't result in one rule to apply:
2. the rule action, in the following order of precedence:
	1. "allow" which means any other remaining rules are ignored.
	2. "allowAllRequests" (for main\_frame and sub\_frame resourceTypes only) has the same effect as allow but also applies to future subresource loads in the document (including descendant frames) generated from the request.
	3. "block" cancels the request.
	4. "upgradeScheme" upgrades the scheme of the request.
	5. "redirect" redirects the request.
	6. "modifyHeaders" rewrites request and response headers. If this doesn't result in one rule to apply:
3. the ruleset the rule belongs to, in this order of precedence:
	1. session
	2. dynamic
	3. static If this doesn't result in one rule to apply:
4. the order of the rule in the ruleset, determined as the lowest value rule ID.

 If only one extension provides a rule for the request, that rule is applied. However, where more than one extension has a matching rule, the browser chooses the one to apply in this order of precedence:

 1. "block"
2. "redirect" and "upgradeScheme"
3. "allow" and "allowAllRequests"

 If the request was not blocked or redirected, the matching `modifyHeaders` actions are applied, as documented in [`declarativeNetRequest.ModifyHeaderInfo`](declarativenetrequest/modifyheaderinfo).


Testing
-------



[`testMatchOutcome`](declarativenetrequest/testmatchoutcome), [`getmatchedrules`](declarativenetrequest/getmatchedrules), and [`onRuleMatchedDebug`](declarativenetrequest/onrulematcheddebug) are available to assist with testing rules and rulesets. These APIs require the `"declarativeNetRequestFeedback"` [permissions](../manifest.json/permissions). In addition:

 * in Chrome, these APIs are only available to unpacked extensions.
* in Firefox, these APIs are only available after setting the `extensions.dnr.feedback` preference to `true`. Set this preference using `about:config` or the [`--pref` flag of the `web-ext` CLI tool](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#pref).


Comparison with the webRequest API
----------------------------------


* The declarativeNetRequest API evaluates network requests in the browser itself. This makes it more performant than the webRequest API, where each network request is evaluated in JavaScript in the extension process.
* Because the requests are not intercepted by the extension process, declarativeNetRequest removes the need for extensions to have a background page.
* Unlike the webRequest API, blocking or upgrading requests using the declarativeNetRequest API requires no host permissions when used with the `declarativeNetRequest` permission.
* The declarativeNetRequest API provides better privacy to users because extensions do not read the network requests made on the user's behalf.
* (Chrome only:) Unlike the webRequest API, any images or iframes blocked using the declarativeNetRequest API are automatically collapsed in the DOM.
* While deciding whether a request is to be blocked or redirected, the declarativeNetRequest API is given priority over the webRequest API because it allows for synchronous interception. Similarly, any headers removed through declarativeNetRequest API are not made visible to web request extensions.
* The webRequest API is more flexible than the declarativeNetRequest API because it allows extensions to evaluate a request programmatically.
Types
-----


 [`declarativeNetRequest.MatchedRule`](declarativenetrequest/matchedrule)  Details of a matched rule.

  [`declarativeNetRequest.ModifyHeaderInfo`](declarativenetrequest/modifyheaderinfo)  The request or response headers to modify for the request.

  [`declarativeNetRequest.Redirect`](declarativenetrequest/redirect)  Details of how the redirect should be performed. Only valid for redirect rules.

  [`declarativeNetRequest.ResourceType`](declarativenetrequest/resourcetype)  The resource type of a request.

  [`declarativeNetRequest.Rule`](declarativenetrequest/rule)  An object containing details of a rule.

  [`declarativeNetRequest.RuleAction`](declarativenetrequest/ruleaction)  An object defining the action to take if a rule is matched.

  [`declarativeNetRequest.RuleCondition`](declarativenetrequest/rulecondition)  An object defining the condition under which a rule is triggered.

  [`declarativeNetRequest.URLTransform`](declarativenetrequest/urltransform)  An object containing details of a URL transformation to perform for a redirect action.

  Properties
----------


 [`declarativeNetRequest.DYNAMIC_RULESET_ID`](declarativenetrequest/dynamic_ruleset_id)  Ruleset ID for the dynamic rules added by the extension.

  [`declarativeNetRequest.GETMATCHEDRULES_QUOTA_INTERVAL`](declarativenetrequest/getmatchedrules_quota_interval)  The time interval within which [`declarativeNetRequest.MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL`](declarativenetrequest/max_getmatchedrules_calls_per_interval) [`declarativeNetRequest.getMatchedRules`](declarativenetrequest/getmatchedrules) calls can be made.

  [`declarativeNetRequest.GUARANTEED_MINIMUM_STATIC_RULES`](declarativenetrequest/guaranteed_minimum_static_rules)  The minimum number of static rules guaranteed to an extension across its enabled static rulesets.

  [`declarativeNetRequest.MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL`](declarativenetrequest/max_getmatchedrules_calls_per_interval)  The number of times [`declarativeNetRequest.getMatchedRules`](declarativenetrequest/getmatchedrules) can be called within a period of [`declarativeNetRequest.GETMATCHEDRULES_QUOTA_INTERVAL`](declarativenetrequest/getmatchedrules_quota_interval).

  [`declarativeNetRequest.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES`](declarativenetrequest/max_number_of_dynamic_and_session_rules)  The maximum number of combined dynamic and session scoped rules an extension can add.

  [`declarativeNetRequest.MAX_NUMBER_OF_ENABLED_STATIC_RULESETS`](declarativenetrequest/max_number_of_enabled_static_rulesets)  The maximum number of static rulesets an extension can enable.

  [`declarativeNetRequest.MAX_NUMBER_OF_REGEX_RULES`](declarativenetrequest/max_number_of_regex_rules)  The maximum number of regular expression rules that an extension can add.

  [`declarativeNetRequest.MAX_NUMBER_OF_STATIC_RULESETS`](declarativenetrequest/max_number_of_static_rulesets)  The maximum number of static rulesets an extension can specify as part of the [`declarative_net_request.rule_resources`](../manifest.json/declarative_net_request) manifest key.

  [`declarativeNetRequest.SESSION_RULESET_ID`](declarativenetrequest/session_ruleset_id)  The ruleset ID for the session-scoped rules added by the extension.

  Functions
---------


 [`declarativeNetRequest.getAvailableStaticRuleCount()`](declarativenetrequest/getavailablestaticrulecount)  Returns the number of static rules an extension can enable before the global static rule limit is reached.

  [`declarativeNetRequest.getDynamicRules()`](declarativenetrequest/getdynamicrules)  Returns the set of dynamic rules for the extension.

  [`declarativeNetRequest.getEnabledRulesets()`](declarativenetrequest/getenabledrulesets)  Returns the IDs for the set of enabled static rulesets.

  [`declarativeNetRequest.getMatchedRules()`](declarativenetrequest/getmatchedrules)  Returns all the rules matched for the extension.

  [`declarativeNetRequest.getSessionRules()`](declarativenetrequest/getsessionrules)  Returns the set of session scoped rules for the extension.

  [`declarativeNetRequest.isRegexSupported()`](declarativenetrequest/isregexsupported)  Checks if a regular expression is supported as a [`declarativeNetRequest.RuleCondition`](declarativenetrequest/rulecondition)`.regexFilter` rule condition.

  [`declarativeNetRequest.setExtensionActionOptions()`](declarativenetrequest/setextensionactionoptions)  Configures how the action count for tabs are handled.

  [`declarativeNetRequest.testMatchOutcome()`](declarativenetrequest/testmatchoutcome)  Checks if any of the extension's `declarativeNetRequest` rules would match a hypothetical request.

  [`declarativeNetRequest.updateDynamicRules()`](declarativenetrequest/updatedynamicrules)  Modifies the active set of dynamic rules for the extension.

  [`declarativeNetRequest.updateEnabledRulesets()`](declarativenetrequest/updateenabledrulesets)  Updates the set of active static rulesets for the extension.

  [`declarativeNetRequest.updateSessionRules()`](declarativenetrequest/updatesessionrules)  Modifies the set of session scoped rules for the extension.

  Events
------


 [`declarativeNetRequest.onRuleMatchedDebug`](declarativenetrequest/onrulematcheddebug)  Fired when a rule is matched with a request when debugging an extension with the "declarativeNetRequestFeedback" permission.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DYNAMIC_RULESET_ID` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `GETMATCHEDRULES_QUOTA_INTERVAL` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `GUARANTEED_MINIMUM_STATIC_RULES` | 89 | 89 | No | ? | 75 | No | ? | ? | No | ? | No | ? |
| `MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES` | 90 | 90 | No | ? | 76 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `MAX_NUMBER_OF_ENABLED_STATIC_RULESETS` | 94 | 94 | No | ? | 80 | preview | ? | ? | No | ? | No | ? |
| `MAX_NUMBER_OF_REGEX_RULES` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `MAX_NUMBER_OF_STATIC_RULESETS` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `MatchedRule` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `Redirect` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `ResourceType` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `Rule` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `RuleAction` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `RuleCondition` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `SESSION_RULESET_ID` | 90 | 90 | No | ? | 76 | No | ? | ? | No | ? | No | ? |
| `URLTransform` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `getAvailableStaticRuleCount` | 89 | 89 | No | ? | 75 | No | ? | ? | No | ? | No | ? |
| `getDynamicRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `getEnabledRulesets` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `getMatchedRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `getSessionRules` | 90 | 90 | No | ? | 76 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `isRegexSupported` | 87 | 87 | No | ? | 73 | 15 | ? | ? | No | ? | 15 | ? |
| `onRuleMatchedDebug` | 84Available only to unpacked extensions. | 84Available only to unpacked extensions. | No | ? | 70Available only to unpacked extensions. | No | ? | ? | No | ? | No | ? |
| `setExtensionActionOptions` | 88 | 88 | No | ? | 74 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `testMatchOutcome` | 103 | 103 | No | ? | 89 | No | ? | ? | No | ? | No | ? |
| `updateDynamicRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `updateEnabledRulesets` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `updateSessionRules` | 90 | 90 | No | ? | 76 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest>

devtools
========



Enables extensions to interact with the browser's [Developer Tools](https://developer.mozilla.org/en-US/docs/Glossary/Developer_Tools). You can use this API to create Developer Tools pages, interact with the window that is being inspected, inspect the page network usage.

 To use this API you need to have the `"devtools"` [API permission](../manifest.json/permissions#api_permissions) specified in your [manifest.json](../manifest.json) file. This permission can not be optional.



Properties
----------


 [`devtools.inspectedWindow`](devtools/inspectedwindow)  Interact with the window that Developer tools are attached to (inspected window). This includes obtaining the tab ID for the inspected page, evaluate the code in the context of the inspected window, reload the page, or obtain the list of resources within the page.

  [`devtools.network`](devtools/network)  Obtain information about network requests associated with the window that the Developer Tools are attached to (the inspected window).

  [`devtools.panels`](devtools/panels)  Create User Interface panels that will be displayed inside User Agent Developer Tools.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |


 **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv2/devtools/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools>

dom
===


Access special extension only DOM features.


Functions
---------


 [`dom.openOrClosedShadowRoot()`](dom/openorclosedshadowroot)  Gets the open shadow root or the closed shadow root hosted by the specified element. If the shadow root isn't attached to the element, it will return `null`.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openOrClosedShadowRoot` | 88 | 88 | NoUse `element.openOrClosedShadowRoot`, available since Firefox 63. | ? | 74 | No | ? | ? | NoUse `element.openOrClosedShadowRoot`, available since Firefox 63. | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dom>

find
====



Finds text in a web page, and highlights matches.

 To use this API you need to have the "find" [permission](../manifest.json/permissions).



Functions
---------


 [`find.find()`](find/find)  Find text in a web page.

  [`find.highlightResults()`](find/highlightresults)  Highlight the last set of matches found.

  [`find.removeHighlighting()`](find/removehighlighting)  Remove any highlighting.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `find` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `highlightResults` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `removeHighlighting` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |

Example extensions
------------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find>

cookies
=======


Enables extensions to get and set cookies, and be notified when they change.


Permissions
-----------



To use this API, an add-on must specify the "cookies" [API permission](../manifest.json/permissions#api_permissions) in its [manifest.json](../manifest.json) file, along with [host permissions](../manifest.json/permissions#host_permissions) for any sites for which it wishes to access cookies. The add-on may read or write any cookies which could be read or written by a URL matching the host permissions. For example:

  `http://*.example.com/`  An add-on with this host permission may:

 * Read a non-secure cookie for `www.example.com`, with any path.
* Write a secure or non-secure cookie for `www.example.com`, with any path.

 It may *not*:

 * Read a secure cookie for `www.example.com`.

  `http://www.example.com/`  An add-on with this host permission may:

 * Read a non-secure cookie for `www.example.com`, with any path.
* Read a non-secure cookie for `.example.com`, with any path.
* Write a secure or non-secure cookie for `www.example.com` with any path.
* Write a secure or non-secure cookie for `.example.com` with any path.

 It may *not*:

 * Read or write a cookie for `foo.example.com`.
* Read or write a cookie for `foo.www.example.com`.

  `*://*.example.com/`  An add-on with this host permission may:

 * Read or write a secure or non-secure cookie for `www.example.com` with any path.

  
Tracking protection
-------------------



Trackers use third-party cookies, that is, cookies set by a website other than the one you are on, to identify the websites you visit. For example:

 1. You visit `a-shopping-site.com`, which uses `ad-tracker.com` to deliver its adverts on the web. `ad-tracker.com` sets a cookie associated with the `ad-tracker.com` domain. While you are on `a-shopping-site.com`, `ad-tracker.com` receives information about the products you browse.
2. You now visit `a-news-site.com` that uses `ad-tracker.com` to deliver adverts. `ad-tracker.com` read its cookie and use the information collected from `a-shopping-site.com` to decide which adverts to display to you.

 Firefox includes features to prevent tracking. These features separate cookies so that trackers cannot make an association between websites visited. So, in the preceding example, `ad-tracker.com` cannot see the cookie created on `a-news-site.com` when visiting `a-shopping-site.com`. The first iteration of this protection was first-party isolation which is now being superseded by [dynamic partitioning](https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#dynamic_partitioning).

  **Note:** First-party isolation and dynamic partitioning will not be active at the same time. If the user or an extension turns on first-party isolation, it takes precedence over dynamic partitioning. However, when private browsing uses dynamic partitioning, normal browsing may not be partitioning cookies. See [Status of partitioning in Firefox](https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#status_of_partitioning_in_firefox), for details.

 
### Storage partitioning



When using [dynamic partitioning](https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#dynamic_partitioning), Firefox partitions the storage accessible to JavaScript APIs by top-level site while providing appropriate access to unpartitioned storage to enable common use cases. This feature is being rolled out progressively. See [Status of partitioning in Firefox](https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#status_of_partitioning_in_firefox), for implementation details.

 Storage partitions are keyed by the schemeful URL of the top-level [website](https://developer.mozilla.org/en-US/docs/Glossary/Site) and, when dynamic partitioning is active, the key value is available through the `partitionKey.topLevelSite` property in the cookies API, for example, `partitionKey: {topLevelSite: "http://site"}`.

 Generally, top-level documents are in unpartitioned storage, while third-party iframes are in partitioned storage. If a partition key cannot be determined, the default (unpartitioned storage) is used. For example, while all HTTP(S) sites can be used as a partition key, `moz-extension:-` URLs cannot. Therefore, iframes in Firefox's extension documents do not use partitioned storage.

 By default, [`cookies.get()`](cookies/get), [`cookies.getAll()`](cookies/getall), [`cookies.set()`](cookies/set), and [`cookies.remove()`](cookies/remove) work with cookies in unpartitioned storage. To work with cookies in partitioned storage in these APIs, `topLevelSite` in `partitionKey` must be set. The exception is `getAll` where setting `partitionKey` without `topLevelSite` returns cookies in partitioned and unpartitioned storage. [`cookies.onChanged`](cookies/onchanged) fires for any cookie that the extension can access, including cookies in partitioned storage. To ensure that the correct cookie is modified, extensions should read the `cookie.partitionKey` property from the event and pass its value to [`cookies.set()`](cookies/set) and [`cookies.remove()`](cookies/remove).


### First-party isolation



When first-party isolation is on, cookies are qualified by the domain of the original page the user visited (essentially, the domain shown to the user in the URL bar, also known as the "first party domain").

 First-party isolation can be enabled by the user by adjusting the browser's configuration and set by extensions using the [`firstPartyIsolate`](privacy/websites) setting in the [`privacy`](privacy) API. Note that first-party isolation is enabled by default in [Tor Browser](https://www.torproject.org/).

 In the `cookies` API, the first party domain is represented using the `firstPartyDomain` attribute. All cookies set while first-party isolation is on have this attribute set to the domain of the original page. In the preceding example, this is `a-shopping-site.com` for one cookie and `a-news-site.com` for the other. When first-party isolation is off, all cookies set by websites have this property set to an empty string.

 The [`cookies.get()`](cookies/get), [`cookies.getAll()`](cookies/getall), [`cookies.set()`](cookies/set) and [`cookies.remove()`](cookies/remove) APIs all accept a `firstPartyDomain` option.

 When first-party isolation is on, you must provide this option or the API call will fail and return a rejected promise. For `get()`, `set()`, and `remove()` you must pass a string value. For `getAll()`, you may also pass `null` here, and this will get all cookies, whether or not they have a non-empty value for `firstPartyDomain`.

 When first-party isolation is off, the `firstPartyDomain` parameter is optional and defaults to an empty string. A non-empty string can be used to retrieve or modify first-party isolation cookies. Likewise, passing `null` as `firstPartyDomain` to `getAll()` will return all cookies.


Types
-----


 [`cookies.Cookie`](cookies/cookie)  Represents information about an HTTP cookie.

  [`cookies.CookieStore`](cookies/cookiestore)  Represents a cookie store in the browser.

  [`cookies.OnChangedCause`](cookies/onchangedcause)  Represents the reason a cookie changed.

  [`cookies.SameSiteStatus`](cookies/samesitestatus)  Represents the same-site status of the cookie.

  Methods
-------


 [`cookies.get()`](cookies/get)  Retrieves information about a single cookie.

  [`cookies.getAll()`](cookies/getall)  Retrieves all cookies that match a given set of filters.

  [`cookies.set()`](cookies/set)  Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.

  [`cookies.remove()`](cookies/remove)  Deletes a cookie by name.

  [`cookies.getAllCookieStores()`](cookies/getallcookiestores)  Lists all existing cookie stores.

  Event handlers
--------------


 [`cookies.onChanged`](cookies/onchanged)  Fired when a cookie is set or removed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Cookie` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `CookieStore` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `OnChangedCause` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `get` | Yes | 14 | 45Provides access to cookies from private browsing mode and container tabs since version 52. | ? | Yes | 14HTTPOnly cookies are not retrieved. | ? | ? | 48 | ? | 15HTTPOnly cookies are not retrieved. | ? |
| `getAll` | Yes | 14If no URL is provided, cookies are retrieved only for URLs in currently opened tabs. In Chrome, this gets all cookies on a user's machine. | 45Before version 52, the 'tabIds' list was empty and only cookies from the default cookie store were returned. From version 52 onwards, this has been fixed and the result includes cookies from private browsing mode and container tabs. | ? | Yes | 14["Only the cookies in the default cookie store are retrieved.", "HTTPOnly cookies are not retrieved."] | ? | ? | 48 | ? | 15["Only the cookies in the default cookie store are retrieved.", "HTTPOnly cookies are not retrieved."] | ? |
| `getAllCookieStores` | Yes | 14Always returns the same default cookie store with ID 0. All cookies belong to this store. | 45Before version 52, only the default cookie store was visible. From version 52 onwards, the cookie stores for private browsing mode and container tabs are also readable. | ? | Yes | 14Always returns the same default cookie store with ID 0. | ? | ? | 48 | ? | 15Always returns the same default cookie store with ID 0. | ? |
| `onChanged` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `remove` | Yes | 14 | 45Before version 56, this function did not remove cookies from private browsing mode. From version 56 onwards this is fixed. | ? | Yes | 14 | ? | ? | 48Before version 56, this function did not remove cookies from private browsing mode. From version 56 onwards this is fixed. | ? | 15 | ? |
| `sameSiteStatus` | Yes | 79 | 63 | ? | No | 14Only supports explicit. | ? | ? | 63 | ? | 15Only supports explicit. | ? |
| `set` | Yes | 14 | 45Before version 56, this function did not modify cookies in private browsing mode. From version 56 onwards this is fixed. | ? | Yes | 14 | ? | ? | 48Before version 56, this function did not modify cookies in private browsing mode. From version 56 onwards this is fixed. | ? | 15 | ? |


Example extensions
------------------



* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [list-cookies](https://github.com/mdn/webextensions-examples/tree/master/list-cookies)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies>

dns
===



Enables an extension to resolve domain names.

 To use this API, an extension must request the "dns" [permission](../manifest.json/permissions) in its [`manifest.json`](../manifest.json) file.

  **Note:** DNS will fail with NS\_ERROR\_UNKNOWN\_PROXY\_HOST if proxying DNS over socks is enabled.

 

Functions
---------


 [`dns.resolve()`](dns/resolve)  Resolves the given hostname to a DNS record.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `resolve` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns>

events
======


Common types used by APIs that dispatch events.


Types
-----


 [`events.Rule`](events/rule)  Description of a declarative rule for handling events.

  [`events.Event`](events/event)  An object which allows the addition and removal of listeners for a browser event.

  [`events.UrlFilter`](events/urlfilter)  Filters URLs for various criteria. If any of the given criteria match, then the whole filter matches.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Event` | Yes | 14 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `Rule` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `UrlFilter` | Yes | 79 | 50 | ? | Yes | 14 | ? | ? | 50 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.events`](https://developer.chrome.com/docs/extensions/reference/events/) API. This documentation is derived from [`events.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/events.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events>

extension
=========



Utilities related to your extension. Get URLs to resources packages with your extension. Get the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for your extension's pages. Get the values for various settings.

  **Note:** **The messaging APIs in this module are deprecated** in favor of the equivalent APIs in the [`runtime`](runtime) module.

 

Types
-----


 [`extension.ViewType`](extension/viewtype)  The type of extension view.

  Properties
----------


 
[`extension.lastError`](extension/lasterror)  Deprecated 
  Set for the lifetime of a callback if an asynchronous extension API has resulted in an error. If no error has occurred, `lastError` will be [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).

  [`extension.inIncognitoContext`](extension/inincognitocontext)  `True` for content scripts running inside incognito tabs, and for extension pages running inside an incognito process. (The latter only applies to extensions with '`split`' `incognito_behavior`.)

  Functions
---------


 [`extension.getBackgroundPage()`](extension/getbackgroundpage)  Returns the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for the background page running inside the current extension. Returns [`null`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null) if the extension has no background page.

  
[`extension.getExtensionTabs()`](extension/getextensiontabs)  Deprecated 
  Returns an array of the JavaScript [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) objects for each of the tabs running inside the current extension.

  
[`extension.getURL()`](extension/geturl)  Deprecated 
  Converts a relative path within an extension install directory to a fully-qualified URL.

  [`extension.getViews()`](extension/getviews)  Returns an array of the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) objects for each of the pages running inside the current extension.

  [`extension.isAllowedIncognitoAccess()`](extension/isallowedincognitoaccess)  Retrieves the state of the extension's access to Incognito-mode (as determined by the user-controlled '*Allowed in Incognito*' checkbox).

  [`extension.isAllowedFileSchemeAccess()`](extension/isallowedfileschemeaccess)  Retrieves the state of the extension's access to the `file://` scheme (as determined by the user-controlled '*Allow access to File URLs*' checkbox).

  
[`extension.sendRequest()`](extension/sendrequest)  Deprecated 
  Sends a single request to other listeners within the extension.

  [`extension.setUpdateUrlData()`](extension/setupdateurldata)  Sets the value of the ap CGI parameter used in the extension's update URL. This value is ignored for extensions that are hosted in the browser vendor's store.

  Events
------


 
[`extension.onRequest`](extension/onrequest)  Deprecated 
  Fired when a request is sent from either an extension process or a content script.

  
[`extension.onRequestExternal`](extension/onrequestexternal)  Deprecated 
  Fired when a request is sent from another extension.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ViewType` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `getBackgroundPage` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `getExtensionTabs` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `getURL` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `getViews` | Yes | 14 | 45If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then its return value will not include the extension's background page. | ? | Yes | 14 | ? | ? | 48If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then its return value will not include the extension's background page. | ? | 15 | ? |
| `inIncognitoContext` | Yes | 17 | 45 | ? | Yes | 14Always returns false. | ? | ? | 48 | ? | 15Always returns false. | ? |
| `isAllowedFileSchemeAccess` | Yes | 79 | 48 | ? | Yes | 14Always returns false. | ? | ? | 48 | ? | 15Always returns false. | ? |
| `isAllowedIncognitoAccess` | Yes | 17 | 48 | ? | Yes | 14Always returns true. | ? | ? | 48 | ? | 15Always returns true. | ? |
| `lastError` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `onRequest` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onRequestExternal` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `sendRequest` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |
| `setUpdateUrlData` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)
* [user-agent-rewriter](https://github.com/mdn/webextensions-examples/tree/master/user-agent-rewriter)

  **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension>

extensionTypes
==============


Some common types used in other WebExtension APIs.


Types
-----


 [`extensionTypes.ImageDetails`](extensiontypes/imagedetails)  Details about the format and quality of an image.

  [`extensionTypes.ImageFormat`](extensiontypes/imageformat)  The format of an image.

  [`extensionTypes.InjectDetails`](extensiontypes/injectdetails)  Injects details into a page.

  [`extensionTypes.RunAt`](extensiontypes/runat)  The soonest that the JavaScript or CSS will be injected into the tab.

  `extensionTypes.CSSOrigin`  Indicates whether a CSS stylesheet injected by [`tabs.insertCSS`](tabs/insertcss) should be treated as an "author" or "user" stylesheet.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CSSOrigin` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |
| `ImageDetails` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `ImageFormat` | YesThis feature is supported but not exposed through the 'extensionTypes' object. | 14This feature is supported but not exposed through the 'extensionTypes' object. | 45 | ? | YesThis feature is supported but not exposed through the 'extensionTypes' object. | 14This feature is supported but not exposed through the 'extensionTypes' object. | ? | ? | 48 | ? | 15This feature is supported but not exposed through the 'extensionTypes' object. | ? |
| `RunAt` | 20This feature is supported but not exposed through the 'extensionTypes' object. | 79This feature is supported but not exposed through the 'extensionTypes' object. | 45 | ? | 15This feature is supported but not exposed through the 'extensionTypes' object. | 14["This feature is supported but not exposed through the 'extensionTypes' object.", "'document\_idle' and 'document\_end' are treated the same."] | ? | ? | 48 | ? | 15["This feature is supported but not exposed through the 'extensionTypes' object.", "'document\_idle' and 'document\_end' are treated the same."] | ? |


 **Note:** This API is based on Chromium's [`chrome.extensionTypes`](https://developer.chrome.com/docs/extensions/reference/extensionTypes/) API. This documentation is derived from [`extension_types.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/extension_types.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes>

history
=======



Use the `history` API to interact with the browser history.

 If you are looking for information about the browser session history, see the [History interface](https://developer.mozilla.org/en-US/docs/Web/API/History).

  **Note:** Downloads are treated as [`HistoryItem`](history/historyitem) objects. Therefore, events such as [`history.onVisited`](history/onvisited) fire for downloads.

  Browser history is a chronological record of pages the user has visited. The history API enables you to:

 * [search for pages that appear in the browser history](history/search)
* [remove individual pages from the browser history](history/deleteurl)
* [add pages to the browser history](history/addurl)
* [remove all pages from the browser history](history/deleteall).

 However, the user may have visited a single page multiple times, so the API also has the concept of "visits". So you can also use this API to:

 * [retrieve the complete set of visits the user made to a particular page](history/getvisits)
* [remove visits to any pages made during a given time period](history/deleterange).

 To use this API, an extension must request the "history" [permission](../manifest.json/permissions) in its [`manifest.json`](../manifest.json) file.



Types
-----


 [`history.TransitionType`](history/transitiontype)  Describes how the browser navigated to a particular page.

  [`history.HistoryItem`](history/historyitem)  Provides information about a particular page in the browser history.

  [`history.VisitItem`](history/visititem)  Describes a single visit to a page.

  Functions
---------


 [`history.search()`](history/search)  Searches the browser history for [`history.HistoryItem`](history/historyitem) objects matching the given criteria.

  [`history.getVisits()`](history/getvisits)  Retrieves information about visits to a given page.

  [`history.addUrl()`](history/addurl)  Adds a record to the browser history of a visit to the given page.

  [`history.deleteUrl()`](history/deleteurl)  Removes all visits to the given URL from the browser history.

  [`history.deleteRange()`](history/deleterange)  Removes all visits to pages that the user made during the given time range.

  [`history.deleteAll()`](history/deleteall)  Removes all visits from the browser history.

  Events
------


 [`history.onTitleChanged`](history/ontitlechanged)  Fired when the title of a page visited by the user is recorded.

  [`history.onVisited`](history/onvisited)  Fired each time the user visits a page, providing the [`history.HistoryItem`](history/historyitem) data for that page.

  [`history.onVisitRemoved`](history/onvisitremoved)  Fired when a URL is removed completely from the browser history.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `HistoryItem` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `TransitionType` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `VisitItem` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `addUrl` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `deleteAll` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `deleteRange` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `deleteUrl` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getVisits` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onTitleChanged` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `onVisitRemoved` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onVisited` | Yes | 79 | 50Before version 56, the result object's 'title' was always an empty string. From version 56 onwards, it is set to the last known title, if that is available, or an empty string otherwise. | ? | Yes | No | ? | ? | No | ? | No | ? |
| `search` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)

  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history>

identity
========



Use the identity API to get an [OAuth2](https://oauth.net/2/) authorization code or access token, which an extension can then use to access user data from a service that supports OAuth2 access (such as Google or Facebook).

 OAuth2 flows vary between service provider so, to use this API with a particular service provider, consult their documentation. For example:

 * [Google](https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow)
* [GitHub](https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps)

 The identity API provides the [`identity.launchWebAuthFlow()`](identity/launchwebauthflow) function. This authenticates the user with the service, if necessary, and asks the user to authorize the extension to access data, if necessary. The function completes with an access token or authorization code, depending on the provider.

 The extension then completes the OAuth2 flow to get a validated access token, and uses the token in HTTPS requests to access the user's data according to the authorization the user gave.

 To use this API, you must have the "identity" [API permission](../manifest.json/permissions#api_permissions).



Setup
-----


There's some setup you must do before publishing your extension.

### Getting the redirect URL



The [redirect URL](https://www.oauth.com/oauth2-servers/redirect-uris/) represents the end point of [`identity.launchWebAuthFlow()`](identity/launchwebauthflow), in which the access token or authorization code is delivered to the extension. The browser extracts the result from the redirect URL without loading its response.

 You get the redirect URL by calling [`identity.getRedirectURL()`](identity/getredirecturl). This function derives a redirect URL from the add-on's ID. To simplify testing, set your add-on's ID explicitly using the [`browser_specific_settings`](../manifest.json/browser_specific_settings) key (otherwise, each time you [temporarily install the add-on](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/), you get a different redirect URL).

 [`identity.getRedirectURL()`](identity/getredirecturl) returns a URL at a fixed domain name and a subdomain derived from the add-on's ID. Some OAuth servers (such as Google) only accept domains with a verified ownership as the redirect URL. As the dummy domain cannot be controlled by extension developers, the default domain cannot always be used.

 However, loopback addresses are an accepted alternative that do not require domain validation (based on [RFC 8252, section 7.3](https://datatracker.ietf.org/doc/html/rfc8252#section-7.3)). Starting from Firefox 86, a loopback address with the format `http://127.0.0.1/mozoauth2/[subdomain of URL returned by identity.getRedirectURL()]` is permitted as a value for the redirect URL.

  **Note:** Starting with Firefox 75, you must use the redirect URL returned by [`identity.getRedirectURL()`](identity/getredirecturl). Earlier versions allowed you to supply any redirect URL.

 Starting with Firefox 86, the special loopback address described above can be used too.

  You'll use the redirect URL in two places:

 * supply it when registering your extension as an OAuth2 client.
* pass it into `identity.launchWebAuthFlow()`, as a URL parameter added to that function's `url` argument.


### Registering your extension



Before you use OAuth2 with a service provider, you must register the extension with the provider as an OAuth2 client.

 This will tend to be specific to the service provider, but in general it means creating an entry for your extension on the provider's website. In this process you supply your redirect URL, and receive a client ID (and sometimes also a secret). You need to pass both of these into [`identity.launchWebAuthFlow()`](identity/launchwebauthflow).


Functions
---------


 [`identity.getRedirectURL()`](identity/getredirecturl)  Gets the redirect URL.

  [`identity.launchWebAuthFlow()`](identity/launchwebauthflow)  Launches WAF.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getRedirectURL` | Yes | 79 | 53 | ? | 60 | No | ? | ? | No | ? | No | ? |
| `launchWebAuthFlow` | Yes | 79 | 53 | ? | Yes | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)

  **Note:** This API is based on Chromium's [`chrome.identity`](https://developer.chrome.com/docs/extensions/reference/identity/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/identity>

menus
=====



Add items to the browser's menu system.

 This API is modeled on Chrome's ["contextMenus"](https://developer.chrome.com/docs/extensions/reference/contextMenus/) API, which enables Chrome extensions to add items to the browser's context menu. The `browser.menus` API adds a few features to Chrome's API.

 Before Firefox 55 this API was also originally named `contextMenus`, and that name has been retained as an alias, so you can use `contextMenus` to write code that works in Firefox and also in other browsers.

 To use this API you need to have the `menus` [permission](../manifest.json/permissions). You may also use the `contextMenus` alias instead of `menus`, but if you do, the APIs must be accessed as `browser.contextMenus` instead.

 Except for [`menus.getTargetElement()`](menus/gettargetelement), this API cannot be used from content scripts.



Creating menu items
-------------------



To create a menu item call the [`menus.create()`](menus/create) method. You pass this method an object containing options for the item, including the item ID, item type, and the contexts in which it should be shown.

 Listen for clicks on your menu item by adding a listener to the [`menus.onClicked`](menus/onclicked) event. This listener will be passed a [`menus.OnClickData`](menus/onclickdata) object containing the event's details.

 You can create four different types of menu item, based on the value of the `type` property you supply in the options to `create()`:

 * "normal": a menu item that just displays a label
* "checkbox": a menu item that represents a binary state. It displays a checkmark next to the label. Clicking the item toggles the checkmark. The click listener will be passed two extra properties: "checked", indicating whether the item is checked now, and "wasChecked", indicating whether the item was checked before the click event.
* "radio": a menu item that represents one of a group of choices. Just like a checkbox, this also displays a checkmark next to the label, and its click listener is passed "checked" and "wasChecked". However, if you create more than one radio item, then the items function as a group of radio items: only one item in the group can be checked, and clicking an item makes it the checked item.
* "separator": a line separating a group of items.

 If you have created more than one context menu item or more than one tools menu item, then the items will be placed in a submenu. The submenu's parent will be labeled with the name of the extension. For example, here's an extension called "Menu demo" that's added two context menu items:

  ![Context menu with two items labeled click me, and click me too!] 


Icons
-----



If you've specified icons for your extension using the ["icons" manifest key](../manifest.json/icons), your menu item will display the specified icon next to its label. The browser will try to choose a 16x16 pixel icon for a normal display or a 32x32 pixel icon for a high-density display:

  ![Context menu with two items labeled click me, and click me too!] 

 Only for items in a submenu, you can specify custom icons by passing the `icons` option to [`menus.create()`](menus/create):

  ![Context menu with two items labeled click me, and click me too!. The click me option is labeled with a green paint can icon. The click me too option is labeled with a blue paint can icon.] 


Example
-------



Here's a context menu containing 4 items: a normal item, two radio items with separators on each side, and a checkbox. The radio items are given custom icons.

  ![Context menu with four items labeled remove me, Greenify, Bluify, and uncheck me. Greenify and Bluify are radio buttons given custom icons.]You could create a submenu like this using code like: 

 
```
browser.menus.create({
  id: "remove-me",
  title: browser.i18n.getMessage("menuItemRemoveMe"),
  contexts: ["all"]
}, onCreated);

browser.menus.create({
  id: "separator-1",
  type: "separator",
  contexts: ["all"]
}, onCreated);

browser.menus.create({
  id: "greenify",
  type: "radio",
  title: browser.i18n.getMessage("menuItemGreenify"),
  contexts: ["all"],
  checked: true,
  icons: {
    "16": "icons/paint-green-16.png",
    "32": "icons/paint-green-32.png"
  }
}, onCreated);

browser.menus.create({
  id: "bluify",
  type: "radio",
  title: browser.i18n.getMessage("menuItemBluify"),
  contexts: ["all"],
  checked: false,
  icons: {
    "16": "icons/paint-blue-16.png",
    "32": "icons/paint-blue-32.png"
  }
}, onCreated);

browser.menus.create({
  id: "separator-2",
  type: "separator",
  contexts: ["all"]
}, onCreated);

let checkedState = true;

browser.menus.create({
  id: "check-uncheck",
  type: "checkbox",
  title: browser.i18n.getMessage("menuItemUncheckMe"),
  contexts: ["all"],
  checked: checkedState
}, onCreated);

```

Types
-----


 [`menus.ContextType`](menus/contexttype)  The different contexts a menu can appear in.

  [`menus.ItemType`](menus/itemtype)  The type of menu item: "normal", "checkbox", "radio", "separator".

  [`menus.OnClickData`](menus/onclickdata)  Information sent when a menu item is clicked.

  Properties
----------


 [`menus.ACTION_MENU_TOP_LEVEL_LIMIT`](menus/action_menu_top_level_limit)  The maximum number of top level extension items that can be added to a menu item whose ContextType is "browser\_action" or "page\_action".

  Functions
---------


 [`menus.create()`](menus/create)  Creates a new menu item.

  [`menus.getTargetElement()`](menus/gettargetelement)  Returns the element for a given `info.targetElementId`.

  [`menus.overrideContext()`](menus/overridecontext)  Hide all default Firefox menu items in favor of providing a custom context menu UI.

  [`menus.refresh()`](menus/refresh)  Update a menu that's currently being displayed.

  [`menus.remove()`](menus/remove)  Removes a menu item.

  [`menus.removeAll()`](menus/removeall)  Removes all menu items added by this extension.

  [`menus.update()`](menus/update)  Updates a previously created menu item.

  Events
------


 [`menus.onClicked`](menus/onclicked)  Fired when a menu item is clicked.

  [`menus.onHidden`](menus/onhidden)  Fired when the browser hides a menu.

  [`menus.onShown`](menus/onshown)  Fired when the browser shows a menu.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ACTION_MENU_TOP_LEVEL_LIMIT` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `ContextType` | Yes | Yes | 55'The 'editable' context does not include password fields. Use the 'password' context for this.48 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `ItemType` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `OnClickData` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `create` | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | 5548Before version 53, items that don't specify 'contexts' do not inherit contexts from their parents. | ? | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | 14Items that don't specify 'contexts' do not inherit contexts from their parents. | ? | ? | No | ? | No | ? |
| `getTargetElement` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `onClicked` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `onHidden` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |
| `onShown` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |
| `overrideContext` | No | No | 64 | ? | No | No | ? | ? | No | ? | No | ? |
| `refresh` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |
| `remove` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `removeAll` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `update` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |

Example extensions
------------------


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.



* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)

  **Note:**

 This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus>

i18n
====



Functions to internationalize your extension. You can use these APIs to get localized strings from locale files packaged with your extension, find out the browser's current language, and find out the value of its [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#the_accept-language_header).

 See the [Internationalization](../internationalization) page for a guide on using this API.



Types
-----


 [`i18n.LanguageCode`](i18n/languagecode)  A [language tag](https://www.rfc-editor.org/rfc/rfc9110.html#name-language-tags) such as `"en-US"` or "`fr`".

  Functions
---------


 [`i18n.getAcceptLanguages()`](i18n/getacceptlanguages)  Gets the [accept-languages](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#the_accept-language_header) of the browser. This is different from the locale used by the browser. To get the locale, use [`i18n.getUILanguage`](i18n/getuilanguage).

  [`i18n.getMessage()`](i18n/getmessage)  Gets the localized string for the specified message.

  [`i18n.getUILanguage()`](i18n/getuilanguage)  Gets the UI language of the browser. This is different from [`i18n.getAcceptLanguages`](i18n/getacceptlanguages) which returns the preferred user languages.

  [`i18n.detectLanguage()`](i18n/detectlanguage)  Detects the language of the provided text using the [Compact Language Detector](https://github.com/CLD2Owners/cld2).

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `LanguageCode` | 47 | 14 | 45 | ? | 34 | No | ? | ? | 48 | ? | No | ? |
| `detectLanguage` | 47 | 79 | 47 | ? | 34 | No | ? | ? | 10648–106The method existed but always threw an error. | ? | No | ? |
| `getAcceptLanguages` | 47 | 14 | 47 | ? | 34 | 14 | ? | ? | 48 | ? | 15 | ? |
| `getMessage` | 17 | 14["Throws an exception instead returning an empty string if the message does not exist.", "Expects substitutions to be strings, while other browsers allow any value which is then converted to a string."] | 45Firefox 47 and earlier returns "??" instead of "" if the message is not found in \_locales, [bug 1258199](https://bugzil.la/1258199) changed this act to match Chrome, landed on Firefox 48. | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `getUILanguage` | 35 | 14 | 47Firefox 55 and earlier returns a language tag that's separated with the underscore character instead of hyphen, see [bug 1374552](https://bugzil.la/1374552). | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


Example extensions
------------------



* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)

  **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 
See also
--------


* [Internationalization](../internationalization): a guide to using the WebExtension i18n system.
* [Locale-Specific Message reference](i18n/locale-specific_message_reference): extensions supply locale-specific strings in files called `messages.json`. This page describes the format of `messages.json`.


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n>

idle
====



Find out when the user's system is idle, locked, or active.

 To use this API you need to have the "idle" [permission](../manifest.json/permissions).



Types
-----


 [`idle.IdleState`](idle/idlestate)  String describing the device's idle state.

  Functions
---------


 [`idle.queryState()`](idle/querystate)  Returns `"locked"` if the system is locked, `"idle"` if the user has not generated any input for a specified number of seconds, or `"active"` otherwise.

  [`idle.setDetectionInterval()`](idle/setdetectioninterval)  Sets the interval used to determine when the system is in an idle state for [`idle.onStateChanged`](idle/onstatechanged) events.

  Events
------


 [`idle.onStateChanged`](idle/onstatechanged)  Fired when the system changes state.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `IdleState` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `onStateChanged` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `queryState` | Yes | 15 | 45Before version 51, Firefox always reports 'active'. After version 51, Firefox reports 'active' or 'idle' as appropriate. | ? | Yes | No | ? | ? | 48Before version 51, Firefox always reports 'active'. After version 51, Firefox reports 'active' or 'idle' as appropriate. | ? | No | ? |
| `setDetectionInterval` | Yes | 15 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/) API. This documentation is derived from [`idle.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/idle.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle>

management
==========



Get information about installed add-ons.

 With the `management` API you can:

 * get information about installed add-ons
* enable/disable add-ons
* uninstall add-ons
* find out which permission warnings are given for particular add-ons or manifests
* get notifications of add-ons being installed, uninstalled, enabled, or disabled.

 Most of these operations require the "management" [API permission](../manifest.json/permissions). Operations that don't provide access to other add-ons don't require this permission.



Types
-----


 [`management.ExtensionInfo`](management/extensioninfo)  An object that contains information about an installed add-on.

  Functions
---------


 [`management.getAll()`](management/getall)  Returns information about all installed add-ons.

  [`management.get()`](management/get)  Returns information about a particular add-on, given its ID.

  [`management.getSelf()`](management/getself)  Returns information about the calling add-on.

  [`management.install()`](management/install)  Installs a particular theme, given its URL at [addons.mozilla.org](https://addons.mozilla.org).

  [`management.uninstall()`](management/uninstall)  Uninstalls a particular add-on, given its ID.

  [`management.uninstallSelf()`](management/uninstallself)  Uninstalls the calling add-on.

  [`management.getPermissionWarningsById()`](management/getpermissionwarningsbyid)  Get the set of permission warnings for a particular add-on, given its ID.

  [`management.getPermissionWarningsByManifest()`](management/getpermissionwarningsbymanifest)  Get the set of permission warnings that would be displayed for the given manifest string.

  [`management.setEnabled()`](management/setenabled)  Enable/disable a particular add-on, given its ID.

  Events
------


 [`management.onInstalled`](management/oninstalled)  Fired when an add-on is installed.

  [`management.onUninstalled`](management/onuninstalled)  Fired when an add-on is uninstalled.

  [`management.onEnabled`](management/onenabled)  Fired when an add-on is enabled.

  [`management.onDisabled`](management/ondisabled)  Fired when an add-on is disabled.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ExtensionInfo` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `get` | Yes | 79 | 56 | ? | Yes | No | ? | ? | 56 | ? | No | ? |
| `getAll` | Yes | 79 | 55Before version 56, only extensions whose 'type' is 'theme' are returned. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose 'type' is 'theme' are returned. | ? | No | ? |
| `getPermissionWarningsById` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getPermissionWarningsByManifest` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getSelf` | Yes | 79 | 51 | ? | No | No | ? | ? | 51 | ? | No | ? |
| `install` | No | No | 63The installable file pointed to by `url` must be a [theme](https://developer.mozilla.org/docs/Mozilla/Add-ons/Themes), and not a normal browser extension. | ? | No | No | ? | ? | 63The installable file pointed to by `url` must be a [theme](https://developer.mozilla.org/docs/Mozilla/Add-ons/Themes), and not a normal browser extension. | ? | No | ? |
| `onDisabled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |
| `onEnabled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |
| `onInstalled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |
| `onUninstalled` | Yes | 79 | 55["Before version 56, only extensions whose `type` is `'theme'` are supported.", "This event is not fired when the extension is in the \"pending uninstall\" state. The event is fired as expected once the extension is completely removed (for example, when the `about:addons` tab is closed)."] | ? | Yes | No | ? | ? | 55["Before version 56, only extensions whose `type` is `'theme'` are supported.", "This event is not fired when the extension is in the \"pending uninstall\" state. The event is fired as expected once the extension is completely removed (for example, when the `about:addons` tab is closed)."] | ? | No | ? |
| `setEnabled` | Yes | 79 | 55Only extensions whose 'type' is 'theme' can be enabled and disabled. | ? | Yes | No | ? | ? | 55Only extensions whose 'type' is 'theme' can be enabled and disabled. | ? | No | ? |
| `uninstall` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `uninstallSelf` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |


Example extensions
------------------



* [theme-switcher](https://github.com/mdn/webextensions-examples/tree/master/theme-switcher)

  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management>

notifications
=============



Display notifications to the user, using the underlying operating system's notification mechanism. Because this API uses the operating system's notification mechanism, the details of how notifications appear and behave may differ according to the operating system and the user's settings.

 To use this API you need to have the "notifications" [permission](../manifest.json/permissions).

 The notification looks the same on all desktop operating systems. Something like:

  ![Example notification with a bold title and regular text] 



Types
-----


 [`notifications.NotificationOptions`](notifications/notificationoptions)  Defines the content of a notification.

  [`notifications.TemplateType`](notifications/templatetype)  The type of notification. For example, this defines whether the notification can contain an image.

  Functions
---------


 [`notifications.clear()`](notifications/clear)  Clear a specific notification, given its ID.

  [`notifications.create()`](notifications/create)  Create and display a new notification.

  [`notifications.getAll()`](notifications/getall)  Get all notifications.

  [`notifications.update()`](notifications/update)  Update a notification.

  Events
------


 [`notifications.onButtonClicked`](notifications/onbuttonclicked)  Fired when the user clicked a button in the notification.

  [`notifications.onClicked`](notifications/onclicked)  Fired when the user clicked the notification, but not on a button.

  [`notifications.onClosed`](notifications/onclosed)  Fired when a notification closed, either by the system or because the user dismissed it.

  [`notifications.onShown`](notifications/onshown)  Fired immediately after a notification has been shown.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `NotificationOptions` | Yes | 17 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `TemplateType` | Yes | 17 | 45Only the 'basic' type is supported. | ? | YesOnly the 'basic' type is supported. | No | ? | ? | 48Only the 'basic' type is supported. | ? | No | ? |
| `clear` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `create` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `getAll` | 29 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `onButtonClicked` | 28 | 17 | No | ? | 25 | No | ? | ? | No | ? | No | ? |
| `onClicked` | 28 | 17 | 47 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `onClosed` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `onShown` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |
| `update` | 28 | 17 | No | ? | 25Not supported on macOS. | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)

  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications>

omnibox
=======



Enables extensions to implement customized behavior when the user types into the browser's address bar.

 When the user focuses the browser's address bar and starts typing, the browser displays a drop-down list containing suggested pages based on what they typed. This gives the user a quick way to access, for example, pages from their history or bookmarks.

 The omnibox API provides the extension a way to customize the suggestions displayed in the drop-down, when the user enters a keyword defined by the extension. It works as follows:

 1. First, the extension must include an "[omnibox](../manifest.json/omnibox)" key in its [manifest.json](../manifest.json) file, which defines a keyword.
2. When the user focuses the address bar and types the keyword followed by a space, the extension gets an [`omnibox.onInputStarted`](omnibox/oninputstarted) event.
3. Optionally, the extension can call [`omnibox.setDefaultSuggestion()`](omnibox/setdefaultsuggestion) to define the first suggestion displayed in the address bar drop-down.
4. As the user continues to type characters, the extension gets [`omnibox.onInputChanged`](omnibox/oninputchanged) events. The event listener is passed the value the user has typed and can populate the address bar drop-down with suggestions. If the extension sets a default suggestion using [`omnibox.setDefaultSuggestion()`](omnibox/setdefaultsuggestion), this suggestion is displayed first in the drop-down.
5. If the user accepts a suggestion, the extension gets an [`omnibox.onInputEntered`](omnibox/oninputentered) event. The event listener is passed the accepted suggestion.
6. If the user deletes a suggestion, the extension gets an [`omnibox.onDeleteSuggestion`](omnibox/ondeletesuggestion) event.
7. If the user dismisses the drop-down, the extension gets an [`omnibox.onInputCancelled`](omnibox/oninputcancelled) event.



Types
-----


 [`omnibox.OnInputEnteredDisposition`](omnibox/oninputentereddisposition)  Describes the recommended method to handle the selected suggestion: open in the current tab, open in a new foreground tab, or open in a new background tab.

  [`omnibox.SuggestResult`](omnibox/suggestresult)  An object representing a suggestion to add to the address bar drop-down.

  Functions
---------


 [`omnibox.setDefaultSuggestion()`](omnibox/setdefaultsuggestion)  Defines the first suggestion displayed in the drop-down when the user enters your extension's keyword followed by a space.

  Events
------


 [`omnibox.onDeleteSuggestion`](omnibox/ondeletesuggestion)  Fired whenever the user deletes a suggestion.

  [`omnibox.onInputStarted`](omnibox/oninputstarted)  Fired when the user focuses the address bar and types your extension's omnibox keyword, followed by a space.

  [`omnibox.onInputChanged`](omnibox/oninputchanged)  Fired whenever the user's input changes after they have focused the address bar and typed your extension's keyword followed by a space.

  [`omnibox.onInputEntered`](omnibox/oninputentered)  Fired when the user accepts one of your extension's suggestions.

  [`omnibox.onInputCancelled`](omnibox/oninputcancelled)  Fired when the user dismisses the address bar drop-down after they have focused the address bar and typed your extension's keyword followed by a space.

  Example extensions
------------------


* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnInputEnteredDisposition` | 44 | 79 | 52 | ? | 31 | No | ? | ? | No | ? | No | ? |
| `SuggestResult` | 9 | 79 | 52'description' is interpreted as plain text, and XML markup is not recognized. | ? | 15 | No | ? | ? | No | ? | No | ? |
| `onDeleteSuggestion` | 63 | 79 | 109 | ? | 50 | No | ? | ? | No | ? | No | ? |
| `onInputCancelled` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `onInputChanged` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `onInputEntered` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `onInputStarted` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `setDefaultSuggestion` | 9 | 79 | 52'description' is interpreted as plain text, and XML markup is not recognized. | ? | 15 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox>

pkcs11
======



The `pkcs11` API enables an extension to enumerate [PKCS #11](https://en.wikipedia.org/wiki/PKCS_11) security modules and to make them accessible to the browser as sources of keys and certificates.

 To use this API you need to have the "pkcs11" [permission](../manifest.json/permissions).



Using the Firefox Preferences Dialog to Install PKCS #11 Modules
----------------------------------------------------------------



Perform the following steps:

 1. Save the PKCS #11 module to a permanent location on your local computer
2. Select **Tools > Options** or select the **Firefox menu** and then **Options**
3. Once the Options page opens, select **Privacy & Security**
4. Scroll down to the bottom of the page and under **Certificates** click or tap on **Security Devices…** ![Security modules and devices]
5. Click or tap the **Load** button ![Load PKCS#11 device driver]
6. Enter a name for the security module, such as "*My Client Database*"  **Warning:** Be careful about using international characters as there is currently a bug in Firefox where international characters may cause problems.
7. Choose **Browse…** to find the location of the PKCS #11 module on your local computer, and then click or tap **OK** to confirm.


Provisioning PKCS #11 modules
-----------------------------



 **Note:** Starting with Firefox 58, extensions can use this API to enumerate PKCS #11 modules and make them accessible to the browser as sources of keys and certificates.

  There are two environmental prerequisites for using this **API**:

 * One or more `PKCS #11` modules must be installed on the user's computer
* For each installed `PKCS #11` module, there must be a [native manifest](../native_manifests) file that enables the browser to locate the module.

 Most probably, the user or device administrator would install the `PKCS #11` module, and its installer would install the native manifest file at the same time.

 However, the module and manifest can't be installed as part of the extension's own installation process.

 For details about the manifest file's contents and location, see [Native manifests](../native_manifests).


Functions
---------


 [`pkcs11.getModuleSlots()`](pkcs11/getmoduleslots)  For each slot in a module, get its name and whether it contains a token.

  [`pkcs11.installModule()`](pkcs11/installmodule)  Installs the named PKCS #11 module.

  [`pkcs11.isModuleInstalled()`](pkcs11/ismoduleinstalled)  Checks whether the named PKCS #11 module is installed.

  [`pkcs11.uninstallModule()`](pkcs11/uninstallmodule)  Uninstalls the named PKCS #11 module.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getModuleSlots` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `installModule` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `isModuleInstalled` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `uninstallModule` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11>

privacy
=======



Access and modify various privacy-related browser settings.

 To use the privacy API, you must have the "privacy" [API permission](../manifest.json/permissions#api_permissions).



Properties
----------


 [`privacy.network`](privacy/network)  Access and modify privacy settings relating to the network.

  [`privacy.services`](privacy/services)  Access and modify privacy settings relating to the services provided by the browser or third parties.

  [`privacy.websites`](privacy/websites)  Access and modify privacy settings relating to the behavior of websites.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |


 **Note:** This API is based on Chromium's [`chrome.privacy`](https://developer.chrome.com/docs/extensions/reference/privacy/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy>

scripting
=========



Inserts JavaScript and CSS into websites. This API offers two approaches to inserting content:

 * [`scripting.executeScript()`](scripting/executescript), [`scripting.insertCSS()`](scripting/insertcss), and [`scripting.removeCSS()`](scripting/removecss) that provide for one-off injections.
* [`scripting.registerContentScripts()`](scripting/registercontentscripts) that registers content scripts dynamically, which can then be retrieved with [`scripting.getRegisteredContentScripts()`](scripting/getregisteredcontentscripts) and unregistered with [`scripting.unregisterContentScripts()`](scripting/unregistercontentscripts)).

  **Note:** Chrome restricts this API to Manifest V3. Firefox and Safari support this API in Manifest V2 and V3.

  This API requires the `"scripting"` [permission](../manifest.json/permissions) and [host permission](../manifest.json/permissions#host_permissions) for the target in the tab into which JavaScript or CSS is injected.

 Alternatively, you can get permission temporarily in the active tab and only in response to an explicit user action, by asking for the [`"activeTab"` permission](../manifest.json/permissions#activetab_permission). However, the `"scripting"` permission is still required.



Types
-----


 [`scripting.ContentScriptFilter`](scripting/contentscriptfilter)  Specifies the IDs of scripts to retrieve with [`scripting.getRegisteredContentScripts()`](scripting/getregisteredcontentscripts) or to unregister with [`scripting.unregisterContentScripts()`](scripting/unregistercontentscripts).

  [`scripting.ExecutionWorld`](scripting/executionworld)  Specifies the execution environment of a script injected with [`scripting.executeScript()`](scripting/executescript) or registered with [`scripting.registerContentScripts()`](scripting/registercontentscripts).

  [`scripting.InjectionTarget`](scripting/injectiontarget)  Details of an injection target.

  [`scripting.RegisteredContentScript`](scripting/registeredcontentscript)  Details of a content script to be registered or that is registered.

  Functions
---------


 [`scripting.executeScript()`](scripting/executescript)  Injects JavaScript code into a page.

  [`scripting.getRegisteredContentScripts()`](scripting/getregisteredcontentscripts)  Gets a list of registered content scripts.

  [`scripting.insertCSS()`](scripting/insertcss)  Injects CSS into a page.

  [`scripting.registerContentScripts()`](scripting/registercontentscripts)  Registers a content script for future page loads.

  [`scripting.removeCSS()`](scripting/removecss)  Removes CSS which was previously injected into a page by a [`scripting.insertCSS()`](scripting/insertcss) call.

  [`scripting.updateContentScripts()`](scripting/updatecontentscripts)  Updates one or more content scripts already registered.

  [`scripting.unregisterContentScripts()`](scripting/unregistercontentscripts)  Unregisters one or more content scripts.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ExecutionWorld` | 102 | 102 | 102 | ? | 88 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `InjectionTarget` | 88 | 88 | 102 | ? | 74 | 15.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 15.4Available for use in Manifest V2 or later. | ? |
| `RegisteredContentScript` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `scripting` | 88Available for use in Manifest V3 or later. | 88Available for use in Manifest V3 or later. | 102 | ? | 74Available for use in Manifest V3 or later. | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `executeScript` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `getRegisteredContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `insertCSS` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `registerContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `removeCSS` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `unregisterContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `updateContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting>

search
======



Use the search API to retrieve the installed search engines and execute searches.

 To use this API you need to have the `"search"` [permission](../manifest.json/permissions).

 When choosing between `search.query()` and `search.search()`, consider the following:

 * [`search.query()`](search/query) is available in most major browsers, making it ideal for use in cross-browser extensions. However, it can only issue searches against the browser's default search engine.
* [`search.search()`](search/search) is available only in Firefox. However, it has the advantage of being able to issue a search against any search engine installed in the browser.



Functions
---------


 [`search.get()`](search/get)  Retrieve all search engines.

  [`search.query()`](search/query)  Search using the browser's default search engine.

  [`search.search()`](search/search)  Search using a specified search engine.

  Example extensions
------------------


* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `query` | 87 | 87 | 111 | ? | 73 | No | ? | ? | No | ? | No | ? |
| `search` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/search>

sessions
========



Use the sessions API to list, and restore, tabs and windows that have been closed while the browser has been running.

 The [`sessions.getRecentlyClosed()`](sessions/getrecentlyclosed) function returns an array of [`tabs.Tab`](tabs/tab) and [`windows.Window`](windows/window) objects, representing tabs and windows that have been closed since the browser was running, up to the maximum defined in [`sessions.MAX_SESSION_RESULTS`](sessions/max_session_results).

 You can then restore a window or tab using the [`sessions.restore()`](sessions/restore) function. Restoring doesn't just reopen the tab: it also restores the tab's navigation history so the back/forward buttons will work.

 This API also provides a group of functions that enable an extension to store additional state associated with a tab or a window. Then, if the tab or window is closed and subsequently restored, the extension can retrieve the state. For example, a tab grouping extension might use this to remember which group a tab is in, so as to restore it into the right group if the user restores the tab.

 To use the sessions API you must have the "sessions" [API permission](../manifest.json/permissions#api_permissions).



Types
-----


 [`sessions.Filter`](sessions/filter)  Enables you to restrict the number of [`Session`](sessions/session) objects returned by a call to [`sessions.getRecentlyClosed()`](sessions/getrecentlyclosed).

  [`sessions.Session`](sessions/session)  Represents a tab or window that the user has closed in the current browsing session.

  Properties
----------


 [`sessions.MAX_SESSION_RESULTS`](sessions/max_session_results)  The maximum number of sessions that will be returned by a call to [`sessions.getRecentlyClosed()`](sessions/getrecentlyclosed).

  Functions
---------


 [`sessions.forgetClosedTab()`](sessions/forgetclosedtab)  Removes a closed tab from the browser's list of recently closed tabs.

  [`sessions.forgetClosedWindow()`](sessions/forgetclosedwindow)  Removes a closed window from the browser's list of recently closed windows.

  [`sessions.getRecentlyClosed()`](sessions/getrecentlyclosed)  Returns an array of [`Session`](sessions/session) objects, representing windows and tabs that were closed in the current browsing session (that is: the time since the browser was started).

  [`sessions.restore()`](sessions/restore)  Restores a closed tab or window.

  [`sessions.setTabValue()`](sessions/settabvalue)  Store a key/value pair associated with a given tab.

  [`sessions.getTabValue()`](sessions/gettabvalue)  Retrieve a previously stored value for a given tab, given its key.

  [`sessions.removeTabValue()`](sessions/removetabvalue)  Remove a key/value pair from a given tab.

  [`sessions.setWindowValue()`](sessions/setwindowvalue)  Store a key/value pair associated with a given window.

  [`sessions.getWindowValue()`](sessions/getwindowvalue)  Retrieve a previously stored value for a given window, given its key.

  [`sessions.removeWindowValue()`](sessions/removewindowvalue)  Remove a key/value pair from a given window.

  Events
------


 [`sessions.onChanged`](sessions/onchanged)  Fired when a tab or window is closed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Filter` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `MAX_SESSION_RESULTS` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `Session` | Yes | 79 | 52'Tab' objects in Sessions don't contain the 'url', 'title', or 'favIconUrl' properties. | ? | Yes | No | ? | ? | No | ? | No | ? |
| `forgetClosedTab` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `forgetClosedWindow` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `getRecentlyClosed` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `getWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `onChanged` | Yes | 79 | 53 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `removeTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `removeWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `restore` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `setTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `setWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)

  **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions>

sidebarAction
=============



Gets and sets properties of an extension's sidebar.

 A [sidebar](../user_interface/sidebars) is a pane that is displayed at the left-hand or right-hand side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display. Using the [`sidebar_action`](../manifest.json/sidebar_action) manifest.json key, an extension can define its own sidebar. Using the `sidebarAction` API described here, an extension can get and set the sidebar's properties.

 The `sidebarAction` API is closely modeled on the [`browserAction`](browseraction) API.

 The sidebarAction API is based on Opera's [sidebarAction API](https://dev.opera.com/extensions/sidebar-action-api/). However, note that the following are not yet supported: `setBadgeText()`, `getBadgeText()`, `setBadgeBackgroundColor()`, `getBadgeBackgroundColor()`, `onFocus`, `onBlur`.



Types
-----


 [`sidebarAction.ImageDataType`](sidebaraction/imagedatatype)  Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).

  Functions
---------


 [`sidebarAction.close()`](sidebaraction/close)  Closes the sidebar.

  [`sidebarAction.getPanel()`](sidebaraction/getpanel)  Gets the sidebar's panel.

  [`sidebarAction.getTitle()`](sidebaraction/gettitle)  Gets the sidebar's title.

  [`sidebarAction.isOpen()`](sidebaraction/isopen)  Checks whether the sidebar is open or not.

  [`sidebarAction.open()`](sidebaraction/open)  Opens the sidebar.

  [`sidebarAction.setIcon()`](sidebaraction/seticon)  Sets the sidebar's icon.

  [`sidebarAction.setPanel()`](sidebaraction/setpanel)  Sets the sidebar's panel.

  [`sidebarAction.setTitle()`](sidebaraction/settitle)  Sets the sidebar's title. This will be displayed in any UI provided by the browser to list sidebars, such as a menu.

  [`sidebarAction.toggle()`](sidebaraction/toggle)  Toggles the visibility of the sidebar.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `close` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `getBadgeBackgroundColor` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `getBadgeText` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `getPanel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `getTitle` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `isOpen` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `onBlur` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `onFocus` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `open` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `setBadgeBackgroundColor` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `setBadgeText` | No | No | No | ? | 30 | No | ? | ? | No | ? | No | ? |
| `setIcon` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `setPanel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `setTitle` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `toggle` | No | No | 73 | ? | No | No | ? | ? | No | ? | No | ? |


Example add-ons
---------------



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)

  **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction>

proxy
=====



Use the proxy API to proxy web requests. You can use the [`proxy.onRequest`](proxy/onrequest) event listener to intercept web requests, and return an object that describes whether and how to proxy them.

 The advantage of the [`proxy.onRequest`](proxy/onrequest) approach is that the code that implements your proxy policy runs in your extension's background script, so it gets full access to the WebExtension APIs available to your extension (including, for example, access to your extension's [`storage`](storage) and networking APIs like [`dns`](dns)).

 Apart from this API, extensions can also use the [`browserSettings.proxyConfig`](proxy/settings) property to configure global proxy settings.

 Google Chrome provides [an extension API also called "proxy"](https://developer.chrome.com/docs/extensions/reference/proxy/) which is functionally similar to this API, in that extensions can use it to implement a proxying policy. However, the design of the Chrome API is completely different to this API. Because this API is incompatible with the Chrome `proxy` API, this API is only available through the `browser` namespace.

 To use this API you need to have the "proxy" [permission](../manifest.json/permissions). Also, where you want to intercept requests, you also need [host permission](../manifest.json/permissions#host_permissions) for the URLs of intercepted requests.

  **Note:** The "proxy" permission requires `"strict_min_version"` to be set to "91.1.0" or above. To use this permission, add or update the [`"browser_specific_settings"`](../manifest.json/browser_specific_settings) key in your [manifest.json](../manifest.json) to specify a minimum Firefox version. See [Securing the proxy API for Firefox add-ons](https://blog.mozilla.org/security/2021/10/25/securing-the-proxy-api-for-firefox-add-ons/) for more information.

   **Note:** The browser can make speculative connections, where it determines that a request to a URI may be coming soon. This type of connection does not provide valid tab information, so request details such as `tabId`, `frameId`, `parentFrameId`, etc. are inaccurate. These connections have a [`webRequest.ResourceType`](webrequest/resourcetype) of `speculative`.

 

Types
-----


 [`proxy.ProxyInfo`](proxy/proxyinfo)  Describes a proxy.

  [`proxy.RequestDetails`](proxy/requestdetails)  Contains information about a web request that the browser is about to make.

  Properties
----------


 [`proxy.settings`](proxy/settings)  Get and set proxy settings.

  Functions
---------



 **Warning:** You should not use these methods ([`proxy.register()`](proxy/register) or [`proxy.unregister()`](proxy/unregister)) to register and remove an extended [Proxy Auto-Configuration (PAC) file](proxy/register#pac_file_specification). They were deprecated in Firefox 68 and removed in Firefox 71.

   
[`proxy.register()`](proxy/register)  Deprecated 
  Registers the given proxy script.

  
[`proxy.unregister()`](proxy/unregister)  Deprecated 
  Unregisters the proxy script.

  
Events
------


 [`proxy.onError`](proxy/onerror)  Fired when the system encounters an error running the PAC script or the `onRequest` listener.

  [`proxy.onRequest`](proxy/onrequest)  Fired when a web request is about to be made, giving the extension an opportunity to proxy it.

  Example extensions
------------------


* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ProxyInfo` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `RequestDetails` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `onError` | No | No | 6055–71 | ? | No | No | ? | ? | 6055 | ? | No | ? |
| `onRequest` | No | No | 60Before version 78, the `tabId` and `windowId` filter properties are ignored. | ? | No | No | ? | ? | 60 | ? | No | ? |
| `register` | No | No | 56–7155–71 | ? | No | No | ? | ? | 56–7955–79 | ? | No | ? |
| `settings` | No | No | 60From version 88, the `ftp` setting has no effect because FTP is no longer supported (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | No | ? | ? | No | ? | No | ? |
| `unregister` | No | No | 56–71 | ? | No | No | ? | ? | 56–79 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy>

theme
=====



Enables browser extensions to update the browser theme.

 To use this API, an extension must request the "theme" [permission](../manifest.json/permissions) in its [manifest.json](../manifest.json) file.

  **Note:** When we set up a theme in a background file, we must declare the 'theme' [permission](../manifest.json/permissions) and therefore we cannot use the [theme](../manifest.json/theme) function of the manifest, since it's not compatible.

 

Types
-----


 [`theme.Theme`](theme/theme)  Represents the content of a theme.

  Functions
---------


 [`theme.getCurrent()`](theme/getcurrent)  Gets the current browser theme.

  [`theme.update()`](theme/update)  Updates the browser's theme.

  [`theme.reset()`](theme/reset)  Removes any theme updates made in a call to [`theme.update()`](theme/update).

  Events
------


 [`theme.onUpdated`](theme/onupdated)  Fired when the browser theme has been changed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Theme` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `getCurrent` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `onUpdated` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |
| `reset` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `update` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |


Example extensions
------------------


* [dynamic-theme](https://github.com/mdn/webextensions-examples/tree/master/dynamic-theme)
* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)
* [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme>

types
=====


Defines the `BrowserSetting` type, which is used to represent a browser setting.


Types
-----


 [`types.BrowserSetting`](types/browsersetting)  Represents a browser setting.

  Browser compatibility
---------------------



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types>

userScripts
===========



Use this API to register user scripts, third-party scripts designed to manipulate webpages or provide new features. Registering a user script instructs the browser to attach the script to pages that match the URL patterns specified during registration.

  **Note:** When using Manifest V3 or higher, use [`scripting.registerContentScripts()`](scripting/registercontentscripts) to register scripts.

  This API offers similar capabilities to [`contentScripts`](contentscripts) but with features suited to handling third-party scripts:

 * execution is in an isolated sandbox: each user script is run in an isolated sandbox within the web content processes, preventing accidental or deliberate interference among scripts.
* access to the `window` and `document` global values related to the webpage the user script is attached to.
* no access to WebExtension APIs or associated permissions granted to the extension: the API script, which inherits the extension's permissions, can provide packaged WebExtension APIs to registered user scripts. An API script is declared in the extension's manifest file using the "user\_scripts" manifest key.

  **Warning:** This API requires the presence of the [`user_scripts`](../manifest.json/user_scripts) key in the manifest.json, even if no API script is specified. For example. `user_scripts: {}`.

  To use the API, call `[`register()`](userscripts/register)` passing in an object defining the scripts to register. The method returns a Promise that is resolved with a `[`RegisteredUserScript`](userscripts/registereduserscript)` object.

  **Note:** User scripts are unregistered when the related extension page (from which the user scripts were registered) is unloaded, so you should register a user script from an extension page that persists at least as long as you want the user scripts to stay registered.

 

Types
-----


 [`userScripts.RegisteredUserScript`](userscripts/registereduserscript)  The `object` returned by the [`register()`](userscripts/register) method. It represents the registered user scripts and is used to deregister the user scripts.

  Methods
-------


 [`userScripts.register()`](userscripts/register)  Registers user scripts.

  Events
------


 [`userScripts.onBeforeScript`](userscripts/onbeforescript)  An event available to the API script, registered in[`"user_scripts"`](../manifest.json/user_scripts), that execute before a user script executes. Use it to trigger the export of the additional APIs provided by the API script, so they are available to the user script.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RegisteredUserScript` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |
| `cookieStoreId` | No | No | 98 | ? | No | No | ? | ? | 98 | ? | No | ? |
| `onBeforeScript` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |
| `register` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |


See also
--------


* [Working with `userScripts`](userscripts/working_with_userscripts)
* [`browser.contentScripts`](contentscripts)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts>

webRequest
==========



Add event listeners for the various stages of making an HTTP request, which includes websocket requests on `ws://` and `wss://`. The event listener receives detailed information about the request and can modify or cancel the request.

 Each event is fired at a particular stage of the request. The typical sequence of events is like this:

  ![Order of requests is onBeforeRequest, onBeforeSendHeader, onSendHeaders, onHeadersReceived, onResponseStarted, and onCompleted. The onHeadersReceived can cause an onBeforeRedirect and an onAuthRequired. Events caused by onHeadersReceived start at the beginning onBeforeRequest. Events caused by onAuthRequired start at onBeforeSendHeader.] 

 [`onErrorOccurred`](webrequest/onerroroccurred) can fire at any time during the request. Also, note that sometimes the sequence of events may differ from this. For example, in Firefox, on an [HSTS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) upgrade, the `onBeforeRedirect` event is triggered immediately after `onBeforeRequest`. `onErrorOccurred` is also fired if [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop) blocks a request.

 All events – *except* `onErrorOccurred` – can take three arguments to `addListener()`:

 * the listener itself
* a [`filter`](webrequest/requestfilter) object, so you can only be notified for requests made to particular URLs or for particular types of resource
* an optional `extraInfoSpec` object. You can use this to pass additional event-specific instructions.

 The listener function is passed a `details` object containing information about the request. This includes a request ID, which is provided to enable an add-on to correlate events associated with a single request. It is unique within a browser session and the add-on's context. It stays the same throughout a request, even across redirections and authentication exchanges.

 To use the `webRequest` API for a given host, an extension must have the `"webRequest"` [API permission](../manifest.json/permissions#api_permissions) and the [host permission](../manifest.json/permissions#host_permissions) for that host. To use the `"blocking"` feature, the extension must also have the `"webRequestBlocking"` API permission.

 To intercept resources loaded by a page (such as images, scripts, or stylesheets), the extension must have the host permission for the resource as well as for the main page requesting the resource. For example, if a page at `https://developer.mozilla.org` loads an image from `https://mdn.mozillademos.org`, then an extension must have both host permissions if it is to intercept the image request.



Modifying requests
------------------



On some of these events, you can modify the request. Specifically, you can:

 * cancel the request in:
	+ [`onBeforeRequest`](webrequest/onbeforerequest)
	+ [`onBeforeSendHeaders`](webrequest/onbeforesendheaders)
	+ [`onAuthRequired`](webrequest/onauthrequired)
* redirect the request in:
	+ [`onBeforeRequest`](webrequest/onbeforerequest)
	+ [`onHeadersReceived`](webrequest/onheadersreceived)
* modify request headers in:
	+ [`onBeforeSendHeaders`](webrequest/onbeforesendheaders)
* modify response headers in:
	+ [`onHeadersReceived`](webrequest/onheadersreceived)
* supply authentication credentials in:
	+ [`onAuthRequired`](webrequest/onauthrequired)

 To do this, you need to pass an option with the value `"blocking"` in the `extraInfoSpec` argument to the event's `addListener()`. This makes the listener synchronous.

 In the listener, you can then return a [`BlockingResponse`](webrequest/blockingresponse) object, which indicates the modification you need to make: for example, the modified request header you want to send.


Requests at browser startup
---------------------------


When a listener is registered with the `"blocking"` option and is registered during the extension startup, if a request is made during the browser startup that matches the listener the extension starts early. This enables the extension to observe the request at browser startup. If you don't take these steps, requests made at startup could be missed.

Speculative requests
--------------------


The browser can make speculative connections, where it determines that a request to a URI may be coming soon. This type of connection does not provide valid tab information, so request details such as `tabId`, `frameId`, `parentFrameId`, etc. are inaccurate. These connections have a [`webRequest.ResourceType`](webrequest/resourcetype) of `speculative`.

Accessing security information
------------------------------



In the [`onHeadersReceived`](webrequest/onheadersreceived) listener you can access the [TLS](https://developer.mozilla.org/en-US/docs/Glossary/TLS) properties of a request by calling [`getSecurityInfo()`](webrequest/getsecurityinfo). To do this you must also pass "blocking" in the `extraInfoSpec` argument to the event's `addListener()`.

 You can read details of the TLS handshake, but can't modify them or override the browser's trust decisions.


Modifying responses
-------------------



To modify the HTTP response bodies for a request, call [`webRequest.filterResponseData`](webrequest/filterresponsedata), passing it the ID of the request. This returns a [`webRequest.StreamFilter`](webrequest/streamfilter) object that you can use to examine and modify the data as it is received by the browser.

 To do this, you must have the `"webRequestBlocking"` API permission as well as the `"webRequest"` [API permission](../manifest.json/permissions#api_permissions) and the [host permission](../manifest.json/permissions#host_permissions) for the relevant host.


Types
-----


 [`webRequest.BlockingResponse`](webrequest/blockingresponse)  An object of this type is returned by event listeners that have set `"blocking"` in their `extraInfoSpec` argument. By setting particular properties in `BlockingResponse`, the listener can modify network requests.

  [`webRequest.CertificateInfo`](webrequest/certificateinfo)  An object describing a single X.509 certificate.

  [`webRequest.HttpHeaders`](webrequest/httpheaders)  An array of HTTP headers. Each header is represented as an object with two properties: `name` and either `value` or `binaryValue`.

  [`webRequest.RequestFilter`](webrequest/requestfilter)  An object describing filters to apply to `webRequest` events.

  [`webRequest.ResourceType`](webrequest/resourcetype)  Represents a particular kind of resource fetched in a web request.

  [`webRequest.SecurityInfo`](webrequest/securityinfo)  An object describing the security properties of a particular web request.

  [`webRequest.StreamFilter`](webrequest/streamfilter)  An object that can be used to monitor and modify HTTP responses while they are being received.

  [`webRequest.UploadData`](webrequest/uploaddata)  Contains data uploaded in a URL request.

  Properties
----------


 [`webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES`](webrequest/max_handler_behavior_changed_calls_per_10_minutes)  The maximum number of times that [`handlerBehaviorChanged()`](webrequest/handlerbehaviorchanged) can be called in a 10 minute period.

  Methods
-------


 [`webRequest.handlerBehaviorChanged()`](webrequest/handlerbehaviorchanged)  This method can be used to ensure that event listeners are applied correctly when pages are in the browser's in-memory cache.

  [`webRequest.filterResponseData()`](webrequest/filterresponsedata)  Returns a [`webRequest.StreamFilter`](webrequest/streamfilter) object for a given request.

  [`webRequest.getSecurityInfo()`](webrequest/getsecurityinfo)  Gets detailed information about the [TLS](https://developer.mozilla.org/en-US/docs/Glossary/TLS) connection associated with a given request.

  Events
------


 [`webRequest.onBeforeRequest`](webrequest/onbeforerequest)  Fired when a request is about to be made, and before headers are available. This is a good place to listen if you want to cancel or redirect the request.

  [`webRequest.onBeforeSendHeaders`](webrequest/onbeforesendheaders)  Fired before sending any HTTP data, but after HTTP headers are available. This is a good place to listen if you want to modify HTTP request headers.

  [`webRequest.onSendHeaders`](webrequest/onsendheaders)  Fired just before sending headers. If your add-on or some other add-on modified headers in `[`onBeforeSendHeaders`](webrequest/onbeforesendheaders)`, you'll see the modified version here.

  [`webRequest.onHeadersReceived`](webrequest/onheadersreceived)  Fired when the HTTP response headers associated with a request have been received. You can use this event to modify HTTP response headers.

  [`webRequest.onAuthRequired`](webrequest/onauthrequired)  Fired when the server asks the client to provide authentication credentials. The listener can do nothing, cancel the request, or supply authentication credentials.

  [`webRequest.onResponseStarted`](webrequest/onresponsestarted)  Fired when the first byte of the response body is received. For HTTP requests, this means that the status line and response headers are available.

  [`webRequest.onBeforeRedirect`](webrequest/onbeforeredirect)  Fired when a server-initiated redirect is about to occur.

  [`webRequest.onCompleted`](webrequest/oncompleted)  Fired when a request is completed.

  [`webRequest.onErrorOccurred`](webrequest/onerroroccurred)  Fired when an error occurs.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BlockingResponse` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `CertificateInfo` | NoSee [bug 628819](https://crbug.com/628819). | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `HttpHeaders` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | No | ? |
| `MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `RequestFilter` | YesIf a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 14If a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 45["From Firefox 78 onwards, if a filter contains unrecognized values in its `types` property, then these values are ignored and `addListener()` proceeds.", "Before Firefox 78, if a filter contains unrecognized values in its `types` property, `addListener()` throws an exception."] | ? | YesIf a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 14 | ? | ? | 48If a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | ? | No | ? |
| `ResourceType` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `SecurityInfo` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `StreamFilter` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `UploadData` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `filterResponseData` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `getSecurityInfo` | NoSee [bug 628819](https://crbug.com/628819). | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `handlerBehaviorChanged` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `onAuthRequired` | Yes | 14 | 54To handle a request asynchronously, return a Promise from the listener. | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 54To handle a request asynchronously, return a Promise from the listener. | ? | No | ? |
| `onBeforeRedirect` | Yes | 14 | 46 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |
| `onBeforeRequest` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 46Asynchronous event listeners are supported from version 52. | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48Asynchronous event listeners are supported from version 52. | ? | No | ? |
| `onBeforeSendHeaders` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 45Asynchronous event listeners are supported from version 52. | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48Asynchronous event listeners are supported from version 52. | ? | No | ? |
| `onCompleted` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |
| `onErrorOccurred` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |
| `onHeadersReceived` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 45["Modification of the 'Content-Type' header is supported from version 51.", "Asynchronous event listeners are supported from version 52."] | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48["Modification of the 'Content-Type' header is supported from version 51.", "Asynchronous event listeners are supported from version 52."] | ? | No | ? |
| `onResponseStarted` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |
| `onSendHeaders` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


[Additional notes on Chrome incompatibilities](../chrome_incompatibilities#webrequest_api).


Example extensions
------------------



* [http-response](https://github.com/mdn/webextensions-examples/tree/master/http-response)
* [root-cert-stats](https://github.com/mdn/webextensions-examples/tree/master/root-cert-stats)
* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)
* [user-agent-rewriter](https://github.com/mdn/webextensions-examples/tree/master/user-agent-rewriter)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest>

scripting.executeScript()
=========================



Injects a script into a target context. The script is run at `document_idle` by default.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Safari and Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the target's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission). Note that some special pages do not allow this permission, including reader view, view-source, and PDF viewer pages.

 In Firefox and Safari, partial lack of host permissions can result in a successful execution (with the partial results in the resolved promise). In Chrome, any missing permission prevents any execution from happening (see [Issue 1325114](https://crbug.com/1325114)).

 The scripts you inject are called [content scripts](../../content_scripts).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let results = await browser.scripting.executeScript(
  details             // object
)

```
### Parameters


 `details`  An object describing the script to inject. It contains these properties:

  
`args` Optional
  An array of arguments to carry into the function. This is only valid if the `func` parameter is specified. The arguments must be JSON-serializable.

  
`files` Optional
  `array` of `string`. An array of path of the JS files to inject, relative to the extension's root directory. Exactly one of `files` and `func` must be specified.

  
`func` Optional
  `function`. A JavaScript function to inject. This function is serialized and then deserialized for injection. This means that any bound parameters and execution context are lost. Exactly one of `files` and `func` must be specified.

  
`injectImmediately` Optional
  `boolean`. Whether the injection into the target is triggered as soon as possible, but not necessarily prior to page load.

  `target`  [`scripting.InjectionTarget`](injectiontarget). Details specifying the target to inject the script into.

  
`world` Optional
  [`scripting.ExecutionWorld`](executionworld). The execution environment for a script to execute in.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an array of `InjectionResult` objects, which represent the result of the injected script in every injected frame.

 The promise is rejected if the injection fails, such as when the injection target is invalid. When script execution has started, its result is included in the result, whether successful (as `result`) or unsuccessfully (as `error`).

 Each `InjectionResult` object has these properties:

  `frameId`  `number`. The frame ID associated with the injection.

  
`result` Optional
  `any`. The result of the script execution.

  
`error` Optional
  `any`. If an error occurs, contains the value the script threw or rejected with. Typically this is an error object with a message property but it could be any value (including primitives and undefined).

 Chrome does not support the `error` property yet (see [Issue 1271527: Propagate errors from scripting.executeScript to InjectionResult](https://crbug.com/1271527)). As an alternative, runtime errors can be caught by wrapping the code to execute in a try-catch statement. Uncaught errors are also reported to the console of the target tab.

   The result of the script is the last evaluated statement, which is similar to the results seen if you executed the script in the [Web Console](https://firefox-source-docs.mozilla.org/devtools-user/web_console/index.html) (not any `console.log()` output). For example, consider a script like this:

 
```
let foo='my result'; foo;

```
 Here the results array contains the string "`my result`" as an element.

 The result values must be [structured cloneable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)).


Examples
--------



This example executes a one-line code snippet in the active tab:

 
```
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.executeScript({
      target: {
        tabId: tab.id,
      },
      func: () => {
        document.body.style.border = "5px solid green";
      },
    });
  } catch (err) {
    console.error(`failed to execute script: ${err}`);
  }
});

```
 This example executes a script from a file (packaged with the extension) called `"content-script.js"`. The script is executed in the active tab. The script is executed in subframes and the main document:

 
```
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.executeScript({
      target: {
        tabId: tab.id,
        allFrames: true,
      },
      files: ["content-script.js"],
    });
  } catch (err) {
    console.error(`failed to execute script: ${err}`);
  }
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `InjectionResult` | 88 | 88 | 102 | ? | 74 | NoSafari returns an array with the results, instead of an array of InjectionResults. | ? | ? | 102 | ? | NoSafari returns an array with the results, instead of an array of InjectionResults. | ? |
| `executeScript` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `injectImmediately` | 88 | 88 | 102 | ? | 74 | No | ? | ? | 102 | ? | No | ? |
| `world` | 95 | 95 | 102Only supports `ISOLATED`, not `MAIN`. | ? | 81 | 15.4 | ? | ? | 102Only supports `ISOLATED`, not `MAIN`. | ? | 15.4 | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-executeScript) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript>

topSites
========



Use the topSites API to get an array containing pages that the user has visited frequently.

 Browsers maintain this to help the user get back to these places easily. For example, Firefox by default provides a list of the most-visited pages in the "New Tab" page.

 To use the topSites API you must have the "topSites" [API permission](../manifest.json/permissions#api_permissions).



Types
-----


 [`topSites.MostVisitedURL`](topsites/mostvisitedurl)  An object containing the title and URL of a website.

  Methods
-------


 [`topSites.get()`](topsites/get)  Gets an array containing all the sites listed in the browser's "New Tab" page. Note that the number of sites returned here is browser-specific, and the particular sites returned will probably be specific to the user, based on their browsing history.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MostVisitedURL` | Yes | 79 | 52 | ? | Yes | No | ? | ? | 52–79 | ? | No | ? |
| `get` | Yes | 79 | 52Since Firefox 78, a user may disable the browser's "Top Sites" feature by toggling the "browser.newtabpage.activity-stream.feeds.system.topsites" preference. In this case, `topSites.get()` will always return a list of the most-visited sites, regardless of the value of the `newtab` parameter. | ? | Yes | No | ? | ? | 52–79 | ? | No | ? |


Example extensions
------------------



* [top-sites](https://github.com/mdn/webextensions-examples/tree/master/top-sites)

  **Note:** This API is based on Chromium's [`chrome.topSites`](https://developer.chrome.com/docs/extensions/reference/topSites/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/topSites>

webNavigation
=============



Add event listeners for the various stages of a navigation. A navigation consists of a frame in the browser transitioning from one URL to another, usually (but not always) in response to a user action like clicking a link or entering a URL in the location bar.

 Compared with the [`webRequest`](webrequest) API: navigations usually result in the browser making web requests, but the webRequest API is concerned with the lower-level view from the HTTP layer, while the webNavigation API is more concerned with the view from the browser UI itself.

 Each event corresponds to a particular stage in the navigation. The sequence of events is like this:

  ![Visualization of the primary flow and additional flows described below.] 

 * The primary flow is:
	+ `[`onBeforeNavigate`](webnavigation/onbeforenavigate)`
	+ `[`onCommitted`](webnavigation/oncommitted)`
	+ `[`onDOMContentLoaded`](webnavigation/ondomcontentloaded)`
	+ `[`onCompleted`](webnavigation/oncompleted)`.
* Additionally:
	+ `[`onCreatedNavigationTarget`](webnavigation/oncreatednavigationtarget)` is fired before `onBeforeNavigate` if the browser needed to create a new tab or window for the navigation (for example, because the user opened a link in a new tab).
	+ [`onHistoryStateUpdated`](webnavigation/onhistorystateupdated) is fired if a page uses the [history API (2011)](http://diveintohtml5.info/history.html) to update the URL displayed in the browser's location bar.
	+ [`onReferenceFragmentUpdated`](webnavigation/onreferencefragmentupdated) is fired if the [fragment identifier](https://en.wikipedia.org/wiki/Fragment_identifier) for a page is changed.
	+ [`onErrorOccurred`](webnavigation/onerroroccurred) can be fired at any point.

 Each navigation is a URL transition in a particular browser frame. The browser frame is identified by a tab ID and a frame ID. The frame may be the top-level browsing context in the tab, or may be a nested browsing context implemented as an [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).

 Each event's `addListener()` call accepts an optional filter parameter. The filter will specify one or more URL patterns, and the event will then only be fired for navigations in which the target URL matches one of the patterns.

 The `onCommitted` event listener is passed two additional properties: a [`TransitionType`](webnavigation/transitiontype) indicating the cause of the navigation (for example, because the user clicked a link, or because the user selected a bookmark), and a [`TransitionQualifier`](webnavigation/transitionqualifier) providing further information about the navigation.

 To use this API you need to have the "webNavigation" [permission](../manifest.json/permissions).



Types
-----


 [`webNavigation.TransitionType`](webnavigation/transitiontype)  Cause of the navigation: for example, the user clicked a link, or typed an address, or clicked a bookmark.

  [`webNavigation.TransitionQualifier`](webnavigation/transitionqualifier)  Extra information about a transition.

  Functions
---------


 [`webNavigation.getFrame()`](webnavigation/getframe)  Retrieves information about a particular frame. A frame may be the top-level frame in a tab or a nested [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe), and is uniquely identified by a tab ID and a frame ID.

  [`webNavigation.getAllFrames()`](webnavigation/getallframes)  Given a tab ID, retrieves information about all the frames it contains.

  Events
------


 [`webNavigation.onBeforeNavigate`](webnavigation/onbeforenavigate)  Fired when the browser is about to start a navigation event.

  [`webNavigation.onCommitted`](webnavigation/oncommitted)  Fired when a navigation is committed. At least part of the new document has been received from the server and the browser has decided to switch to the new document.

  [`webNavigation.onDOMContentLoaded`](webnavigation/ondomcontentloaded)  Fired when the [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) event is fired in the page.

  [`webNavigation.onCompleted`](webnavigation/oncompleted)  Fired when a document, including the resources it refers to, is completely loaded and initialized. This is equivalent to the DOM [`load`](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event) event.

  [`webNavigation.onErrorOccurred`](webnavigation/onerroroccurred)  Fired when an error occurs and the navigation is aborted. This can happen if either a network error occurred, or the user aborted the navigation.

  [`webNavigation.onCreatedNavigationTarget`](webnavigation/oncreatednavigationtarget)  Fired when a new window, or a new tab in an existing window, is created to host a navigation: for example, if the user opens a link in a new tab.

  [`webNavigation.onReferenceFragmentUpdated`](webnavigation/onreferencefragmentupdated)  Fired if the [fragment identifier](https://en.wikipedia.org/wiki/Fragment_identifier) for a page is changed.

  [`webNavigation.onTabReplaced`](webnavigation/ontabreplaced)  Fired when the contents of the tab is replaced by a different (usually previously pre-rendered) tab.

  [`webNavigation.onHistoryStateUpdated`](webnavigation/onhistorystateupdated)  Fired when the page used the [history API (2011)](http://diveintohtml5.info/history.html) to update the URL displayed in the browser's location bar.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TransitionQualifier` | Yes | 79 | 48'server\_redirect' is limited to top-level frames and 'client\_redirect' is not supplied when redirections are created by JavaScript. | ? | 17 | No | ? | ? | 48'server\_redirect' is limited to top-level frames and 'client\_redirect' is not supplied when redirections are created by JavaScript. | ? | No | ? |
| `TransitionType` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `getAllFrames` | Yes | 14 | 47The returned objects do not include the `errorOccurred` property. See [bug 1248418](https://bugzil.la/1248418). | ? | 17 | 14 | ? | ? | 48The returned objects do not include the `errorOccurred` property. See [bug 1248418](https://bugzil.la/1248418). | ? | 15 | ? |
| `getFrame` | Yes | 14 | 47 | ? | 17 | 14 | ? | ? | 48 | ? | 15 | ? |
| `onBeforeNavigate` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `onCommitted` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `onCompleted` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `onCreatedNavigationTarget` | YesIf a blocked popup is unblocked by the user, the event is still not sent. | 14 | 54["If the filter parameter is empty, Firefox raises an exception.", "If a blocked popup is unblocked by the user, the event is then sent."] | ? | 17If a blocked popup is unblocked by the user, the event is still not sent. | No | ? | ? | 54["If the filter parameter is empty, Firefox raises an exception.", "If a blocked popup is unblocked by the user, the event is then sent.", "This event is only sent in the 'window.open()' case."] | ? | No | ? |
| `onDOMContentLoaded` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `onErrorOccurred` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `onHistoryStateUpdated` | Yes | 14Filtering is not supported. | 47 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `onReferenceFragmentUpdated` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | No | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | No | ? |
| `onTabReplaced` | Yes | 14 | 45Although you can add listeners for this event, it will never fire because the underlying functionality is not supported. | ? | 17 | No | ? | ? | 48Although you can add listeners for this event, it will never fire because the underlying functionality is not supported. | ? | No | ? |


Example extensions
------------------



* [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats)

  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation>

windows
=======


Interact with browser windows. You can use this API to get information about open windows and to open, modify, and close windows. You can also listen for window open, close, and activate events.


Types
-----


 [`windows.WindowType`](windows/windowtype)  The type of browser window this is.

  [`windows.WindowState`](windows/windowstate)  The state of this browser window.

  [`windows.Window`](windows/window)  Contains information about a browser window.

  [`windows.CreateType`](windows/createtype)  Specifies the type of browser window to create.

  Constants
---------


 [`windows.WINDOW_ID_NONE`](windows/window_id_none)  The `windowId` value that represents the absence of a browser window.

  [`windows.WINDOW_ID_CURRENT`](windows/window_id_current)  A value that can be used in place of a `windowId` in some APIs to represent the current window.

  Methods
-------


 [`windows.get()`](windows/get)  Gets details about a window, given its ID.

  [`windows.getCurrent()`](windows/getcurrent)  Gets the current window.

  [`windows.getLastFocused()`](windows/getlastfocused)  Gets the window that was most recently focused — typically the window 'on top'.

  [`windows.getAll()`](windows/getall)  Gets all windows.

  [`windows.create()`](windows/create)  Creates a new window.

  [`windows.update()`](windows/update)  Updates the properties of a window. Use this to move, resize, and (un)focus a window, etc.

  [`windows.remove()`](windows/remove)  Closes a window, and all its tabs.

  Events
------


 [`windows.onCreated`](windows/oncreated)  Fired when a window is created.

  [`windows.onRemoved`](windows/onremoved)  Fired when a window is closed.

  [`windows.onFocusChanged`](windows/onfocuschanged)  Fired when the currently focused window changes.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CreateType` | Yes`detached_panel` is not supported. | 14`panel` and `detached_panel` are not supported. | 45 | ? | Yes`detached_panel` is not supported. | 14`panel` and `detached_panel` are not supported. | ? | ? | No | ? | 15`panel` and `detached_panel` are not supported. | ? |
| `WINDOW_ID_CURRENT` | 18 | 14 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `WINDOW_ID_NONE` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `Window` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `WindowState` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `WindowType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `create` | Yes | 14 | 45["'url' and 'tabId options can't both be set together.", "The returned 'Window' object contains the 'tabs' property only from version 52 onwards.", "From Firefox 86, the `focused: false` option is ignored."] | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `get` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getAll` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getCurrent` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getLastFocused` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `onCreated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15Fires a pair of events: one for private browsing, one for regular browsing. | ? |
| `onFocusChanged` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15Fires when toggling in or out of private browsing mode, leaving Safari to the home screen, and returning to Safari from the home screen. | ? |
| `onRemoved` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `remove` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `update` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


Example extensions
------------------



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar)
* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows>

extension.getURL()
==================



 **Warning:** This function is deprecated. Please use [`runtime.getURL`](../runtime/geturl).

  Converts a relative path within an extension's install directory to a fully-qualified URL.



Syntax
------



```
browser.extension.getURL(
  path // string
)

```
### Parameters


 `path`  `string`. A path to a resource within an extension expressed relative to its install directory.

  ### Return value


`string`. The fully-qualified URL to the resource.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getURL` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Given a file packaged with the add-on at "beasts/frog.html", get the full URL like this:

 
```
let fullURL = browser.extension.getURL("beasts/frog.html");

// -> something like:
// moz-extension://2c127fa4-62c7-7e4f-90e5-472b45eecfdc/beasts/frog.html

```

### Example extensions



* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)

  **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-getURL) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/getURL>

extension.inIncognitoContext
============================


Boolean value, `true` for content scripts running inside private browsing tabs and for extension pages running inside a private browsing process.


Syntax
------



```
let isPrivate = browser.extension.inIncognitoContext;  // true or false

```
### Value


A *boolean* value indicate if the current script is running in a private tab or process.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `inIncognitoContext` | Yes | 17 | 45 | ? | Yes | 14Always returns false. | ? | ? | 48 | ? | 15Always returns false. | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#property-inIncognitoContext) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/inIncognitoContext>

runtime.getURL()
================



Given a relative path from the [manifest.json](../../manifest.json) to a resource packaged with the extension, return a fully-qualified URL.

 This function does *not* check that the resource actually exists at that URL.



Syntax
------



```
browser.runtime.getURL(
  path // string
)

```
### Parameters


 `path`  `string`. A relative path from the [manifest.json](../../manifest.json) to a resource packaged with the extension.

  ### Return value


`string`. The fully-qualified URL to the resource.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getURL` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Given a file packaged with the extension at "beasts/frog.html", get the full URL like this:

 
```
let fullURL = browser.runtime.getURL("beasts/frog.html");
console.log(fullURL);
// Returns something like:
// moz-extension://2c127fa4-62c7-7e4f-90e5-472b45eecfdc/beasts/frog.html

```

### Example extensions



* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-getURL) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getURL>

runtime.sendMessage()
=====================



Sends a single message to event listeners within your extension or a different extension.

 If sending to your extension, omit the `extensionId` argument. The [`runtime.onMessage`](onmessage) event will be fired in each page in your extension, except for the frame that called `runtime.sendMessage`.

 If sending to a different extension, include the `extensionId` argument set to the other extension's ID. [`runtime.onMessageExternal`](onmessageexternal) will be fired in the other extension. By default, your extension can exchange messages with itself and any other extension (defined by `extensionId`). However, the [`externally_connectable`](../../manifest.json/externally_connectable) manifest key can be used to limit communication to specific extensions.

 Extensions cannot send messages to content scripts using this method. To send messages to content scripts, use [`tabs.sendMessage`](../tabs/sendmessage).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** You can also use a [connection-based approach to exchange messages](../../content_scripts#connection-based_messaging).

 

Syntax
------



```
let sending = browser.runtime.sendMessage(
  extensionId,             // optional string
  message,                 // any
  options                  // optional object
)

```
### Parameters



 
`extensionId` Optional
  `string`. The ID of the extension to send the message to. Include this to send the message to a different extension. If the intended recipient has set an ID explicitly using the [browser\_specific\_settings](../../manifest.json/browser_specific_settings) key in manifest.json, then `extensionId` should have that value. Otherwise it should have the ID that was generated for the intended recipient.

 If `extensionId` is omitted, the message is sent to your extension.

  `message`  `any`. An object that can be structured clone serialized (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)).

  
`options` Optional
  `object`.

  
`includeTlsChannelId` Optional
  `boolean`. Whether the TLS channel ID will be passed into [`runtime.onMessageExternal`](onmessageexternal) for processes that are listening for the connection event.

 This option is only supported in Chromium-based browsers.

     Depending on the arguments it is given, this API is sometimes ambiguous. The following rules are used:

 * **if one argument is given**, it is the message to send, and the message will be sent internally.
* **if two arguments are given:**
	+ the arguments are interpreted as `(message, options)`, and the message is sent internally, if the second argument is any of the following:
		1. a valid `options` object (meaning, it is an object which contains only the properties of `options` that the browser supports)
		2. null
		3. undefined
	+ otherwise, the arguments are interpreted as `(extensionId, message)`. The message will be sent to the extension identified by `extensionId`.
* **if three arguments are given**, the arguments are interpreted as `(extensionId, message, options)`. The message will be sent to the extension identified by `extensionId`.

 Note that before Firefox 55, the rules were different in the 2-argument case. Under the old rules, if the first argument was a string, it was treated as the `extensionId`, with the message as the second argument. This meant that if you called `sendMessage()` with arguments like `("my-message", {})`, then it would send an empty message to the extension identified by "my-message". Under the new rules, with these arguments you would send the message "my-message" internally, with an empty options object.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the receiver sent a response, this will be fulfilled with the response. Otherwise it will be fulfilled with no arguments. If an error occurs while connecting to the extension, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sendMessage` | 26 | 14`runtime.onMessage` listeners in extension views receive the messages they sent. | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Here's a content script that sends a message to the background script when the user clicks the content window. The message payload is `{greeting: "Greeting from the content script"}`, and the sender also expects to get a response, which is handled in the `handleResponse` function:

 
```
// content-script.js

function handleResponse(message) {
  console.log(`Message from the background script: ${message.response}`);
}

function handleError(error) {
  console.log(`Error: ${error}`);
}

function notifyBackgroundPage(e) {
  const sending = browser.runtime.sendMessage({
    greeting: "Greeting from the content script",
  });
  sending.then(handleResponse, handleError);
}

window.addEventListener("click", notifyBackgroundPage);

```
 The corresponding background script looks like this:

 
```
// background-script.js
function handleMessage(request, sender, sendResponse) {
  console.log(`A content script sent a message: ${request.greeting}`);
  sendResponse({ response: "Response from background script" });
}

browser.runtime.onMessage.addListener(handleMessage);

```
   **Note:** Instead of using `sendResponse()`, returning a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) is the recommended approach for Firefox add-ons. Examples using a Promise are available in the [examples section](onmessage#examples) of the [`runtime.onMessage`](onmessage) listener. 

 
### Example extensions



* [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register)
* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [mocha-client-tests](https://github.com/mdn/webextensions-examples/tree/master/mocha-client-tests)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [user-script-register](https://github.com/mdn/webextensions-examples/tree/master/user-script-register)
* [webpack-modules](https://github.com/mdn/webextensions-examples/tree/master/webpack-modules)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-sendMessage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage>

i18n.getMessage()
=================



Gets the localized string for the specified message.

 See the [Internationalization](../../internationalization) page for a guide on using this function.



Syntax
------



```
browser.i18n.getMessage(
  messageName,  // string
  substitutions // optional any
)

```
### Parameters


 `messageName`  `string`. The name of the message, as specified in the messages.json file. If the message can't be found in messages.json:

 * Firefox returns "" and logs an error.
* Chrome returns "" and does not log an error.

  
`substitutions` Optional
  `string` or `array` of `string`. A single substitution string, or an array of substitution strings.

 In Chrome, if you supply more than 9 substitution strings, `getMessage()` will return `undefined`.

  ### Return value


`string`. Message localized for current locale.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getMessage` | 17 | 14["Throws an exception instead returning an empty string if the message does not exist.", "Expects substitutions to be strings, while other browsers allow any value which is then converted to a string."] | 45Firefox 47 and earlier returns "??" instead of "" if the message is not found in \_locales, [bug 1258199](https://bugzil.la/1258199) changed this act to match Chrome, landed on Firefox 48. | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Get the localized string for `"messageContent"`, with `target.url` substituted:

 
```
let message = browser.i18n.getMessage("messageContent", target.url);
console.log(message);

```
 This would work with a \_locales/en/messages.json file containing:

 
```
{
  "messageContent": {
    "message": "You clicked $URL$.",
    "description": "Tells the user which link they clicked.",
    "placeholders": {
      "url" : {
        "content" : "$1",
        "example" : "https://developer.mozilla.org"
      }
    }
  }
}

```
 If `target.url` is "<https://developer.mozilla.org>", then the value of message, in the "en" locale, would be:

 
```
"You clicked https://developer.mozilla.org."

```

### Example extensions



* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)

  **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/#method-getMessage) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getMessage>

i18n.getAcceptLanguages()
=========================



Gets the [accept-languages](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#the_accept-language_header) of the browser. This is different from the locale used by the browser. To get the locale, use [`i18n.getUILanguage`](getuilanguage).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 See the [Internationalization](../../internationalization) page for a guide on using this function.



Syntax
------



```
let gettingAcceptLanguages = browser.i18n.getAcceptLanguages()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `array` of `[`i18n.LanguageCode`](languagecode)` objects.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAcceptLanguages` | 47 | 14 | 47 | ? | 34 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------




```
function onGot(languages) {
  console.log(languages);
  //e.g. Array [ "en-US", "en" ]
}

let gettingAcceptLanguages = browser.i18n.getAcceptLanguages();
gettingAcceptLanguages.then(onGot);

```
  **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/#method-getAcceptLanguages) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getAcceptLanguages>

Sharing objects with page scripts
=================================



 **Note:** The techniques described in this section are only available in Firefox, and only from Firefox 49 onwards.

   **Warning:** As an extension developer you should consider that scripts running in arbitrary web pages are hostile code whose aim is to steal the user's personal information, damage their computer, or attack them in some other way.

 The isolation between content scripts and scripts loaded by web pages is intended to make it more difficult for hostile web pages to do this.

 Since the techniques described in this section break down that isolation, they are inherently dangerous and should be used with great care.

  As the [content scripts guide notes](content_scripts#dom_access), content scripts don't see changes made to the DOM by scripts loaded by web pages. This means that, for example, if a web page loads a library like jQuery, content scripts won't be able to use it, and have to load their own copy. Conversely, scripts loaded by web pages can't see changes made by content scripts.

 However, Firefox provides some APIs that enable content scripts to:

 * access JavaScript objects created by page scripts
* expose their own JavaScript objects to page scripts.



Xray vision in Firefox
----------------------



In Firefox, part of the isolation between content scripts and page scripts is implemented using a feature called "Xray vision". When a script in a more-privileged scope accesses an object that's defined in a less-privileged scope it sees only the "native version" of the object. Any [expando](https://developer.mozilla.org/en-US/docs/Glossary/Expando) properties are invisible, and if any properties of the object have been redefined, it sees the original implementation, not the redefined version.

 The purpose of this feature is to make it harder for the less-privileged script to confuse the more-privileged script by redefining the native properties of objects.

 So, for example, when a content script accesses the page's [window](https://developer.mozilla.org/en-US/docs/Web/API/Window), it won't see any properties the page script added to the window, and if the page script has redefined any existing properties of the window, the content script will see the original version.


Accessing page script objects from content scripts
--------------------------------------------------



In Firefox, DOM objects in content scripts get an extra property `wrappedJSObject`. This is an "unwrapped" version of the object, which includes any changes made to that object by any page scripts.

 Let's take a simple example. Suppose a web page loads a script:

 
```
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script src="main.js"></script>
  </body>
</html>

```
 The script adds an expando property to the global `window`:

 
```
// main.js

let foo = "I'm defined in a page script!";

```
 Xray vision means that if a content script tries to access `foo`, it will be undefined:

 
```
// content-script.js

console.log(window.foo); // undefined

```
 In Firefox, content scripts can use `window.wrappedJSObject` to see the expando property:

 
```
// content-script.js

console.log(window.wrappedJSObject.foo); // "I'm defined in a page script!"

```
 Note that once you do this, you can no longer rely on any of this object's properties or functions being, or doing, what you expect. Any of them, even setters and getters, could have been redefined by untrusted code.

 Also note that unwrapping is transitive: when you use `wrappedJSObject`, any properties of the unwrapped object are themselves unwrapped (and therefore unreliable). So it's good practice, once you've got the object you need, to rewrap it, which you can do like this:

 
```
XPCNativeWrapper(window.wrappedJSObject.foo);

```
 See the document on [Xray vision](https://firefox-source-docs.mozilla.org/dom/scriptSecurity/xray_vision.html) for much more detail on this.


Sharing content script objects with page scripts
------------------------------------------------



Firefox also provides APIs enabling content scripts to make objects available to page scripts. There are several approaches here:

 * [`exportFunction()`](#exportfunction): export a function to page scripts.
* [`cloneInto()`](#cloneinto): export an object to page scripts.
* constructors from the page context


### exportFunction



Given a function defined in the content script, `exportFunction()` exports it to the page script's scope, so the page script can call it.

 For example, let's consider an extension which has a background script like this:

 
```
/\*
Execute content script in the active tab.
\*/
function loadContentScript() {
  browser.tabs.executeScript({
    file: "/content\_scripts/export.js"
  });
}

/\*
Add loadContentScript() as a listener to clicks
on the browser action.
\*/
browser.browserAction.onClicked.addListener(loadContentScript);

/\*
Show a notification when we get messages from
the content script.
\*/
browser.runtime.onMessage.addListener((message) => {
  browser.notifications.create({
    type: "basic",
    title: "Message from the page",
    message: message.content
  });
});

```
 This does two things:

 * execute a content script in the current tab, when the user clicks a browser action
* listen for messages from the content script, and display a [notification](api/notifications) when the message arrives.

 The content script looks like this:

 
```
/\*
Define a function in the content script's scope, then export it
into the page script's scope.
\*/
function notify(message) {
  browser.runtime.sendMessage({ content: `Function call: ${message}` });
}

exportFunction(notify, window, { defineAs: "notify" });

```
 This defines a function `notify()`, which just sends its argument to the background script. It then exports the function to the page script's scope. Now the page script can call this function:

 
```
window.notify("Message from the page script!");

```

### cloneInto



Given an object defined in the content script, this creates a clone of the object in the page script's scope, thereby making the clone accessible to page scripts. By default, this uses the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) to clone the object, meaning that functions in the object are not included in the clone. To include functions, pass the `cloneFunctions` option.

 For example, here's a content script that defines an object that contains a function, then clones it into the page script's scope:

 
```
/\*
Create an object that contains functions in
the content script's scope, then clone it
into the page script's scope.

Because the object contains functions,
the cloneInto call must include
the `cloneFunctions` option.
\*/
let messenger = {
  notify(message) {
    browser.runtime.sendMessage({
      content: `Object method call: ${message}`
    });
  }
};

window.wrappedJSObject.messenger = cloneInto(
  messenger,
  window,
  {cloneFunctions: true});

```
 Now page scripts see a new property on the window, `messenger`, which has a function `notify()`:

 
```
window.messenger.notify("Message from the page script!");

```

### Constructors from the page context



On the xrayed window object pristine constructors for some built-in JavaScript objects such as `Object`, `Function` or `Proxy` and various DOM classes are available. `XMLHttpRequest` does not behave in this way, see the [XHR and fetch](content_scripts#xhr_and_fetch) section for details. They will create instances belonging to the page global's object hierarchy and then return an xray wrapper.

 Since objects created this way already belong to the page and not the content script passing them back to the page will not require additional cloning or exporting.

 
```
/\* JavaScript built-ins \*/

const objA = new Object();
const objB = new window.Object();

console.log(
  objA instanceof Object,                        // true
  objB instanceof Object,                        // false
  objA instanceof window.Object,                 // false
  objB instanceof window.Object,                 // true
  'wrappedJSObject' in objB                      // true; xrayed
);

objA.foo = "foo";
objB.foo = "foo";                                // xray wrappers for plain JavaScript objects pass through property assignments
objB.wrappedJSObject.bar = "bar";                // unwrapping before assignment does not rely on this special behavior

window.wrappedJSObject.objA = objA;
window.wrappedJSObject.objB = objB;              // automatically unwraps when passed to page context

window.eval(`
 console.log(objA instanceof Object); // false
 console.log(objB instanceof Object); // true

 try {
 console.log(objA.foo);
 } catch (error) {
 console.log(error); // Error: permission denied
 }
 
 try {
 objA.baz = "baz";
 } catch (error) {
 console.log(error); // Error: permission denied
 }

 console.log(objB.foo, objB.bar); // "foo", "bar"
 objB.baz = "baz";
`);

/\* other APIs \*/

const ev = new Event("click");

console.log(
  ev instanceof Event,                           // true
  ev instanceof window.Event,                    // true; Event constructor is actually inherited from the xrayed window
  'wrappedJSObject' in ev                        // true; is an xrayed object
);

ev.propA = "propA"                                // xray wrappers for native objects do not pass through assignments
ev.propB = "wrapper";                             // define property on xray wrapper
ev.wrappedJSObject.propB = "unwrapped";           // define same property on page object
Reflect.defineProperty(ev.wrappedJSObject,        // privileged reflection can operate on less privileged objects
  'propC', {
    get: exportFunction(() => {                  // getters must be exported like regular functions
      return 'propC';
    }, window)
  }
);

window.eval(`
 document.addEventListener("click", (e) => {
 console.log(e instanceof Event, e.propA, e.propB, e.propC);
 });
`);

document.dispatchEvent(ev); // true, undefined, "unwrapped", "propC"

```

### Promise cloning



A Promise cannot be cloned directly using `cloneInto`, as Promise is not supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). However, the desired result can be achieved using `window.Promise` instead of `Promise`, and then cloning the resolution value like this:

 
```
const promise = new window.Promise((resolve) => {
  // if just a primitive, then cloneInto is not needed:
  // resolve("string is a primitive");

  // if not a primitive, such as an object, then the value must be cloned
  const result = { exampleKey: "exampleValue" };
  resolve(cloneInto(result, window));
});
// now the promise can be passed to the web page

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts>

runtime.connect()
=================



Make a connection between different contexts inside the extension.

 You can call this:

 * in an extension's content scripts, to establish a connection with the extension's background scripts (or similarly privileged scripts, like popup scripts or options page scripts).
* in an extension's background scripts (or similarly privileged scripts), to establish a connection with a different extension.

 Note that you can't use this function to connect an extension to its content scripts. To do this, use [`tabs.connect()`](../tabs/connect).

 By default, this connection enables the extension to exchange messages with itself or any other extension (if `extensionId` is specified). However, the [`externally_connectable`](../../manifest.json/externally_connectable) manifest key can be used to limit communication to specific extensions and enable communication with websites. Connections within the extension trigger the [`runtime.onConnect`](onconnect) event, connections from other extensions or web pages trigger the [`runtime.onConnectExternal`](onconnectexternal) event.



Syntax
------



```
let port = browser.runtime.connect(
  extensionId, // optional string
  connectInfo  // optional object
)

```
### Parameters


 
`extensionId` Optional
  `string`. The ID of the extension to connect to. If the target has set an ID explicitly using the [browser\_specific\_settings](../../manifest.json/browser_specific_settings) key in manifest.json, then `extensionId` should have that value. Otherwise it should have the ID that was generated for the target.

  
`connectInfo` Optional
  `object`. Details of the connection:

  
`name` Optional
  `string`. Will be passed into [`runtime.onConnect`](onconnect) for processes that are listening for the connection event.

  
`includeTlsChannelId` Optional
  `boolean`. Whether the TLS channel ID will be passed into [`runtime.onConnectExternal`](onconnectexternal) for processes that are listening for the connection event.

    ### Return value


[`runtime.Port`](port). Port through which messages can be sent and received. The port's `onDisconnect` event is fired if the extension does not exist.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `connect` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



This content script:

 * connects to the background script and stores the `Port` in a variable called `myPort`.
* listens for messages on `myPort` and logs them.
* sends messages to the background script, using `myPort`, when the user clicks the document.

 
```
// content-script.js

let myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({greeting: "they clicked the page!"});
});

```
 The corresponding background script:

 * listens for connection attempts from the content script.
* when it receives a connection attempt:
	+ stores the port in a variable named `portFromCS`.
	+ sends the content script a message using the port.
	+ starts listening to messages received on the port, and logs them.
* sends messages to the content script, using `portFromCS`, when the user clicks the extension's browser action.

 
```
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({greeting: "hi there content script!"});
  portFromCS.onMessage.addListener((m) => {
    console.log("In background script, received message from content script")
    console.log(m.greeting);
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({greeting: "they clicked the button!"});
});

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-connect) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connect>

runtime.onConnect
=================


Fired when a connection is made with either an extension process or a content script.


Syntax
------




```
browser.runtime.onConnect.addListener(listener)
browser.runtime.onConnect.removeListener(listener)
browser.runtime.onConnect.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `port`  A [`runtime.Port`](port) object connecting the current script to the other context it is connecting to.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onConnect` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



This content script:

 * connects to the background script, and stores the `Port` in a variable `myPort`
* listens for messages on `myPort`, and logs them
* sends messages to the background script, using `myPort`, when the user clicks the document

 
```
// content-script.js

let myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({greeting: "they clicked the page!"});
});

```
 The corresponding background script:

 * listens for connection attempts from the content script
* when it receives a connection attempt:
	+ stores the port in a variable named `portFromCS`
	+ sends the content script a message using the port
	+ starts listening to messages received on the port, and logs them
* sends messages to the content script, using `portFromCS`, when the user clicks the extension's browser action

 
```
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({greeting: "hi there content script!"});
  portFromCS.onMessage.addListener((m) => {
    console.log("In background script, received message from content script")
    console.log(m.greeting);
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({greeting: "they clicked the button!"});
});

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onConnect) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnect>

runtime.onMessage
=================



Use this event to listen for messages from another part of your extension.

 Some example use cases are:

 * **in a [content script](../../anatomy_of_a_webextension#content_scripts)**, to listen for messages from a [background script.](../../anatomy_of_a_webextension#background_scripts)
* **in a background script**, to listen for messages from a content script.
* **in an [options page](../../anatomy_of_a_webextension#options_pages) or [popup](../../user_interface#popups) script**, to listen for messages from a background script.
* **in a background script**, to listen for messages from an options page or popup script.

 To send a message that is received by the `onMessage()` listener, use [`runtime.sendMessage()`](sendmessage) or (to send a message to a content script) [`tabs.sendMessage()`](../tabs/sendmessage).

  **Note:** Avoid creating multiple `onMessage()` listeners for the same type of message, because the order in which multiple listeners will fire is not guaranteed.

 If you want to guarantee the delivery of a message to a specific end point, use the [connection-based approach to exchange messages](../../content_scripts#connection-based_messaging).

  Along with the message itself, the listener is passed:

 * a `sender` object giving details about the message sender.
* a `sendResponse()` function that can be used to send a response back to the sender.

 You can send a synchronous response to the message by calling the `sendResponse()` function inside your listener. [See an example](#sending_a_synchronous_response).

 To send an asynchronous response, there are two options:

 * return `true` from the event listener. This keeps the `sendResponse()` function valid after the listener returns, so you can call it later. [See an example](#sending_an_asynchronous_response_using_sendresponse).
* return a `Promise` from the event listener, and resolve when you have the response (or reject it in case of an error). [See an example](#sending_an_asynchronous_response_using_a_promise).

  **Note:** You can also use a [connection-based approach to exchange messages](../../content_scripts#connection-based_messaging).

 

Syntax
------




```
browser.runtime.onMessage.addListener(listener)
browser.runtime.onMessage.removeListener(listener)
browser.runtime.onMessage.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether at least one listener is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `listener`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `message`  `object`. The message itself. This is a serializable object (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)).

  `sender`  A [`runtime.MessageSender`](messagesender) object representing the sender of the message.

  `sendResponse`  A function to call, at most once, to send a response to the `message`. The function takes a single argument, which may be any serializable object (see [Data cloning algorithm](../../chrome_incompatibilities#data_cloning_algorithm)). This argument is passed back to the message sender.

 If you have more than one `onMessage()` listener in the same document, then only one may send a response.

 To send a response synchronously, call `sendResponse()` before the listener function returns.

 To send a response asynchronously:

 * either keep a reference to the `sendResponse()` argument and return `true` from the listener function. You will then be able to call `sendResponse()` after the listener function has returned.
* or return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) from the listener function and resolve the promise when the response is ready. This is a preferred way.

   The `listener` function can return either a Boolean or a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** If you pass an async function to `addListener()`, the listener will return a Promise for every message it receives, preventing other listeners from responding:

 
```
// don't do this
browser.runtime.onMessage.addListener(
  async (data, sender) => {
    if (data.type === 'handle\_me') { return 'done'; }
  }
);

```
 If you only want the listener to respond to messages of a certain type, you must define the listener as a non-`async` function, and return a Promise only for the messages the listener is meant to respond to — and otherwise return false or undefined:

 
```
browser.runtime.onMessage.addListener(
  (data, sender) => {
    if (data.type === 'handle\_me') {
      return Promise.resolve('done');
    }
    return false;
  }
);

```
   Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onMessage` | 26 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |
| `return_promise` | No | No | Yes | ? | No | 15.4 | ? | ? | Yes | ? | 15.4 | ? |


Examples
--------


### Simple example



This content script listens for click events on the web page. If the click was on a link, it messages the background page with the target URL:

 
```
// content-script.js

window.addEventListener("click", notifyExtension);

function notifyExtension(e) {
  if (e.target.tagName !== "A") {
    return;
  }
  browser.runtime.sendMessage({"url": e.target.href});
}

```
 The background script listens for these messages and displays a notification using the [`notifications`](../notifications) API:

 
```
// background-script.js

browser.runtime.onMessage.addListener(notify);

function notify(message) {
  browser.notifications.create({
    "type": "basic",
    "iconUrl": browser.extension.getURL("link.png"),
    "title": "You clicked a link!",
    "message": message.url
  });
}

```

### Sending a synchronous response



This content script sends a message to the background script when the user clicks on the page. It also logs any response sent by the background script:

 
```
// content-script.js

function handleResponse(message) {
  console.log(`background script sent a response: ${message.response}`);
}

function handleError(error) {
  console.log(`Error: ${error}`);
}

function sendMessage(e) {
  const sending = browser.runtime.sendMessage({content: "message from the content script"});
  sending.then(handleResponse, handleError);
}

window.addEventListener("click", sendMessage);

```
 Here is a version of the corresponding background script, that sends a response synchronously, from inside in the listener:

 
```
// background-script.js

function handleMessage(request, sender, sendResponse) {
  console.log(`content script sent a message: ${request.content}`);
  sendResponse({response: "response from background script"});
}

browser.runtime.onMessage.addListener(handleMessage);

```
 And here is another version which uses [`Promise.resolve()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve):

 
```
// background-script.js

function handleMessage(request, sender, sendResponse) {
  console.log(`content script sent a message: ${request.content}`);
  return Promise.resolve({response: "response from background script"});
}

browser.runtime.onMessage.addListener(handleMessage);

```

### Sending an asynchronous response using sendResponse



Here is an alternative version of the background script from the previous example. It sends a response asynchronously after the listener has returned. Note `return true;` in the listener: this tells the browser that you intend to use the `sendResponse` argument after the listener has returned.

 
```
// background-script.js

function handleMessage(request, sender, sendResponse) {
  console.log(`content script sent a message: ${request.content}`);
  setTimeout(() => {
    sendResponse({response: "async response from background script"});
  }, 1000);
  return true;
}

browser.runtime.onMessage.addListener(handleMessage);

```

### Sending an asynchronous response using a Promise



This content script gets the first `<a>` link on the page and sends a message asking if the link's location is bookmarked. It expects to get a Boolean response (`true` if the location is bookmarked, `false` otherwise):

 
```
// content-script.js

const firstLink = document.querySelector("a");

function handleResponse(isBookmarked) {
  if (isBookmarked) {
    firstLink.classList.add("bookmarked");
  }
}

browser.runtime.sendMessage({
  url: firstLink.href
}).then(handleResponse);

```
 Here is the background script. It uses `[`bookmarks.search()`](../bookmarks/search)` to see if the link is bookmarked, which returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise):

 
```
// background-script.js

function isBookmarked(message, sender, response) {
  return browser.bookmarks.search({
    url: message.url
  }).then((results) => results.length > 0);
}

browser.runtime.onMessage.addListener(isBookmarked);

```
 If the asynchronous handler doesn't return a Promise, you can explicitly construct a promise. This rather contrived example sends a response after a 1-second delay, using [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout):

 
```
// background-script.js

function handleMessage(request, sender, sendResponse) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({response: "async response from background script"});
    }, 1000);
  });
}

browser.runtime.onMessage.addListener(handleMessage);

```

### Example extensions



* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify)
* [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
* [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [imagify](https://github.com/mdn/webextensions-examples/tree/master/imagify)
* [mocha-client-tests](https://github.com/mdn/webextensions-examples/tree/master/mocha-client-tests)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)
* [user-script-register](https://github.com/mdn/webextensions-examples/tree/master/user-script-register)
* [webpack-modules](https://github.com/mdn/webextensions-examples/tree/master/webpack-modules)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage>

i18n.getUILanguage()
====================



Gets the UI language of the browser. This is different from [`i18n.getAcceptLanguages`](getacceptlanguages) which returns the preferred user languages.

 See the [Internationalization](../../internationalization) page for a guide on using this function.



Syntax
------



```
browser.i18n.getUILanguage()

```
### Parameters


None.

### Return value


`string`. The browser UI language code as an [`i18n.LanguageCode`](languagecode).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getUILanguage` | 35 | 14 | 47Firefox 55 and earlier returns a language tag that's separated with the underscore character instead of hyphen, see [bug 1374552](https://bugzil.la/1374552). | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------




```
let uiLanguage = browser.i18n.getUILanguage();
console.log(uiLanguage);

//e.g. "fr"

```
  **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/#method-getUILanguage) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getUILanguage>

i18n.detectLanguage()
=====================



Detects the language of the provided text using the [Compact Language Detector](https://github.com/CLD2Owners/cld2) (CLD).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 See the [Internationalization](../../internationalization) page for a guide on using this function.



Syntax
------



```
let detectingLanguages = browser.i18n.detectLanguage(
  text                  // string
)

```
### Parameters


 `text`  `string`. User input string to be translated.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a result object. The result object has two properties:

  `isReliable`  `boolean`. Whether the language was detected reliably.

  `languages`  `array` of objects, each of which has two properties:

  `language`  [`i18n.LanguageCode`](languagecode). The detected language.

  `percentage`  `integer`. The percentage of the input string that was in the detected language.

    
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `detectLanguage` | 47 | 79 | 47 | ? | 34 | No | ? | ? | 10648–106The method existed but always threw an error. | ? | No | ? |


Examples
--------




```
function onLanguageDetected(langInfo) {
  for (const lang of langInfo.languages) {
    console.log(`Language is: ${lang.language}`);
    console.log(`Percentage is: ${lang.percentage}`);
  }
}

let text = "L'homme est né libre, et partout il est dans les fers."

let detecting = browser.i18n.detectLanguage(text);
detecting.then(onLanguageDetected);

```
  **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/#method-detectLanguage) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/detectLanguage>

Locale-specific message reference
=================================



Each internationalized extension has at least one file named `messages.json` that provides locale-specific strings. This page describes the format of `messages.json` files.

  **Note:** For information on how to internationalize your extensions, see our [i18n](../../internationalization) guide.

 

messages.json example
---------------------



The following code shows an example `messages.json file`, taken from our [notify-link-clicks-i18n example](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) extension. Only the "*name*" and "message" fields are required.

 
```
{
  "extensionName": {
    "message": "Notify link clicks i18n",
    "description": "Name of the extension."
  },

  "extensionDescription": {
    "message": "Shows a notification when the user clicks on links.",
    "description": "Description of the extension."
  },

  "notificationTitle": {
    "message": "Click notification",
    "description": "Title of the click notification."
  },

  "notificationContent": {
    "message": "You clicked $URL$.",
    "description": "Tells the user which link they clicked.",
    "placeholders": {
      "url" : {
        "content" : "$1",
        "example" : "https://developer.mozilla.org"
      }
    }
  }
}

```

Placement
---------


Your `messages.json` files need to be placed inside directories named after the locale each one is supporting — `en`, `de`, `ja`, etc. These in turn need to be placed inside a directory called `_locales`, inside the root of your extension.

Member details
--------------


This section describes each member that can appear in a `messages.json` file.

### name



Each top-level member is named after the name of the message string you are localizing, for example `"extensionName"` or `"notificationContent"` in the example above. Each name is case-insensitive, and acts as a key allowing you to retrieve the localized message text.

 The name can include the following characters:

 * A-Z
* a-z
* 0-9
* \_ (underscore)
* @

  **Note:** You shouldn't define names that start with @@. Such names are reserved for [predefined messages](../../internationalization#predefined_messages).

 
### message



At least this property must be set for every string. The `"message"` member contains a localized string that can contain [placeholders](#placeholders). You can use:

 * *$placeholder\_name$* (case insensitive) to insert a particular placeholder (for example $URL$ in the example above) into your string.
* `$1`, `$2`, `$3`, etc. to directly insert values obtained from a [`i18n.getMessage()`](getmessage) call into your string.

 Other points to note:

 * Any number of consecutive dollar signs appearing in strings are replaced by the same number of dollar signs minus one. So, $$ > $, $$$ > $$, etc.
* When the locale file is read, tokens matching `/\$([a-z0-9_@]+)\$/i` are replaced with the matching value from the string's "placeholders" object. These substitutions happen prior to processing any `/\$\d/` tokens in the message.
* When a locale string is used, tokens matching `/\$\d+/` are replaced with the replacements passed to [`i18n.getMessage()`](getmessage).
* `getMessage()` won't process calls with more than 9 placeholders/substitutions.


### description



Optional The `"description"` member should contain a description of the message string's contents, aimed to provide a translator with help to create the best translation possible of the string.


### placeholders



Optional The `"placeholders"` member defines one or more placeholder substrings to be used within the message — these can be used to hardcode items that you don't want translated, or refer to variables.

 Each placeholder substring definition has a number of values of its own:

 
```
"url" : {
  "content" : "$1",
  "example" : "https://developer.mozilla.org"
}

```
 #### placeholder name

 The placeholder name is used to represent the placeholder in the substitution string (e.g. `"url"` becomes `$url$`). It is case insensitive and can contain the same characters as a message string [name](#name).

 #### content

 The "content" item defines the content of the placeholder. This can be a hardcoded string, such as "My placeholder", but it can also include values obtained from a [`i18n.getMessage()`](getmessage) call. This property is required. For more information, see [Retrieving message strings from JavaScript](../../internationalization#retrieving_message_strings_from_javascript).

 #### example


Optional The optional "example" item is again intended to help translators by showing them an example of how the placeholder would appear to end users, allowing them to make the best choice when localizing the file.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/Locale-Specific_Message_reference>

runtime.id
==========


The ID of the extension.


Syntax
------



```
let myAddonId = browser.runtime.id;

```
### Value


A `string` representing the add-on ID. If the extension specifies an ID in its [`browser_specific_settings`](../../manifest.json/browser_specific_settings) manifest.json key, `runtime.id` contains that value. Otherwise, `runtime.id` contains the ID that was generated for the extension.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `id` | 22 | 14 | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#property-id) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/id>

devtools.inspectedWindow
========================



 **Note:** This page describes the WebExtensions devtools APIs as they exist in Firefox 54. Although the APIs are based on the [Chrome devtools APIs](https://developer.chrome.com/docs/extensions/mv3/devtools/), there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see [Limitations of the devtools APIs](../../extending_the_developer_tools#limitations_of_the_devtools_apis).

  The `devtools.inspectedWindow` API lets a devtools extension interact with the window that the developer tools are attached to.

 Like all the `devtools` APIs, this API is only available to code running in the document defined in the [devtools\_page](../../manifest.json/devtools_page) manifest.json key, or in other devtools documents created by the extension (such as the document hosted by a panel the extension created). See [Extending the developer tools](../../extending_the_developer_tools) for more.



Properties
----------


 [`devtools.inspectedWindow.tabId`](inspectedwindow/tabid)  The ID of the window that the developer tools are attached to.

  Functions
---------


 [`devtools.inspectedWindow.eval()`](inspectedwindow/eval)  Evaluate some JavaScript in the target window.

  [`devtools.inspectedWindow.reload()`](inspectedwindow/reload)  Reload the target window's document.

  Example extensions
------------------


* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `eval` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `reload` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `tabId` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools.inspectedWindow`](https://developer.chrome.com/docs/extensions/reference/devtools_inspectedWindow/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow>

menus.getTargetElement()
========================



Returns the element for a given `targetElementId`

 This method is available to all extension script contexts (content scripts, background pages and other extension pages) and returns the element for a given `info.targetElementId`, provided that the element still exists in the document where the method is invoked.

 The method only works in the document that includes the right-clicked element and the `targetElementId` expires when the user opens another context menu.

  **Note:** `menus.getTargetElement` only return the requested element if called in the same context as the document that contains the element, for example using content scripts (as shown in the example below).

  An extension requires the "menus" permission to use this API.



Syntax
------



```
let elem = browser.menus.getTargetElement(targetElementId);

```
### Parameters


 `targetElementId`  The property of the `[`menus.OnClickData`](onclickdata)` object passed to the `[`menus.onClicked`](onclicked)` handler or `[`menus.onShown`](onshown)` event.

  ### Return value


The element referred to by the `targetElementId` parameter. If the `targetElementId` parameter is not valid, the method returns `null`.

Examples
--------



The following example uses the `getTargetElement` method to get the element referred to by the `info.targetElementId` property and then removes it.

 
```
browser.menus.create({
  title: "Remove element",
  documentUrlPatterns: ["\*://\*/\*"],
  contexts: [
    "audio",
    "editable",
    "frame",
    "image",
    "link",
    "page",
    "password",
    "video",
  ],
  onclick(info, tab) {
    browser.tabs.executeScript(tab.id, {
      frameId: info.frameId,
      code: `browser.menus.getTargetElement(${info.targetElementId}).remove();`,
    });
  },
});

```

### Example extensions


* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTargetElement` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |


See also
--------


* [`menus.create`](create)
* [`menus.OnClickData`](onclickdata)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/getTargetElement>

runtime.MessageSender
=====================



An object containing information about the sender of a message or connection request; this is passed to the [`runtime.onMessage()`](onmessage) listener.

 It is also a property of [`runtime.Port`](port), but only in the `Port` instance passed into the [`runtime.onConnect()`](onconnect) or [`runtime.onConnectExternal()`](onconnectexternal) listeners.



Type
----



Values of this type are objects. They contain the following properties:

  
`tab` Optional
  [`tabs.Tab`](../tabs/tab). The [`tabs.Tab`](../tabs/tab) which opened the connection. This property will only be present when the connection was opened from a tab (including content scripts).

  
`frameId` Optional
  `integer`. The frame that opened the connection. Zero for top-level frames, positive for child frames. This will only be set when `tab` is set.

  
`id` Optional
  `string`. The ID of the extension that sent the message, if the message was sent by an extension. If the sender set an ID explicitly using the [browser\_specific\_settings](../../manifest.json/browser_specific_settings) key in manifest.json, then `id` will have this value. Otherwise it will have the ID that was generated for the sender.

  
`url` Optional
  `string`. The URL of the page or frame hosting the script that sent the message.

 If the sender is a script running in an extension page (such as a [background page](../../anatomy_of_a_webextension#background_scripts), an [options page](../../anatomy_of_a_webextension#options_pages), or a [browser action](../../anatomy_of_a_webextension#browser_actions_2) or [page action](../../anatomy_of_a_webextension#page_actions) popup), the URL will be in the form `"moz-extension://<extension-internal-id>/path/to/page.html"`. If the sender is a background script and you haven't included a background page, it will be `"moz-extension://<extension-internal-id>/_generated_background_page.html"`.

 >If the sender is a script running in a web page (including content scripts as well as normal page scripts), then `url` will be the web page URL. If the script is running in an iframe, `url` will be the iframe's URL.

  
`tlsChannelId` Optional
  `string`. The TLS channel ID of the page or frame that opened the connection, if requested by the extension, and if available.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MessageSender` | 26 | 14 | 45Before version 54, 'id' was the add-on's internal UUID, not the add-on ID. | ? | 15 | 14 | ? | ? | 48Before version 54, 'id' was the add-on's internal UUID, not the add-on ID. | ? | 15 | ? |
| `frameId` | 41 | 14 | 45 | ? | 28 | 14 | ? | ? | 48 | ? | 15 | ? |
| `tlsChannelId` | 32 | 79 | 45 | ? | 19 | No | ? | ? | 48 | ? | No | ? |
| `url` | 28 | 14The `url` is missing when the message was sent by an extension view. | 45 | ? | 15 | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-MessageSender) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/MessageSender>

devtools.network
================



The `devtools.network` API lets a devtools extension get information about network requests associated with the window that the devtools are attached to (the inspected window).

 Like all the `devtools` APIs, this API is only available to code running in the document defined in the [devtools\_page](../../manifest.json/devtools_page) manifest.json key, or in other devtools documents created by the extension (such as the panel's own document). See [Extending the developer tools](../../extending_the_developer_tools) for more.



Functions
---------


 [`devtools.network.getHAR()`](network/gethar)  Get a [HAR log](http://www.softwareishard.com/blog/har-12-spec/#log) for the page loaded in the current tab.

  Events
------


 [`devtools.network.onNavigated`](network/onnavigated)  Fired when the user navigates the inspected window to a new page.

  [`devtools.network.onRequestFinished`](network/onrequestfinished)  Fired when the a network request has finished and its details are available to the extension.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getHAR` | Yes | 79 | 60The returned HAR log will be empty unless the user has previously activated the browser's network panel at least once. | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onNavigated` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `onRequestFinished` | Yes | 79 | 6160–61This event will only start firing after the user has activated the browser's network panel at least once. | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools.network`](https://developer.chrome.com/docs/extensions/reference/devtools_network/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/network>

devtools.inspectedWindow.tabId
==============================



The ID of the [`tab`](../../tabs/tab) that this instance of the devtools is attached to, represented as a number.

 This can be sent to the extension's background page, so that background page can use the [`tabs`](../../tabs) API to interact with the tab:

 
```
// devtools-panel.js

const scriptToAttach = "document.body.innerHTML = 'Hi from the devtools';";

attachContentScriptButton.addEventListener("click", () => {
  browser.runtime.sendMessage({
    tabId: browser.devtools.inspectedWindow.tabId,
    script: scriptToAttach
  });
});

```
 
```
// background.js

function handleMessage(request, sender, sendResponse) {
  browser.tabs.executeScript(request.tabId, {
    code: request.script
  });
}

browser.runtime.onMessage.addListener(handleMessage);

```


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `tabId` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow/tabId>

storage.managed
===============


A [`storage.StorageArea`](storagearea) object that represents the `managed` storage area. Items in `managed` storage are set by the domain administrator or other native applications installed on the user's computer and are read-only for the extension. Trying to modify this storage area results in an error.


Provisioning managed storage
----------------------------



The procedure for provisioning managed storage varies between browsers. For Chrome instructions, see the ["Manifest for storage areas"](https://developer.chrome.com/docs/extensions/mv3/manifest/storage/) article.

 For Firefox, you need to create a JSON manifest file in a specific format and location. For the details of manifest syntax and location, see [Native manifests](../../native_manifests).

 Here's an example manifest:

 
```
{
  "name": "favourite-colour-examples@mozilla.org",
  "description": "ignored",
  "type": "storage",
  "data": {
    "colour": "management thinks it should be blue!"
  }
}

```
 Given this manifest, the [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour) extension could access the data using code like this:

 
```
let storageItem = browser.storage.managed.get('colour');
storageItem.then((res) => {
  console.log(`Managed colour is: ${res.colour}`);
});

```

Methods
-------



The `managed` object implements the methods defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.managed.get()`](storagearea/get)  Retrieves one or more items from the storage area.

  [`storage.managed.getBytesInUse()`](storagearea/getbytesinuse)  Gets the amount of storage space (in bytes) used for one or more items in the storage area.

  
Events
------



The `managed` object implements the events defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.managed.onChanged`](storagearea/onchanged)  Fires when one or more items in the storage area change.

  
### Example extensions


* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `managed` | Yes | 79 | 57["Platform-specific storage backends, such as Windows registry keys, are not supported.", "Enforcement of extension-provided storage schemas is not supported.", "The `onChanged` event is not supported."] | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#property-managed) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/managed>

runtime.connectNative()
=======================



Connects the extension to a native application on the user's computer. This takes the name of a native application as a parameter. It starts the native application and returns a [`runtime.Port`](port) object to the caller. The caller can then use the `Port` to exchange messages with the native application using `Port.postMessage()` and `port.onMessage`. The native application will run until it exits itself, or the caller calls `Port.disconnect()`, or the page that created the `Port` is destroyed. Once the `Port` is disconnected the browser will give the process a few seconds to exit gracefully, and then kill it if it has not exited.

 For more information, see [Native messaging](../../native_messaging).



Syntax
------



```
let port = browser.runtime.connectNative(
  application // string
)

```
### Parameters


 `application`  `string`. The name of the native application to connect to. This must match the "name" property in the [native application's manifest file](../../native_messaging#app_manifest).

  ### Return value


A [`runtime.Port`](port) object. The port which the caller can use to exchange messages with the native application.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `connectNative` | 29 | 15 | 50 | ? | 16 | 14See the documentation on developer.apple.com about native messaging in Safari. | ? | ? | 68 | ? | 15See the documentation on developer.apple.com about native messaging in Safari. | ? |


Examples
--------



This example connects to the native application "ping\_pong" and starts listening for messages from it. It also sends the native application a message when the user clicks a browser action icon:

 
```
/\*
On startup, connect to the "ping\_pong" app.
\*/
let port = browser.runtime.connectNative("ping\_pong");

/\*
Listen for messages from the app.
\*/
port.onMessage.addListener((response) => {
  console.log(`Received: ${response}`);
});

/\*
On a click on the browser action, send the app a message.
\*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending: ping");
  port.postMessage("ping");
});

```

### Example extensions



* [native-messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-connectNative) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connectNative>

runtime.sendNativeMessage()
===========================



Sends a single message from an extension to a native application.

 This takes two mandatory parameters: the name of the native application and a JSON object which is the message to send it. The browser will launch the native application and deliver the message.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). The first message sent by the native application is treated as a response to the `sendNativeMessage()` call, and the promise will be fulfilled with this message as a parameter. Note that you can't use [`runtime.onMessage`](onmessage) to get responses from the application: you must use the callback function instead.

 A new instance of the application is launched for call to `runtime.sendNativeMessage()`. The browser will terminate the native application after getting a reply. To terminate a native application, the browser will close the pipe, give the process a few seconds to exit gracefully, and then kill it if it has not exited.

 For more information, see [Native messaging](../../native_messaging).



Syntax
------



```
let sending = browser.runtime.sendNativeMessage(
  application,             // string
  message                  // object
)

```
### Parameters


 `application`  `string`. The name of the native application. This must match the "name" property in the [native application's manifest file](../../native_messaging#app_manifest).

  `message`  `object`. A JSON object that will be sent to the native application.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the sender sent a response, this will be fulfilled with the response as a JSON object. Otherwise it will be fulfilled with no arguments. If an error occurs while connecting to the native application, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sendNativeMessage` | 29 | 15 | 50 | ? | 16 | 14See the documentation on developer.apple.com about native messaging in Safari. | ? | ? | 68 | ? | 15See the documentation on developer.apple.com about native messaging in Safari. | ? |


Examples
--------



Here's a background script that sends a "ping" message to the "ping\_pong" app and logs the response, whenever the user clicks the browser action:

 
```
function onResponse(response) {
  console.log(`Received ${response}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

/\*
On a click on the browser action, send the app a message.
\*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending: ping");
  let sending = browser.runtime.sendNativeMessage("ping\_pong", "ping");
  sending.then(onResponse, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-sendNativeMessage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendNativeMessage>

devtools.panels
===============



 **Note:** Although the APIs are based on the [Chrome devtools APIs](https://developer.chrome.com/docs/extensions/mv3/devtools/), there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see [Limitations of the devtools APIs](../../extending_the_developer_tools#limitations_of_the_devtools_apis).

  The `devtools.panels` API lets a devtools extension define its user interface inside the devtools window.

 The devtools window hosts a number of separate tools - the JavaScript Debugger, Network Monitor, and so on. A row of tabs across the top lets the user switch between the different tools. The window hosting each tool's user interface is called a "panel".

 With the `devtools.panels` API you can create new panels in the devtools window.

 Like all the `devtools` APIs, this API is only available to code running in the document defined in the [devtools\_page](../../manifest.json/devtools_page) manifest.json key, or in other devtools documents created by the extension (such as the panel's own document). See [Extending the developer tools](../../extending_the_developer_tools) for more.



Types
-----


 [`devtools.panels.ElementsPanel`](panels/elementspanel)  Represents the HTML/CSS inspector in the browser's devtools.

  [`devtools.panels.ExtensionPanel`](panels/extensionpanel)  Represents a devtools panel created by the extension.

  [`devtools.panels.ExtensionSidebarPane`](panels/extensionsidebarpane)  Represents a pane that an extension has added to the HTML/CSS inspector in the browser's devtools.

  Properties
----------


 [`devtools.panels.elements`](panels/elements)  A reference to an [`ElementsPanel`](panels/elementspanel) object.

  [`devtools.panels.themeName`](panels/themename)  The name of the current devtools theme.

  Functions
---------


 [`devtools.panels.create()`](panels/create)  Creates a new devtools panel.

  Events
------


 [`devtools.panels.onThemeChanged`](panels/onthemechanged)  Fired when the devtools theme changes.

  Example extensions
------------------


* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `elements` | Yes | 79 | 56 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `onThemeChanged` | No | No | 55 | ? | No | 16 | ? | ? | No | ? | No | ? |
| `themeName` | 59 | 79 | 55 | ? | 41 | 16 | ? | ? | No | ? | No | ? |


Example extensions
------------------



* [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels)

  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels>

devtools.inspectedWindow.eval()
===============================



Executes JavaScript in the window that the devtools are attached to.

 This is somewhat like using [`tabs.executeScript()`](../../tabs/executescript) to attach a content script, but with two main differences:

 First, the JavaScript can use a set of [special commands that browsers typically provide in their devtools console implementation](#helpers): for example, using "$0" to refer to the element currently selected in the Inspector.

 Second, the JavaScript you execute can see any changes made to the page by scripts that the page loaded. This is in contrast to content scripts, which see the page [as it would exist if no page scripts were loaded](../../../content_scripts#dom_access). However, note that the isolation provided by content scripts is a deliberate security feature, intended to make it harder for malicious or uncooperative web pages to confuse or subvert WebExtensions APIs by redefining DOM functions and properties. This means you need to be very careful if you waive this protection by using `eval()`, and should use content scripts unless you need to use `eval()`.

 The script is evaluated by default in the main frame of the page. The script must evaluate to a value that can be represented as JSON (meaning that, for example, it may not evaluate to a function or an object that contains any functions). By default, the script does not see any content scripts attached to the page.

 You can't call `eval()` on privileged browser windows such as "about:addons".

 You can optionally provide an `options` parameter, which includes options to evaluate the script in a different frame or in the context of attached content scripts. Note that Firefox does not yet support the `options` parameter.

 The `eval()` function returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to the evaluated result of the script or to an error.



Helpers
-------



The script gets access to a number of objects that help the injected script interact with the developer tools. The following helpers are currently supported:

  `$0`  Contains a reference to the element that's currently selected in the devtools Inspector.

  `inspect()`  Given an object, if it is an DOM element in the page, selects it in the devtools Inspector, otherwise it creates an object preview in the webconsole.

   [See some examples.](#examples)


Syntax
------



```
let evaluating = browser.devtools.inspectedWindow.eval(
  expression,       // string
  options           // object
)

```
### Parameters


 `expression`  `string`. The JavaScript expression to evaluate. The string must evaluate to an object that can be represented as JSON, or an exception will be thrown. For example, `expression` must not evaluate to a function.

  
`options` Optional
  `object`. Options for the function (Note that Firefox does not yet support this options), as follows:

  
`frameURL` Optional
  `string`. The URL of the frame in which to evaluate the expression. If this is omitted, the expression is evaluated in the main frame of the window.

  
`useContentScriptContext` Optional
  `boolean`. If `true`, evaluate the expression in the context of any content scripts that this extension has attached to the page. If you set this option, then you must have actually attached some content scripts to the page, or a Devtools error will be thrown.

  
`contextSecurityOrigin` Optional
  `string`. Evaluate the expression in the context of a content script attached by a different extension, whose origin matches the value given here. This overrides `useContentScriptContext`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `array` containing two elements.

 If no error occurred, element 0 will contain the result of evaluating the expression, and element 1 will be `undefined`.

 If an error occurred, element 0 will be `undefined`, and element 1 will contain an object giving details about the error. Two different sorts of errors are distinguished:

 * errors encountered evaluating the JavaScript (for example, syntax errors in the expression). In this case, element 1 will contain:
	+ a boolean property `isException`, set to `true`
	+ a string property `value`, giving more details.
* other errors (for example, an expression that evaluates to an object that can't be represented as JSON). In this case, element 1 will contain:
	+ a boolean property `isError`, set to `true`
	+ a string property `code` containing an error code.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `$0` | Yes | 79 | 55 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `eval` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `inspect` | Yes | 79 | 55 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `options` | Yes | 79 | No | ? | Yes | 16 | ? | ? | No | ? | No | ? |


Examples
--------



This tests whether jQuery is defined in the inspected window, and logs the result. Note that this wouldn't work in a content script, because even if jQuery were defined, the content script would not see it.

 
```
function handleError(error) {
  if (error.isError) {
    console.log(`Devtools error: ${error.code}`);
  } else {
    console.log(`JavaScript error: ${error.value}`);
  }
}

function handleResult(result) {
  console.log(result);
  if (result[0] !== undefined) {
    console.log(`jQuery: ${result[0]}`);
  } else if (result[1]) {
    handleError(result[1]);
  }
}

const checkjQuery = "typeof jQuery !== 'undefined'";

evalButton.addEventListener("click", () => {
  browser.devtools.inspectedWindow.eval(checkjQuery)
    .then(handleResult);
});

```

### Helper examples



This uses the `$0` helper to set the background color of the element that's currently selected in the Inspector:

 
```
const evalButton = document.querySelector("#reddinate");
const evalString = "$0.style.backgroundColor = 'red'";

function handleError(error) {
  if (error.isError) {
    console.log(`Devtools error: ${error.code}`);
  } else {
    console.log(`JavaScript error: ${error.value}`);
  }
}

function handleResult(result) {
  if (result[1]) {
    handleError(result[1]);
  }
}

evalButton.addEventListener("click", () => {
  browser.devtools.inspectedWindow.eval(evalString)
    .then(handleResult);
});

```
 This uses the `inspect()` helper to select the first <h1> element in the page:

 
```
const inspectButton = document.querySelector("#inspect");
const inspectString = "inspect(document.querySelector('h1'))";

function handleError(error) {
  if (error.isError) {
    console.log(`Devtools error: ${error.code}`);
  } else {
    console.log(`JavaScript error: ${error.value}`);
  }
}

function handleResult(result) {
  if (result[1]) {
    handleError(result[1]);
  }
}

inspectButton.addEventListener("click", () => {
  browser.devtools.inspectedWindow.eval(inspectString)
    .then(handleResult);
});

```
  **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow/eval>

Context menu items
==================



This user interface option adds one or more items to a browser context menu. This is the context menu available when a user right-clicks on a web page. Tabs can have context menus also, available through the [browser.menus API](../api/menus).

  ![Example of content menu items added by a WebExtension, from the context-menu-demo example] 

 You would use this option to expose features that are relevant to specific browser or web page contexts. For example, you could show features to open a graphic editor when the user clicks on an image or offer a feature to save page content when part of a page is selected. You can add plain menu items, checkbox items, radio button groups, and separators to menus. Once a context menu item has been added using [`contextMenus.create`](../api/menus/create) it's displayed in all browser tabs, but you can hide it by removing it with [`contextMenus.remove`](../api/menus/remove).

 The full list of supported contexts is available at [`menus.ContextType`](../api/menus/contexttype) and includes contexts outside of a web page, such as bookmark items in the browser UI. For example, the "[Open bookmark in Container Tab](https://github.com/Rob--W/bookmark-container-tab)" extension adds a menu item that allows the user to open a bookmark URL in a new container tab:

  ![A context menu with "open in new container tab" submenu highlighted. The submenu shows personal, work, banking, shopping, and Facebook contextual identities. There is an option at the top of the submenu to select no container.] 



Specifying context menu items
-----------------------------



You manage context menu items programmatically, using the [`contextMenus`](../api/menus) API. However, you need to request the `contextMenus` permission in your manifest.json to be able to take advantage of the API.

 
```
"permissions": ["contextMenus"]

```
 You can then add (and update or delete) the context menu items in your extension's background script. To create a menu item you specify an id, its title, and the context menus it should appear on:

 
```
browser.contextMenus.create(
  {
    id: "log-selection",
    title: browser.i18n.getMessage("contextMenuItemSelectionLogger"),
    contexts: ["selection"],
  },
  onCreated
);

```
 Your extension then listens for clicks on the menu items. The passed information about the item clicked, the context where the click happened, and details of the tab where the click took place can then be used to invoke the appropriate extension functionality.

 
```
browser.contextMenus.onClicked.addListener((info, tab) => {
  switch (info.menuItemId) {
    case "log-selection":
      console.log(info.selectionText);
      break;
    // …
  }
});

```

Icons
-----


For details on how to create icons to use with your context menu, see [Iconography](https://acorn.firefox.com/latest/styles/iconography.html) in the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------



The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub contains two examples of extensions that implement context menu items:

 * [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo) adds several items to the browser's context menu.
* [context-menu-copy-link-with-types](https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types) adds a context menu item to links that copies the link URL to the clipboard, as plain text and rich HTML.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items>

Notifications
=============



Notifications allow you to communicate information about your extension or its content using the underlying operating system's notification service.

  ![Click notification in the top right corner of the browser window.] 

 Notifications can include a call to action for the user, and your add-on can listen for the user clicking the notification or the notification closing.



Specifying notifications
------------------------



You manage notifications programmatically, using the [`notifications`](../api/notifications) API. To use this API you must request the `notifications` permission in your manifest.json:

 
```
"permissions": ["notifications"]

```
 You then use [`notifications.create`](../api/notifications/create) to create your notifications, as in this example from [notify-link-clicks-i18n:](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)

 
```
const title = browser.i18n.getMessage("notificationTitle");
const content = browser.i18n.getMessage("notificationContent", message.url);
browser.notifications.create({
  type: "basic",
  iconUrl: browser.extension.getURL("icons/link-48.png"),
  title,
  message: content,
});

```
 This code creates a notification with an icon, title, and message.

 If the notification includes a call to action, you can listen for the user clicking the notification to call the function to handle the action:

 
```
browser.notifications.onClicked.addListener(handleClick);

```
 If you are issuing calls to action through notifications, you will also want to define the optional notification `id`, so you can figure out which call to action the user has selected.


Icons
-----


For details on how to create icons to use with your notification, see [Iconography](https://acorn.firefox.com/latest/styles/iconography.html) in the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n) example which implements notifications.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications>

Address bar suggestions
=======================



Using the [`omnibox`](../api/omnibox) API, extensions can customize the suggestions offered in the browser address bar's drop-down when the user enters a keyword.

  ![Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions.] 

 This enables your extension to, for example, search a library of free ebooks or, as in the example above, a repository of code examples.



Specifying the omnibox customization
------------------------------------



You tell your extension that it is going to customize the address bar suggestions by including the [omnibox](../manifest.json/omnibox) key and definition of the trigger keyword in its [manifest.json](../manifest.json) file:

 
```
  "omnibox": { "keyword" : "cs" }

```
 In the extension's background JavaScript file, using [`omnibox.setDefaultSuggestion()`](../api/omnibox/setdefaultsuggestion), you can optionally define the first suggestion to be displayed in the address bar drop-down. Use this to provide a hint on how to use the feature:

 
```
browser.omnibox.setDefaultSuggestion({
  description: `Search the Firefox codebase
 (e.g. "hello world" | "path:omnibox.js onInputChanged")`
});

```
 You can then add the code to provide the customized content by listening for [`omnibox.onInputStarted`](../api/omnibox/oninputstarted), which is dispatched when the user has typed the keyword and a space, and [`omnibox.onInputChanged`](../api/omnibox/oninputchanged), which is dispatched whenever the user updates the address bar entry. You can then populate the suggestions, in this case building a [search of mozilla-central](https://searchfox.org/mozilla-central) using the term entered by the user:

 
```
browser.omnibox.onInputChanged.addListener((text, addSuggestions) => {
  let headers = new Headers({"Accept": "application/json"});
  let init = {method: 'GET', headers};
  let url = buildSearchURL(text);
  let request = new Request(url, init);

  fetch(request)
    .then(createSuggestionsFromResponse)
    .then(addSuggestions);
});

```
 If the extension set a default suggestion using [`omnibox.setDefaultSuggestion()`](../api/omnibox/setdefaultsuggestion), then this will appear first in the drop-down.

 The extension can then listen for the user clicking one of the suggestions, using [`omnibox.onInputEntered`](../api/omnibox/oninputentered). If the default suggestion is clicked the user's custom term is returned, otherwise the suggestion's string is returned. This also passes information on the user's browser preferences for handling new links. In the code below the user's custom term is used to create a search, otherwise the suggested URL is opened:

 
```
browser.omnibox.onInputEntered.addListener((text, disposition) => {
  let url = text;
  if (!text.startsWith(SOURCE\_URL)) {
    // Update the URL if the user clicks on the default suggestion.
    url = `${SEARCH\_URL}?q=${text}`;
  }
  switch (disposition) {
    case "currentTab":
      browser.tabs.update({url});
      break;
    case "newForegroundTab":
      browser.tabs.create({url});
      break;
    case "newBackgroundTab":
      browser.tabs.create({url, active: false});
      break;
  }
});

```

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search) example which customizes the search bar.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox>

devtools panels
===============



 **Note:** This feature is available since Firefox 54.

  When an extension provides tools that are of use to developers, it's possible to add a UI for them to the browser's developer tools as a new panel.

  ![Simple example showing the addition of "My panel" to the Developer Tools tabs.] 



Specifying a developer tools panel
----------------------------------



A developer tools panel is added using the [`devtools.panels`](../api/devtools/panels) API, which in turn needs to be run from a special devtools page.

 Add the devtools page by including the [`devtools_page`](../manifest.json/devtools_page) key in extension's [manifest.json](../manifest.json) and provide the location of the page's HTML file in the extension:

 
```
"devtools\_page": "devtools-page.html"

```
 From the devtools page, call a script that will add the devtools panel:

 
```
<body>
  <script src="devtools.js"></script>
</body>

```
 In the script, create the devtools panel by specifying the panel's title, icon, and HTML file that provides the panel's content:

 
```
function handleShown() {
  console.log("panel is being shown");
}

function handleHidden() {
  console.log("panel is being hidden");
}

browser.devtools.panels
  .create(
    "My Panel", // title
    "icons/star.png", // icon
    "devtools/panel/panel.html" // content
  )
  .then((newPanel) => {
    newPanel.onShown.addListener(handleShown);
    newPanel.onHidden.addListener(handleHidden);
  });

```
 The extension can now run code in the inspected window using [`devtools.inspectedWindow.eval()`](../api/devtools/inspectedwindow/eval) or by injecting a content script via the background script by passing a message. You can find more details on how to do this in [Extending the developer tools.](../extending_the_developer_tools)


Developer panel design
----------------------


For details on how to design your developer panel's web page to match the style of Firefox, see the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Icons
-----


For details on how to create icons to use with your developer tools panel, see [Iconography](https://acorn.firefox.com/latest/styles/iconography.html) in the [Acorn Design System](https://acorn.firefox.com/latest/acorn.html) documentation.

Examples
--------


The [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub includes the [devtools-panels](https://github.com/mdn/webextensions-examples/tree/master/devtools-panels) example which implements a devtools panel.



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels>

webRequest.onBeforeSendHeaders
==============================



This event is triggered before sending any HTTP data, but after all HTTP headers are available. This is a good place to listen if you want to modify HTTP request headers.

 To have the request headers passed into the listener along with the rest of the request data, pass `"requestHeaders"` in the `extraInfoSpec` array.

 To modify the headers synchronously: pass `"blocking"` in `extraInfoSpec`, then in your event listener, return a [`BlockingResponse`](blockingresponse) with a property named `requestHeaders`, whose value is the set of request headers to send.

 To modify the headers asynchronously: pass `"blocking"` in `extraInfoSpec`, then in your event listener, return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which is resolved with a `BlockingResponse`.

 If you use `"blocking"`, you must have the ["webRequestBlocking" API permission](../../manifest.json/permissions#api_permissions) in your manifest.json.

 It is possible for extensions to conflict here. If two extensions listen to `onBeforeSendHeaders` for the same request, then the second listener will see modifications made by the first listener, and will be able to undo any changes made by the first listener. For example, if the first listener adds a `Cookie` header, and the second listener strips all `Cookie` headers, then the first listener's modifications will be lost. If you want to see the headers that are actually sent, without the risk that another extension will subsequently alter them, use [`onSendHeaders`](onsendheaders), although you can't modify headers on this event.

 Not all headers actually sent are always included in `requestHeaders`. In particular, headers related to caching (for example, `Cache-Control`, `If-Modified-Since`, `If-None-Match`) are never sent. Also, behavior here may differ across browsers.

 According to the specification, header names are case-insensitive. This means that to match a particular header, the listener should lowercase the name before comparing it:

 
```
for (const header of e.requestHeaders) {
  if (header.name.toLowerCase() === desiredHeader) {
    // process header
  }
}

```
 The browser preserves the original case of the header name as generated by the browser. If the extension's listener changes the case, this change will not be kept.



Syntax
------




```
browser.webRequest.onBeforeSendHeaders.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onBeforeSendHeaders.removeListener(listener)
browser.webRequest.onBeforeSendHeaders.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details of the request. This will include request headers if you have included `"requestHeaders"` in `extraInfoSpec`. See the [details](#details_2) section for more information.

   Returns: [`webRequest.BlockingResponse`](blockingresponse). If `"blocking"` is specified in the `extraInfoSpec` parameter, the event listener should return a `BlockingResponse` object, and can set its `requestHeaders` property.

  `filter`  [`webRequest.RequestFilter`](requestfilter). A set of filters that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass any of the following values:

 * `"blocking"`: make the request synchronous, so you can modify request headers
* `"requestHeaders"`: include the request headers in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    
`requestHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP request headers that will be sent with this request.

  `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBeforeSendHeaders` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 45Asynchronous event listeners are supported from version 52. | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48Asynchronous event listeners are supported from version 52. | ? | No | ? |


Examples
--------



This code changes the "User-Agent" header so the browser identifies itself as Opera 12.16, but only when visiting pages under `https://httpbin.org/`.

 
```
"use strict";

/\*
This is the page for which we want to rewrite the User-Agent header.
\*/
const targetPage = "https://httpbin.org/\*";

/\*
Set UA string to Opera 12
\*/
const ua = "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16";

/\*
Rewrite the User-Agent header to "ua".
\*/
function rewriteUserAgentHeader(e) {
  for (const header of e.requestHeaders) {
    if (header.name.toLowerCase() === "user-agent") {
      header.value = ua;
    }
  }
  return { requestHeaders: e.requestHeaders };
}

/\*
Add rewriteUserAgentHeader as a listener to onBeforeSendHeaders,
only for the target page.

Make it "blocking" so we can modify the headers.
\*/
browser.webRequest.onBeforeSendHeaders.addListener(
  rewriteUserAgentHeader,
  { urls: [targetPage] },
  ["blocking", "requestHeaders"]
);

```
 This code is exactly like the previous example, except that the listener is asynchronous, returning a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which is resolved with the new headers:

 
```
"use strict";

/\*
This is the page for which we want to rewrite the User-Agent header.
\*/
const targetPage = "https://httpbin.org/\*";

/\*
Set UA string to Opera 12
\*/
const ua = "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16";

/\*
Rewrite the User-Agent header to "ua".
\*/
function rewriteUserAgentHeaderAsync(e) {
  const asyncRewrite = new Promise((resolve, reject) => {
    setTimeout(() => {
      for (const header of e.requestHeaders) {
        if (header.name.toLowerCase() === "user-agent") {
          header.value = ua;
        }
      }
      resolve({ requestHeaders: e.requestHeaders });
    }, 2000);
  });

  return asyncRewrite;
}

/\*
Add rewriteUserAgentHeader as a listener to onBeforeSendHeaders,
only for the target page.

Make it "blocking" so we can modify the headers.
\*/
browser.webRequest.onBeforeSendHeaders.addListener(
  rewriteUserAgentHeaderAsync,
  { urls: [targetPage] },
  ["blocking", "requestHeaders"]
);

```

### Example extensions



* [user-agent-rewriter](https://github.com/mdn/webextensions-examples/tree/master/user-agent-rewriter)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onBeforeSendHeaders) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeSendHeaders>

storage.local
=============



Represents the `local` storage area. Items in `local` storage are local to the machine the extension is installed on.

 The browser may restrict the amount of data that an extension can store in the local storage area. For example:

 * In Chrome, an extension is limited to storing 5MB of data using this API unless it has the [`"unlimitedStorage"` permission](../../manifest.json/permissions#unlimited_storage).
* In Firefox, the amount of data an extension can store is subjected to the same [storage limits](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria#storage_limits) as applied to IndexedDB databases. Extensions that intend to store more data than this limit need the ["unlimitedStorage"](../../manifest.json/permissions#unlimited_storage) permission. However, extensions with the "unlimitedStorage" permission may get a quota exceeded error when the disk space used by storage exceeds the global limit.

 When the extension is uninstalled, its associated local storage is cleared.

 Also, in Firefox, you can prevent the browser from clearing local storage on uninstall by visiting `about:config` and setting these browser preferences to `true`: `"keepUuidOnUninstall"` and `"keepStorageOnUninstall"`. This feature is provided to help developers test their extensions. Extensions themselves are not able to change these preferences.

 Although this API is similar to [`Window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), it is recommended that you don't use `Window.localStorage` in extension code. Firefox clears data stored by extensions using the localStorage API in various scenarios where users clear their browsing history and data for privacy reasons. Data saved using the `storage.local` API is correctly persisted in these scenarios.



Methods
-------



The `local` object implements the methods defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.local.get()`](storagearea/get)  Retrieves one or more items from the storage area.

  [`storage.local.getBytesInUse()`](storagearea/getbytesinuse)  Gets the amount of storage space (in bytes) used for one or more items in the storage area.

  [`storage.local.set()`](storagearea/set)  Stores one or more items in the storage area. If the item exists, its value is updated.

  [`storage.local.remove()`](storagearea/remove)  Removes one or more items from the storage area.

  [`storage.local.clear()`](storagearea/clear)  Removes all items from the storage area.

  
Events
------



The `local` object implements the events defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.local.onChanged`](storagearea/onchanged)  Fires when one or more items in the storage area change.

  
### Example extensions


* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats)
* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)
* [quicknote](https://github.com/mdn/webextensions-examples/tree/master/quicknote)
* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `local` | Yes | 14 | 45The storage API is supported in content scripts from version 48. | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#property-local) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local>

tabs.onActivated
================


Fires when the active tab in a window changes. Note that the tab's URL may not be set at the time this event fired, but you can listen to [`tabs.onUpdated`](onupdated) events to be notified when a URL is set.


Syntax
------




```
browser.tabs.onActivated.addListener(listener)
browser.tabs.onActivated.removeListener(listener)
browser.tabs.onActivated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `activeInfo`  `object`. ID of the tab that was made active, and ID of its window. See the [activeInfo](#activeinfo_2) section for more details.

    Additional objects
------------------


### activeInfo


 `previousTabId`  `integer`. The ID of the previous activated tab, if that tab is still open.

  `tabId`  `integer`. The ID of the tab that has become active.

  `windowId`  `integer`. The ID of the tab's window.

  Examples
--------



Listen for and log tab activation events:

 
```
function handleActivated(activeInfo) {
  console.log(`Tab ${activeInfo.tabId} was activated`);
}

browser.tabs.onActivated.addListener(handleActivated);

```

### Example extensions


* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onActivated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onActivated) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onActivated>

Browser styles
==============



Certain user interface components - browser and page action <popups>, <sidebars>, and [options pages](options_pages) - are specified by your extension in essentially the same way:

 1. create an HTML file defining the structure of the UI element
2. add a manifest.json key ([`browser_action`](../manifest.json/browser_action), [`page_action`](../manifest.json/page_action), [`sidebar_action`](../manifest.json/sidebar_action), or [`options_ui`](../manifest.json/options_ui)) pointing to that HTML file.

 One of the challenges with this approach is styling the element in such a way that it fits in with the browser's own style. To help with this, the manifest.json keys include an extra optional property: `browser_style`. If this is included and set to `true`, then your document will get one or more extra stylesheets that will help make it look consistent with the browser's UI and with other extensions that use the `browser_style` property.

 When considering using `browser_style: true`, you need to test your extension with various themes (built-in or from AMO) to make sure that the extension UI behaves the way you expect it to.

  **Warning:** When `browser_style: true` is included in your web extension's manifest, text selection in your extension's UI is disabled except in input controls. If this will cause a problem, include browser\_style:false instead.

   **Note:** **Google Chrome** and **Opera** use `chrome_style` instead of `browser_style`, so if you wish to support them, you need to add both keys.

  In Firefox, the stylesheet can be seen at `chrome://browser/content/extension.css`. The extra stylesheet at `chrome://browser/content/extension-mac.css` is also included on macOS.

 Most styles are automatically applied, but some elements require you to add the non-standard `browser-style` class to get their styling, as detailed in the table below:

 

| Element | Example |
| --- | --- |
| `[<button>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button)` | 
```
<button class="browser-style">Click me</button>
```
 |
| `[<select>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)` | 
```
<select class="browser-style" name="select">
  <option value="value1">Value 1</option>
  <option value="value2" selected>Value 2</option>
  <option value="value3">Value 3</option>
</select>
```
 |
| `[<textarea>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)` | 
```
<textarea class="browser-style">Write here</textarea>
```
 |
|  Parent of an `[<input>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)` | 
```
<div class="browser-style">
  <input type="radio" id="op1" name="choices" value="op1"/>
  <label for="op1">Option 1</label>
<input type="radio" id="op2" name="choices" value="op2"/>
<label for="op2">Option 2</label>
</div>
```
 |

  **Note:** See [Firefox bug 1465256](https://bugzil.la/1465256) for removal of this unnecessary requirement.

 

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Browser_styles` | 40 | 79 | 48 | ? | 27 | 14 | ? | ? | 57 | ? | 15 | ? |
| `browser_style` | 40 | 79 | 55 | ? | 27 | No | ? | ? | 57 | ? | No | ? |
| `open_in_tab` | 40 | 79 | 48 | ? | NoOptions pages are always opened in a separate browser tab. | NoOptions pages are always opened in a separate browser tab. | ? | ? | 57 | ? | NoOptions pages are always opened in a separate browser tab. | ? |
| `page` | 40 | 79 | 48 | ? | 27 | 14 | ? | ? | 57 | ? | 15 | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Browser_styles` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `browser_style` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | No | No | 54 | ? | 30SVG icons are not supported. | No | ? | ? | No | ? | No | ? |
| `default_panel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `default_title` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `open_at_install` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Browser_styles` | Yes["Since Chrome 49, page actions are displayed on the toolbar, rather than in the address bar.", "If an extension defines a page action, it is not allowed to define a browser action as well."] | 14 | 48 | ? | YesIf an extension defines a page action, it is not allowed to define a browser action as well. | 14If an extension defines a page action, it is not allowed to define a browser action as well. | ? | ? | Yes | ? | 15If an extension defines a page action, it is not allowed to define a browser action as well. | ? |
| `browser_style` | No | No | 48 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | YesSVG icons are not supported. | 14["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 48 | ? | YesSVG icons are not supported. | 14SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | Yes | ? | 15SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | Yes | ? | 15 | ? |
| `default_title` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | Yes | ? | 15 | ? |
| `hide_matches` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `pinned` | No | No | 64 | ? | No | No | ? | ? | No | ? | No | ? |
| `show_matches` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Browser_styles` | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14Available for use in Manifest V2 only. | 48Available for use in Manifest V2 only. | ? | Yes["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | 14["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? | ? | 55Available for use in Manifest V2 only. | ? | 15["Available for use in Manifest V2 only.", "If an extension defines a browser action, it is not allowed to define a page action as well."] | ? |
| `browser_style` | No | No | 48 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_area` | No | No | 54 | ? | No | No | ? | ? | No | ? | No | ? |
| `default_icon` | YesSVG icons are not supported. | 14["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 48 | ? | YesSVG icons are not supported. | 14SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | No | ? | 15SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 57 | ? | 15 | ? |
| `default_title` | Yes | 14 | 48 | ? | Yes | 14 | ? | ? | 55Browser actions are presented as menu items, and the title is the menu item's label. | ? | 15 | ? |
| `theme_icons` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Browser_styles` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109 | ? | 15.4 | ? |
| `browser_style` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |
| `default_area` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |
| `default_icon` | 88SVG icons are not supported. | 88["SVG icons are not supported.", "'default\_icon' must be an object, with explicit sizes."] | 109 | ? | 74SVG icons are not supported. | 15.4SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? | ? | No | ? | 15.4SVG icons are not supported. Grayscale images will be treated as template icons and processed with the system accent color and system appearance. | ? |
| `default_popup` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109 | ? | 15.4 | ? |
| `default_title` | 88 | 88 | 109 | ? | 74 | 15.4 | ? | ? | 109Browser actions are presented as menu items, and the title is the menu item's label. | ? | 15.4 | ? |
| `theme_icons` | 88 | 88 | 109 | ? | 74 | No | ? | ? | No | ? | No | ? |

### webextensions.manifest.action


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.manifest.browser\_action


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.manifest.page\_action


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.manifest.sidebar\_action


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.manifest.options\_ui


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Firefox Panel Components
------------------------



 **Note:** This feature is non-standard and only works in Firefox.

  The `chrome://browser/content/extension.css` stylesheet also contains the styles for the Firefox Panel Components.

 The [legacy Firefox Style Guide](https://firefoxux.github.io/StyleGuide/#/navigation) documents proper usage.

 

| Element | Example |
| --- | --- |
| Header | 
```
<header class="panel-section panel-section-header">
  <div class="icon-section-header"><img src="image.svg"/></div>
  <div class="text-section-header">Header</div>
</header>
```
 |
| Footer | 
```
<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>
```
 |
| Tabs | 
```
<div class="panel-section panel-section-tabs">
  <button class="panel-section-tabs-button selected">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
</div>
```
 |
| Form | 
```
<div class="panel-section panel-section-formElements">
  <div class="panel-formElements-item">
    <label for="name01">Label:</label>
    <input type="text" value="Name" id="name01" />
  </div>
  <div class="panel-formElements-item">
    <label for="picker01">Label:</label>
    <select id="picker01">
      <option value="value1" selected="true">Dropdown</option>
      <option value="value2">List Item</option>
      <option value="value3">List Item</option>
    </select>
  </div>
  <div class="panel-formElements-item">
    <label for="placeholder01">Label:</label>
    <input type="text" placeholder="Placeholder" id="placeholder01" />
    <button name="expander" class="expander"></button>
  </div>
</div>
```
 |
| Menu | 
```
<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-section-separator"></div>
<div class="panel-list-item disabled">
<div class="icon"></div>
<div class="text">Disabled List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-section-separator"></div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
</div>
```
 |


### Example



#### HTML

 
```
<header class="panel-section panel-section-header">
  <div class="icon-section-header"><!-- An image goes here. --></div>
  <div class="text-section-header">Header</div>
</header>

<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item disabled">
    <div class="icon"></div>
    <div class="text">Disabled List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>
</div>

<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>

```
 #### Result





 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles>

Implement a settings page
=========================



A settings page gives users a way to see and change settings (sometimes also called "preferences" or "options") for the extension.

  With WebExtension APIs, settings are generally stored using the [`storage`](api/storage) API. Implementing a settings page is a three-step process: 

 * Write an HTML file that displays settings and lets the user change them.
* Write a script, included from the HTML file, that populates the settings page from storage and updates stored settings when the user changes them.
* Set the path to the HTML file as the [`options_ui`](manifest.json/options_ui) key in `manifest.json`. By doing this, the HTML document will be shown in the browser's add-on manager, alongside the extension's name and description.

  **Note:** You can also open this page programmatically using the [`runtime.openOptionsPage()`](api/runtime/openoptionspage) function.

 

A simple extension
------------------



First, we'll write an extension that adds a blue border to every page the user visits.

 Create a new directory called `settings`, then create a file called `manifest.json` inside it with the following contents:

 
```
{
  "manifest\_version": 2,
  "name": "Settings example",
  "version": "1.0",

  "content\_scripts": [
    {
      "matches": ["<all\_urls>"],
      "js": ["borderify.js"]
    }
  ]
}

```
 This extension instructs the browser to load a content script called "borderify.js" into all web pages the user visits.

 Next, create a file called `borderify.js` inside the `settings` directory, and give it these contents:

 
```
document.body.style.border = "10px solid blue";

```
 This just adds a blue border to the page.

 Now [install](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/) and test the extension.


Adding settings
---------------



Now let's create a settings page to allow the user to set the color of the border.

 First, update `manifest.json` so it has these contents:

 
```
{
  "manifest\_version": 2,
  "name": "Settings example",
  "version": "1.0",

  "content\_scripts": [
    {
      "matches": ["<all\_urls>"],
      "js": ["borderify.js"]
    }
  ],

  "options\_ui": {
    "page": "options.html"
  },

  "permissions": ["storage"],

  "browser\_specific\_settings": {
    "gecko": {
      "id": "addon@example.com"
    }
  }
}

```
 We've added three new manifest keys:

  [`options_ui`](manifest.json/options_ui)  This sets an HTML document to be the settings page (also called options page) for this extension.

  [`permissions`](manifest.json/permissions)  We'll use the [`storage`](api/storage) API to store the settings, and we need to ask permission to use this API.

  [`browser_specific_settings`](manifest.json/browser_specific_settings)  You have to include an extension id in order to save and retrieve settings from synchronized storage.

   Next, because we've promised to provide `options.html`, let's create it. Create a file with that name inside the `settings` directory, and give it the following contents:

 
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
  </head>

  <body>
    <form>
      <label>Border color <input type="text" id="color" name="color" /></label>
      <button type="submit">Save</button>
    </form>

    <script src="options.js"></script>
  </body>
</html>

```
 This defines a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) with a labeled text [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) and a submit [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button). It also includes a script called `options.js`.

 Create `options.js`, again in the `settings` directory, and give it the following contents:

 
```
function saveOptions(e) {
  e.preventDefault();
  browser.storage.sync.set({
    color: document.querySelector("#color").value
  });
}

function restoreOptions() {
  function setCurrentChoice(result) {
    document.querySelector("#color").value = result.color || "blue";
  }

  function onError(error) {
    console.log(`Error: ${error}`);
  }

  let getting = browser.storage.sync.get("color");
  getting.then(setCurrentChoice, onError);
}

document.addEventListener("DOMContentLoaded", restoreOptions);
document.querySelector("form").addEventListener("submit", saveOptions);

```
 This does two things:

 * When the document has loaded, it fetches the value of `"color"` from storage using [`storage.sync.get()`](api/storage/storagearea/get). If the value isn't set, it uses the default `"blue"`. This retrieves the values from the `sync` storage area.
* When the user submits the form by clicking Save, it stores the value of the textbox using [`storage.sync.set()`](api/storage/storagearea/set). This saves the value to the `sync` storage area.

  **Note:** Specifying a separate `.js` file is required. You cannot use inline JavaScript.

  You could store the settings values in local storage instead if you feel that local storage is preferable for your extension.

  **Note:** The implementation of `storage.sync` in Firefox relies on the Add-on ID. If you use `storage.sync`, you must set an ID for your extension using the [`browser_specific_settings`](manifest.json/browser_specific_settings) key in `manifest.json`, as shown in the example manifest above. See [Firefox bug 1323228](https://bugzil.la/1323228) for related information.

  Finally, update `borderify.js` to read the border color from storage:

 
```
function onError(error) {
  console.log(`Error: ${error}`);
}

function onGot(item) {
  let color = "blue";
  if (item.color) {
    color = item.color;
  }
  document.body.style.border = `10px solid ${color}`;
}

const getting = browser.storage.sync.get("color");
getting.then(onGot, onError);

```
 At this point, the complete extension should look like this:

 
```
settings/
    borderify.js
    manifest.json
    options.html
    options.js

```
 Now:

 * [reload the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/#reloading_a_temporary_add-on)
* load a web page
* visit "`about:addons`" to open the settings and click the Preferences button next to the extension's entry and change the border color.
* reload the web page to see the difference.


Learn more
----------


* [`options_ui`](manifest.json/options_ui) key of `manifest.json` reference documentation
* [`storage`](api/storage) API reference documentation
* open the settings page directly from your extension using the [`runtime.openOptionsPage()`](api/runtime/openoptionspage) API
* Settings page example:
	+ [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page>

webRequest.onBeforeRequest
==========================



This event is triggered when a request is about to be made, and before headers are available. This is a good place to listen if you want to cancel or redirect the request.

 To cancel or redirect the request, first include `"blocking"` in the `extraInfoSpec` array argument to `addListener()`. Then, in the listener function, return a [`BlockingResponse`](blockingresponse) object, setting the appropriate property:

 * to cancel the request, include a property `cancel` with the value `true`.
* to redirect the request, include a property `redirectUrl` with the value set to the URL to which you want to redirect.

 If an extension wants to redirect a public (e.g. HTTPS) URL to an [extension page](../../user_interface/extension_pages), the extension's manifest.json file must contain a [web\_accessible\_resources](../../manifest.json/web_accessible_resources) key that lists the URL for the extension page.

 When multiple blocking handlers modify a request, only one set of modifications take effect. Redirects and cancellations have the same precedence. So if you canceled a request, you might see another request with the same `requestId` again if another blocking handler redirected the request.

 From Firefox 52 onwards, instead of returning `BlockingResponse`, the listener can return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which is resolved with a `BlockingResponse`. This enables the listener to process the request asynchronously.

 If you use `"blocking"`, you must have the ["webRequestBlocking" API permission](../../manifest.json/permissions#api_permissions) in your manifest.json.



Syntax
------




```
browser.webRequest.onBeforeRequest.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onBeforeRequest.removeListener(listener)
browser.webRequest.onBeforeRequest.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

   Returns: [`webRequest.BlockingResponse`](blockingresponse). If `"blocking"` is specified in the `extraInfoSpec` parameter, the event listener should return a `BlockingResponse` object, and can set either its `cancel` or its `redirectUrl` properties. From Firefox 52 onwards, instead of returning `BlockingResponse`, the listener can return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which is resolved with a `BlockingResponse`. This enables the listener to process the request asynchronously.

  `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass any of the following values:

 * `"blocking"`: make the request synchronous, so you can cancel or redirect the request
* `"requestBody"`: include `requestBody` in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameAncestors`  `array`. Contains information for each document in the frame hierarchy up to the top-level document. The first element in the array contains information about the immediate parent of the document being requested, and the last element contains information about the top-level document. If the load is actually for the top-level document, then this array is empty.

  `url`  `string`. The URL that the document was loaded from.

  `frameId`  `integer`. The `frameId` of the document. `details.frameAncestors[0].frameId` is the same as `details.parentFrameId`.

    `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    
`requestBody` Optional
  `object`. Contains the HTTP request body data. Only provided if `extraInfoSpec` contains `"requestBody"`.

  
`error` Optional
  `string`. This is set if any errors were encountered when obtaining request body data.

  
`formData` Optional
  `object`. This object is present if the request method is POST and the body is a sequence of key-value pairs encoded in UTF-8 as either "multipart/form-data" or "application/x-www-form-urlencoded".

 It is a dictionary in which each key contains the list of all values for that key. For example: `{'key': ['value1', 'value2']}`. If the data is of another media type, or if it is malformed, the object is not present.

  
`raw` Optional
  `array` of `[`webRequest.UploadData`](uploaddata)`. If the request method is PUT or POST, and the body is not already parsed in `formData`, then this array contains the unparsed request body elements.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBeforeRequest` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 46Asynchronous event listeners are supported from version 52. | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48Asynchronous event listeners are supported from version 52. | ? | No | ? |


### DNS resolution ordering when BlockingResponse is used


Regarding DNS resolution when BlockingResponse is used with OnBeforeRequest: In HTTP Channel, onBeforeRequest with blocking response does happen prior to DNS resolution and also prior to speculative connect. For other channels, speculative connect may cause DNS requests to happen before onBeforeRequest. This ordering is not something an extension developer ought to rely on as it may vary across browsers, and from one browser version to another, let alone one request channel to another. Refer [BugZilla issue clarification provided by Mozilla developers on DNS resolution ordering](https://bugzil.la/1466099)

Examples
--------



This code logs the URL for every resource requested which matches the [<all\_urls>](../../match_patterns#all_urls) pattern:

 
```
function logURL(requestDetails) {
  console.log(`Loading: ${requestDetails.url}`);
}

browser.webRequest.onBeforeRequest.addListener(
  logURL,
  {urls: ["<all\_urls>"]}
);

```
 This code cancels requests for images that are made to URLs under "<https://developer.mozilla.org/>" (to see the effect, visit any page on MDN that contains images, such as [webRequest](../webrequest)):

 
```
// match pattern for the URLs to redirect
let pattern = "https://developer.mozilla.org/\*";

// cancel function returns an object
// which contains a property `cancel` set to `true`
function cancel(requestDetails) {
  console.log(`Canceling: ${requestDetails.url}`);
  return { cancel: true };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  cancel,
  {urls: [pattern], types: ["image"]},
  ["blocking"]
);

```
 This code replaces, by redirection, all network requests for images that are made to URLs under "<https://developer.mozilla.org/>" (to see the effect, visit any page on MDN that contains images, such as [webRequest](../webrequest)):

 
```
// match pattern for the URLs to redirect
let pattern = "https://developer.mozilla.org/\*";

// redirect function
// returns an object with a property `redirectURL`
// set to the new URL
function redirect(requestDetails) {
  console.log(`Redirecting: ${requestDetails.url}`);
  return {
    redirectUrl: "https://38.media.tumblr.com/tumblr\_ldbj01lZiP1qe0eclo1\_500.gif"
  };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirect,
  {urls:[pattern], types:["image"]},
  ["blocking"]
);

```
 This code is exactly like the previous example, except that the listener handles the request asynchronously. It returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that sets a timer, and resolves with the redirect URL when the timer expires:

 
```
// match pattern for the URLs to redirect
let pattern = "https://developer.mozilla.org/\*";

// URL we will redirect to
let redirectUrl = "https://38.media.tumblr.com/tumblr\_ldbj01lZiP1qe0eclo1\_500.gif";

// redirect function returns a Promise
// which is resolved with the redirect URL when a timer expires
function redirectAsync(requestDetails) {
  console.log(`Redirecting async: ${requestDetails.url}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ redirectUrl });
    }, 2000);
  });
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirectAsync,
  {urls: [pattern], types: ["image"]},
  ["blocking"]
);

```
 Another example, that redirects all images to a data URL:

 
```
let pattern = "https://developer.mozilla.org/\*";

let image = `
 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
 <rect style="stroke-width: 10; stroke: #666;" width="100%" height="100%" fill="#d4d0c8" />
 <text transform="translate(0, 9)" x="50%" y="50%" width="100%" fill="#666" height="100%" style="text-anchor: middle; font: bold 10pt 'Segoe UI', Arial, Helvetica, Sans-serif;">Blocked</text>
 </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: [pattern], types: ["image"]},
  ["blocking"]
);

```
 Here's another version:

 
```
function randomColor() {
  return `#${Math.floor(Math.random()\*16777215).toString(16)}`;
}

const pattern = "https://developer.mozilla.org/\*";

let image = `
 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
 <rect width="100%" height="100%" fill="${randomColor()}"/>
 </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: [pattern], types: ["image"]},
  ["blocking"]
);

```

### Example extensions



* [http-response](https://github.com/mdn/webextensions-examples/tree/master/http-response)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onBeforeRequest) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRequest>

webRequest.RequestFilter
========================


An object describing filters to apply to webRequest events.


Type
----



Values of this type are objects. They contain the following properties:

  `urls`  `array` of `string`. An array of [match patterns](../../match_patterns). The listener will only be called for requests whose targets match any of the given patterns. Only requests made using HTTP or HTTPS will trigger events, other protocols (such as data: and file:) supported by pattern matching do not trigger events. `view-source:` requests may be matched based on its inner URL.

  
`types` Optional
  `array` of `[`webRequest.ResourceType`](resourcetype)`. A list of resource types (for example, stylesheets, images, scripts). The listener will only be called for requests for resources which are one of the given types.

  
`tabId` Optional
  `integer`. The listener will only be called for requests from the [`tab`](../tabs/tab) identified by this ID.

  
`windowId` Optional
  `integer`. The listener will only be called for requests from the [`window`](../windows/window) identified by this ID.

  
`incognito` Optional
  `boolean`. If provided, requests that do not match the incognito state (`true` or `false`) will be filtered out.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RequestFilter` | YesIf a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 14If a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 45["From Firefox 78 onwards, if a filter contains unrecognized values in its `types` property, then these values are ignored and `addListener()` proceeds.", "Before Firefox 78, if a filter contains unrecognized values in its `types` property, `addListener()` throws an exception."] | ? | YesIf a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | 14 | ? | ? | 48If a filter contains unrecognized values in its `types` property, `addListener()` throws an exception. | ? | No | ? |
| `tabId` | Yes | 14 | 53 | ? | Yes | 14 | ? | ? | 53 | ? | No | ? |
| `urls` | Yes | 14 | 45Before Firefox 56, moz-extension:// URLs were not allowed. | ? | Yes | 14 | ? | ? | 48Before Firefox 56, moz-extension:// URLs were not allowed. | ? | No | ? |
| `view-source` | Yes | 14 | 84 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `windowId` | Yes | 14 | 53 | ? | Yes | 14 | ? | ? | 53 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#type-RequestFilter) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/RequestFilter>

pageAction.getTitle()
=====================



Gets the title of the page action.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingTitle = browser.pageAction.getTitle(
  details // object
)

```
### Parameters


 `details`  `object`.

  `tabId`  `integer`. The ID of the tab containing the page action whose title you want to get.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the page action's title.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTitle` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15The API exists, but the title not visible in the UI. | ? |


Examples
--------



This example logs the page action's title when the user clicks its icon:

 
```
function gotTitle(title) {
  console.log(`Title ${title}`);
}

browser.pageAction.onClicked.addListener((tab) => {
  let gettingTitle = browser.pageAction.getTitle({
    tabId: tab.id
  });
  gettingTitle.then(gotTitle);
});

```

### Example extensions



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)

  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-getTitle) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/getTitle>

pageAction.onClicked
====================



Fired when a page action icon is clicked. This event will not fire if the page action has a popup.

 To define a right-click action, use the [`contextMenus`](../menus) API with the "page\_action" [context type](../menus/contexttype).



Syntax
------




```
browser.pageAction.onClicked.addListener(listener)
browser.pageAction.onClicked.removeListener(listener)
browser.pageAction.onClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function is passed the following arguments:

  `tab`  A [`tabs.Tab`](../tabs/tab) object representing the tab whose page action was clicked.

  `OnClickData`  An object containing information about the click.

  `modifiers`  An `array`. The keyboard modifiers active at the time of the click, being one or more of `Shift`, `Alt`, `Command`, `Ctrl`, or `MacCtrl`.

  `button`  An `integer`. Indicates the button used to click the page action icon: `0` for a left-click or a click not associated with a mouse, such as one from the keyboard and `1` for a middle button or wheel click. Note that the right-click is not supported because Firefox consumes that click to display the context menu before this event is triggered.

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnClickData` | No | No | 72 | ? | No | No | ? | ? | No | ? | No | ? |
| `onClicked` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50 | ? | 15 | ? |
| `tab` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50 | ? | 15 | ? |


Examples
--------



When the user clicks the page action, hide it, and navigate the active tab to "<https://giphy.com/explore/cat>":

 
```
let CATGIFS = "https://giphy.com/explore/cat";

browser.pageAction.onClicked.addListener((tab) => {
  browser.pageAction.hide(tab.id);
  browser.tabs.update({url: CATGIFS});
});

browser.pageAction.onClicked.addListener(() => {
});

```

### Example extensions



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)

  **Note:**

 This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#event-onClicked) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/onClicked>

pageAction.setIcon()
====================



Sets the icon for the page action.

 You can specify a single icon as either the path to an image file or a [`pageAction.ImageDataType`](imagedatatype) object.

 You can specify multiple icons in different sizes by supplying a dictionary containing multiple paths or `ImageData` objects. This means the icon doesn't have to be scaled for a device with a different pixel density.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let settingIcon = browser.pageAction.setIcon(
  details         // object
)

```
### Parameters


 `details`  `object`. An object containing either `imageData` or `path` properties, and a `tabId` property.

  
`imageData` Optional
  `[`pageAction.ImageDataType`](imagedatatype)` or `object`. This is either a single `ImageData` object or a dictionary object.

 Use a dictionary object to specify multiple `ImageData` objects in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `imageData` is a dictionary, the value of each property is an `ImageData` object, and its name is its size, like this:

 
```
{
  16: image16,
  32: image32
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`path` Optional
  `string` or `object`. This is either a relative path to an icon file or a dictionary object.

 Use a dictionary object to specify multiple icon files in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `path` is a dictionary, the value of each property is a relative path, and its name is its size, like this:

 
```
{
  16: "path/to/image16.jpg",
  32: "path/to/image32.jpg"
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

 If `path` is `null`, this will reset the page action's icon to the icon that was given in the [`page_action`](../../manifest.json/page_action) manifest key.

 If `path` is `""`, this will reset the icon to the browser's global default icon (that is, the icon used if no icon is given in the [`page_action`](../../manifest.json/page_action) manifest key).

 If `path` does not point to a valid icon, then no icon will be displayed.

  `tabId`  `integer`. The ID of the tab whose icon you want to set.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the icon has been set.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setIcon` | YesBefore Chrome 23, `path` couldn't specify multiple icon files, but had to be a string specifying a single icon path. | 14 | 45 | ? | 15 | 14 | ? | ? | 79 | ? | 15 | ? |
| `imageData` | 23 | 79 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Set the icon for the page action when the user clicks it:

 
```
browser.pageAction.onClicked.addListener((tab) => {
  browser.pageAction.setIcon({
    tabId: tab.id, path: "icons/icon-48.png"
  });
});

```

### Example extensions



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)

  **Note:**

 This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-setIcon) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/setIcon>

pageAction.show()
=================



Shows the [`pageAction`](../pageaction) for a given [`tab`](../tabs/tab). The page action is shown whenever the given tab is the active tab.

 `show()` overrides pattern matching, so the page action will be shown in the specified tab even if [`show_matches`](../../manifest.json/page_action) does not match the URL or [`hide_matches`](../../manifest.json/page_action) does.

 Note that calling `show()` has no effect on a tab with no content loaded.



Syntax
------



```
browser.pageAction.show(
  tabId // integer
)

```
### Parameters


 `tabId`  `integer`. The ID of the [`tab`](../tabs/tab) for which you want to show the page action.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `undefined`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `show` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 50Before version 56, the 'tabId' parameter was ignored, and the page action was shown for all tabs. | ? | No | ? |


Examples
--------



This example shows the [`pageAction`](../pageaction) for the active tab when the user selects a context menu item.

  **Note:** You'll need the `contextMenus` [permission](../../manifest.json/permissions) in your [manifest](../../manifest.json) to create context menu items.

  
```
browser.contextMenus.create({
  id: "show",
  title: "Show page action"
})

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "show") {
    browser.pageAction.show(tab.id)
  }
})

```

### Example extensions



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)
* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)

  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-show) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/show>

bookmarks.create()
==================



Creates a bookmark or folder as a child of the [`BookmarkTreeNode`](bookmarktreenode) with the specified `parentId`. To create a folder, omit or leave empty the [`CreateDetails.url`](createdetails#url) parameter.

  **Warning:** If your extension tries to create a new bookmark in the bookmark tree's root node, it raises an error: "*The bookmark root cannot be modified*" and the bookmark won't be created.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let createBookmark = browser.bookmarks.create(
  bookmark                  // CreateDetails object
)

```
### Parameters


 `bookmark`  A [`bookmarks.CreateDetails`](createdetails) object.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`BookmarkTreeNode`](bookmarktreenode) that describes the new bookmark node.

  **Note:** If you create multiple bookmarks, because this API is asynchronous, the create calls may get processed in any order. Consequently, the value of each bookmark's index returned in [`BookmarkTreeNode`](bookmarktreenode) may change or be unknown until all the create calls are completed. If the index associated with a bookmark matters to your extension, then – when creating multiple bookmarks – the extension should wait for each `bookmarks.create` call to complete before creating the next bookmark. Waiting ensures that the index associated with each bookmark is not affected by a create call executing concurrently while the original call is in progress.

 
Examples
--------



This example creates a bookmark for this page, placing it in the default folder ("Other Bookmarks" in Firefox and Chrome).

 
```
function onCreated(node) {
  console.log(node);
}

let createBookmark = browser.bookmarks.create({
  title: "bookmarks.create() on MDN",
  url: "https://developer.mozilla.org/Add-ons/WebExtensions/API/bookmarks/create",
});

createBookmark.then(onCreated);

```

### Example extensions


* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-create) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/create>

windows.getCurrent()
====================



Gets the current browser window, passing its details into a callback.

 The "current" window is not necessarily the same as the currently focused window. If this function is called from a background script, then it returns the currently focused window. But if it is called from a script whose document is associated with a particular browser window, then it returns that browser window. For example, if the browser is displaying a sidebar, then every browser window has its own instance of the sidebar document. If a script running in the sidebar document calls `getCurrent()`, then it will return that sidebar document's window.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingCurrent = browser.windows.getCurrent(
  getInfo               // optional object
)

```
### Parameters



 
`getInfo` Optional
  `object`.

  
`populate` Optional
  `boolean`. If true, the [`windows.Window`](window) object will have a `tabs` property that contains a list of [`tabs.Tab`](../tabs/tab) objects representing the tabs in the window. The `Tab` objects only contain the `url`, `title` and `favIconUrl` properties if the extension's manifest file includes the `"tabs"` permission or [host permissions](../../manifest.json/permissions#host_permissions) that match the tab's URL.

  
`windowTypes`  Deprecated  Optional
  An `array` of `[`windows.WindowType`](windowtype)` objects. If set, the [`windows.Window`](window) returned will be filtered based on its type. If unset the default filter is set to `['normal', 'panel', 'popup']`, with `'panel'` window types limited to the extension's own windows.

      **Note:** If supplied, the `windowTypes` component of `getInfo` is ignored. The use of `windowTypes` has been deprecated as of Firefox 62.

 
### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](window) object containing the details of the window. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getCurrent` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getInfo` | 18 | 14 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



When the user clicks a browser action's icon, this example gets the current window and logs the URLs of the tabs it contains. Note that you'll need the "tabs" [permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions) to access tab URLs.

 
```
function logTabs(windowInfo) {
  for (const tabInfo of windowInfo.tabs) {
    console.log(tabInfo.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.windows.getCurrent({ populate: true }).then(logTabs, onError);
});

```

### Example extensions



* [annotate-page](https://github.com/mdn/webextensions-examples/tree/master/annotate-page)
* [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar)
* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-getCurrent) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/getCurrent>

pageAction.setTitle()
=====================


Sets the title of the page action. The title is displayed in a tooltip when the user hovers over the page action.


Syntax
------



```
browser.pageAction.setTitle(
  details // object
)

```
### Parameters


 `details`  `object`.

  `tabId`  `integer`. The ID of the tab whose title you want to set.

  `title`  `string` or `null`. The tooltip text.

 If `null` is passed here, the title is reset to the title that was specified in the [`page_action`](../../manifest.json/page_action) manifest key.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setTitle` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15The API exists, but the title not visible in the UI. | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Whenever a tab is updated, show the page action for that tab, and set its title to show the tab's ID:

 
```
browser.tabs.onUpdated.addListener((tabId, changeInfo, tabInfo) => {
  browser.pageAction.show(tabId);
  browser.pageAction.setTitle({
    tabId,
    title: `Tab ID: ${tabId}`,
  });
});

```

### Example extensions



* [apply-css](https://github.com/mdn/webextensions-examples/tree/master/apply-css)

  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-setTitle) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/setTitle>

bookmarks.onCreated
===================


Fired when a bookmark item (a bookmark or a folder) is created.


Syntax
------




```
browser.bookmarks.onCreated.addListener()
browser.bookmarks.onCreated.removeListener(listener)
browser.bookmarks.onCreated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `id`  `string`. The new bookmark item's ID.

  `bookmark`  [`bookmarks.BookmarkTreeNode`](bookmarktreenode). Information about the new bookmark item.

    Examples
--------



```
function handleCreated(id, bookmarkInfo) {
  console.log(`New bookmark ID: ${id}`);
  console.log(`New bookmark URL: ${bookmarkInfo.url}`);
}

browser.bookmarks.onCreated.addListener(handleCreated);

```
### Example extensions


* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreated` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onCreated) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onCreated>

bookmarks.remove()
==================



The `bookmarks.remove()` method removes a single bookmark or an empty bookmark folder.

  **Warning:** If your extension attempts to remove a bookmark from the bookmarks tree root node, the call will raise an error with the message: "The bookmark root cannot be modified" and the bookmark won't be removed.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removingBookmark = browser.bookmarks.remove(
  id                 // string
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) specifying the ID of the bookmark or empty folder to remove.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments.

 If the node corresponding to the `id` parameter can't be found or was a non-empty folder, the promise is rejected with an error message.


Examples
--------



```
function onRemoved() {
  console.log("Removed!");
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let bookmarkId = "abcdefghijkl";

let removingBookmark = browser.bookmarks.remove(bookmarkId);
removingBookmark.then(onRemoved, onRejected);

```
### Example extensions


* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-remove) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/remove>

browserAction.onClicked
=======================



Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.

 To define a right-click action, use the [`contextMenus`](../menus) API with the "browser\_action" [context type](../menus/contexttype).



Syntax
------




```
browser.browserAction.onClicked.addListener(listener)
browser.browserAction.onClicked.removeListener(listener)
browser.browserAction.onClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tab`  [`tabs.Tab`](../tabs/tab). The tab that was active when the icon was clicked.

  `OnClickData`  An object containing information about the click.

  `modifiers`  An `array`. The keyboard modifiers active at the time of the click, being one or more of `Shift`, `Alt`, `Command`, `Ctrl`, or `MacCtrl`.

  `button`  An `integer`. Indicates the button used to click the page action icon: `0` for a left-click or a click not associated with a mouse, such as one from the keyboard and `1` for a middle button or wheel click. Note that the right-click is not supported because Firefox consumes that click to display the context menu before this event is triggered.

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnClickData` | No | No | 72 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `onClicked` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |
| `tab` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 55 | ? | 15 | ? |


Examples
--------



When the user clicks the icon, disable it for the active tab, and log the tab's URL:

 
```
browser.browserAction.onClicked.addListener((tab) => {
  // disable the active tab
  browser.browserAction.disable(tab.id);
  // requires the "tabs" or "activeTab" permission, or host permissions for the URL
  console.log(tab.url);
});

```

### Example extensions



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)
* [native-messaging](https://github.com/mdn/webextensions-examples/tree/master/native-messaging)
* [open-my-page-button](https://github.com/mdn/webextensions-examples/tree/master/open-my-page-button)
* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)
* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)
* [store-collected-images](https://github.com/mdn/webextensions-examples/tree/master/store-collected-images)

  **Note:**

 This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#event-onClicked) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/onClicked>

browserAction.setIcon()
=======================



Sets the icon for the browser action.

 You can specify a single icon as either the path to an image file or a [`browserAction.ImageDataType`](imagedatatype) object.

 You can specify multiple icons in different sizes by supplying a dictionary containing multiple paths or `ImageData` objects. This means the icon doesn't have to be scaled for a device with a different pixel density.

 Tabs without a specific icon will inherit the global icon, which defaults to the [`default_icon`](../../manifest.json/browser_action) specified in the manifest.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let settingIcon = browser.browserAction.setIcon(
  details         // object
)

```
### Parameters



 `details`  `object`. An object containing either `imageData` or `path` properties, and optionally a `tabId` property.

  
`imageData` Optional
  `[`browserAction.ImageDataType`](imagedatatype)` or `object`. This is either a single `ImageData` object or a dictionary object.

 Use a dictionary object to specify multiple `ImageData` objects in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `imageData` is a dictionary, the value of each property is an `ImageData` object, and its name is its size, like this:

 
```
{
  16: image16,
  32: image32
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`path` Optional
  `string` or `object`. This is either a relative path to an icon file or it is a dictionary object.

 Use a dictionary object to specify multiple icon files in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `path` is a dictionary, the value of each property is a relative path, and its name is its size, like this:

 
```
{
  16: "path/to/image16.jpg",
  32: "path/to/image32.jpg"
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`tabId` Optional
  `integer`. Sets the icon only for the given tab. The icon is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the icon for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the icon is not set.
* If `windowId` and `tabId` are both omitted, the global icon is set.

 If each one of `imageData` and `path` is one of `undefined`, `null` or empty object:

 * If `tabId` is specified, and the tab has a tab-specific icon set, then the tab will inherit the icon from the window to which it belongs.
* If `windowId` is specified, and the window has a window-specific icon set, then the window will inherit the global icon.
* Otherwise, the global icon will be reset to the manifest icon.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the icon has been set.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setIcon` | YesBefore Chrome 23, `path` couldn't specify multiple icon files, but had to be a string specifying a single icon path. | 14["This call is not persisted.", "The `imageData` parameter is not accepted.", "The `path` parameter is required."] | 4545–58Tab-specific icons are not cleared when a new page is loaded. | ? | 15 | 14 | ? | ? | 79 | ? | 15 | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `imageData` | 23 | 79 | 45 | ? | 15 | 14 | ? | ? | 79 | ? | 15 | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



The code below uses a browser action to toggle a listener for [`webRequest.onHeadersReceived`](../webrequest/onheadersreceived), and uses `setIcon()` to indicate whether listening is on or off:

 
```
function logResponseHeaders(requestDetails) {
  console.log(requestDetails);
}

function startListening() {
  browser.webRequest.onHeadersReceived.addListener(
    logResponseHeaders,
    { urls: ["<all\_urls>"] },
    ["responseHeaders"]
  );
  browser.browserAction.setIcon({ path: "icons/listening-on.svg" });
}

function stopListening() {
  browser.webRequest.onHeadersReceived.removeListener(logResponseHeaders);
  browser.browserAction.setIcon({ path: "icons/listening-off.svg" });
}

function toggleListener() {
  if (browser.webRequest.onHeadersReceived.hasListener(logResponseHeaders)) {
    stopListening();
  } else {
    startListening();
  }
}

browser.browserAction.onClicked.addListener(toggleListener);

```
 The code below sets the icon using an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object:

 
```
function getImageData() {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");

  ctx.fillStyle = "green";
  ctx.fillRect(10, 10, 100, 100);

  return ctx.getImageData(50, 50, 100, 100);
}

browser.browserAction.onClicked.addListener(() => {
  browser.browserAction.setIcon({ imageData: getImageData() });
});

```
 The following snippet updates the icon when the user clicks it, but only for the active tab:

 
```
browser.browserAction.onClicked.addListener((tab) => {
  browser.browserAction.setIcon({
    tabId: tab.id,
    path: "icons/updated-48.png",
  });
});

```

### Example extensions



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)

  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setIcon) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setIcon>

browserAction.setTitle()
========================


Sets the browser action's title. The title is displayed in a tooltip over the browser action's icon. You can pass a `tabId` in or a `windowId` as an optional parameter — if you do this then the title is changed only for the given tab or the given window. Tabs or windows without a specific title will inherit the global title text, which defaults to the [`default_title`](../../manifest.json/browser_action) or [`name`](../../manifest.json/name) specified in the manifest.


Syntax
------



```
browser.browserAction.setTitle(
  details // object
)

```
### Parameters



 `details`  `object`. The new title and optionally the ID of the tab or window to target.

  `title`  `string` or `null`. The string the browser action should display when moused over.

 If `title` is an empty string, the used title will be the extension name, but [`browserAction.getTitle`](gettitle) will still provide the empty string.

 If `title` is `null`:

 * If `tabId` is specified, and the tab has a tab-specific title set, then the tab will inherit the title from the window to which it belongs.
* if `windowId` is specified, and the window has a window-specific title set, then the window will inherit the global title.
* Otherwise, the global title will be reset to the manifest title.

  
`tabId` Optional
  `integer`. Sets the title only for the given tab.

  
`windowId` Optional
  `integer`. Sets the title for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the title is not set.
* If `windowId` and `tabId` are both omitted, the global title is set.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setTitle` | Yes | 15 | 4545–58Tab-specific titles are not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 5555–58Tab-specific titles are not cleared when a new page is loaded. | ? | 15The API exists, but the title not visible in the UI. | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



This code switches the title between "this" and "that" each time the user clicks the browser action:

 
```
function toggleTitle(title) {
  if (title === "this") {
    browser.browserAction.setTitle({ title: "that" });
  } else {
    browser.browserAction.setTitle({ title: "this" });
  }
}

browser.browserAction.onClicked.addListener(() => {
  let gettingTitle = browser.browserAction.getTitle({});
  gettingTitle.then(toggleTitle);
});

```

### Example extensions



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)

  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setTitle) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setTitle>

windows.onFocusChanged
======================



Fired when the currently focused window changes. Will be [`windows.WINDOW_ID_NONE`](window_id_none) if all browser windows have lost focus.

  **Note:** In Windows and some Linux window managers, WINDOW\_ID\_NONE will always be sent immediately preceding a switch from one browser window to another.

 

Syntax
------




```
browser.windows.onFocusChanged.addListener(listener)
browser.windows.onFocusChanged.removeListener(listener)
browser.windows.onFocusChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `windowId`  `integer`. ID of the newly focused window.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onFocusChanged` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15Fires when toggling in or out of private browsing mode, leaving Safari to the home screen, and returning to Safari from the home screen. | ? |


Examples
--------



Log focus changes:

 
```
browser.windows.onFocusChanged.addListener((windowId) => {
  console.log(`Newly focused window: ${windowId}`);
});

```

### Example extensions



* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#event-onFocusChanged) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/onFocusChanged>

alarms.clearAll()
=================



Cancels all active alarms.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let clearAlarms = browser.alarms.clearAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean. This will be `true` if any alarms were cleared, `false` otherwise. Note that Chrome always passes `true` here.

Examples
--------



```
function onClearedAll(wasCleared) {
  console.log(wasCleared); // true/false
}

let clearAlarms = browser.alarms.clearAll();
clearAlarms.then(onClearedAll);

```
### Example extensions


* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `clearAll` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/clearAll>

bookmarks.onRemoved
===================


Fired when a bookmark or folder is removed. When a folder is removed recursively, a single notification is fired for the folder, and none for its contents.


Syntax
------




```
browser.bookmarks.onRemoved.addListener(listener)
browser.bookmarks.onRemoved.removeListener(listener)
browser.bookmarks.onRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `id`  `string`. ID of the item that was removed.

  `removeInfo`  `object`. More details about the removed item. See the [removeInfo](#removeinfo_2) section for more details.

    Additional objects
------------------


### removeInfo


 `parentId`  `string`. ID of the item's parent in the tree.

  `index`  `integer`. Zero-based index position of this item in its parent.

  `node`  [`bookmarks.BookmarkTreeNode`](bookmarktreenode). Detailed information about the item that was removed.

  Examples
--------



```
function handleRemoved(id, removeInfo) {
  console.log(`Item: ${id} removed`);
  console.log(`Title: ${removeInfo.node.title}`);
  console.log(`Url: ${removeInfo.node.url}`);
}

function handleClick() {
  browser.bookmarks.onRemoved.addListener(handleRemoved);
}

browser.browserAction.onClicked.addListener(handleClick);

```
### Example extensions


* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRemoved` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onRemoved) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onRemoved>

bookmarks.search()
==================



The `bookmarks.search()` function searches for bookmark tree nodes matching the given query.

 This function throws an exception if any of the input parameters are invalid or are not of an appropriate type; look in the [console](https://extensionworkshop.com/documentation/develop/debugging/) for the error message. The exceptions don't have error IDs, and the messages themselves may change, so don't write code that tries to interpret them.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let searching = browser.bookmarks.search(
  query                  // string or object
)

```
### Parameters


 `query`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) or [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) describing the query to perform.

 If `query` is a **string**, it consists of zero or more space-delimited search terms. Each search term matches if it is a substring in the bookmark's URL or title. Matching is case-insensitive. For a bookmark to match the query, all the query's search terms must be matched.

 If `query` is an **object**, it consists of zero or more of 3 properties: `query`, `title`, and `url`, which are described below. For a bookmark to match the query, all the properties' terms must be matched.

  
`query` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) specifying one or more terms to match against; the format is identical to the string form of the `query` parameter. If this isn't a string, an exception is thrown.

  
`url` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) that must exactly match the bookmark's URL. Matching is case-insensitive, and trailing slashes are ignored.

 If you pass an invalid URL, the function will throw an exception.

  
`title` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) that must exactly match the bookmark tree node's title. Matching is case-sensitive.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`bookmarks.BookmarkTreeNode`](bookmarktreenode) objects, each representing a single matching bookmark tree node. Results are returned in the order that the nodes were created. The array is empty if no results were found.

 The [`BookmarkTreeNodes`](bookmarktreenode)—even nodes of the `"folder"` type—returned by `bookmarks.search()` are missing the `children` property. To get a complete `BookmarkTreeNode` use [`bookmarks.getSubTree()`](getsubtree).


Example
-------



This example logs the IDs of all bookmarks:

 
```
function onFulfilled(bookmarkItems) {
  for (const item of bookmarkItems) {
    console.log(item.id);
  }
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

browser.bookmarks.search({}).then(onFulfilled, onRejected);

```
 This example looks to see if the currently active tab is bookmarked:

 
```
function onFulfilled(bookmarkItems) {
  if (bookmarkItems.length) {
    console.log("active tab is bookmarked");
  } else {
    console.log("active tab is not bookmarked");
  }
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

function checkActiveTab(tab) {
  browser.bookmarks.search({ url: tab.url }).then(onFulfilled, onRejected);
}

browser.browserAction.onClicked.addListener(checkActiveTab);

```

### Example extensions


* [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `search` | Yes | 79 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-search) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/search>

alarms.create()
===============


Creates a new alarm for the current browser session. An alarm may fire once or multiple times. An alarm is cleared after it fires for the last time.


Syntax
------



```
browser.alarms.create(
  name,              // optional string
  alarmInfo          // optional object
)

```
### Parameters


 
`name` Optional
  `string`. A name for the alarm. Defaults to the empty string.

 This can be used to refer to a particular alarm in [`alarms.get()`](get) and [`alarms.clear()`](clear). It will also be available in [`alarms.onAlarm`](onalarm) as the `name` property of the [`alarms.Alarm`](alarm) object passed into the listener function.

 Alarm names are unique within the scope of a single extension. If an alarm with an identical name exists, the existing alarm will be cleared and the alarm being created will replace it.

  
`alarmInfo` Optional
  `object`. You can use this to specify when the alarm will initially fire, either as an absolute value (`when`), or as a delay from the time the alarm is set (`delayInMinutes`). To make the alarm recur, specify `periodInMinutes`.

 On Chrome, unless the extension is loaded unpackaged, alarms it creates are not allowed to fire more than once per minute. If an extension tries to set `delayInMinutes` to a value < 1, or `when` to a value < 1 minute in the future, then the alarm will fire after 1 minute. If an extension tries to set `periodInMinutes` to a value < 1, then the alarm will fire every minute.

 The `alarmInfo` object may contain the following properties:

  
`when` Optional
  `double`. The time the alarm will fire first, given as [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time). To get the number of milliseconds between the epoch and the current time, use [`Date.now()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now). If you specify `when`, don't specify `delayInMinutes`.

  
`delayInMinutes` Optional
  `double`. The time the alarm will fire first, given as minutes from the time the alarm is set. If you specify `delayInMinutes`, don't specify `when`.

  
`periodInMinutes` Optional
  `double`. If this is specified, the alarm will fire again every `periodInMinutes` after its initial firing. If you specify this value you may omit both `when` and `delayInMinutes`, and the alarm will then fire initially after `periodInMinutes`. If `periodInMinutes` is not specified, the alarm will only fire once.

    Examples
--------



Create a one-time delay-based alarm with "" for the name:

 
```
const delayInMinutes = 5;

browser.alarms.create({
  delayInMinutes,
});

```
 Create a periodic delay-based alarm named "my-periodic-alarm":

 
```
const delayInMinutes = 5;
const periodInMinutes = 2;

browser.alarms.create("my-periodic-alarm", {
  delayInMinutes,
  periodInMinutes,
});

```
 Create a periodic absolute alarm named "my-periodic-alarm":

 
```
const when = 1545696000;
const periodInMinutes = 2;

browser.alarms.create("my-periodic-alarm", {
  when,
  periodInMinutes,
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | Yes | 79 | 4545–64Alarms scheduled for a time in the past never fire. | ? | Yes | 14 | ? | ? | 4848–64Alarms scheduled for a time in the past never fire. | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/create>

getAll()
========



Gets all commands for the extension that you have registered using the [`commands` manifest.json key](../../manifest.json/commands).

 The commands are returned as an array of [`commands.Command`](command) objects. Alternately, if you are using the promise-based version of the API, `browser.commands.getAll()`, the commands are passed into the `onFulfilled` argument to [`Promise.then()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getCommands = browser.commands.getAll();

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of `[`commands.Command`](command)` objects, one for each command registered for the extension. If no commands were registered, the array will be empty.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



```
function logCommands(commands) {
  commands.forEach((command) => {
    console.log(command);
  });
}

let getCommands = browser.commands.getAll();
getCommands.then(logCommands);

```
### Example extensions



* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)

  **Note:** This API is based on Chromium's [`chrome.commands`](https://developer.chrome.com/docs/extensions/reference/commands/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands/getAll>

commands.reset()
================



Resets the given command's description and keyboard shortcut to the values given in the extension's [`commands` manifest.json key](../../manifest.json/commands).

 This effectively undoes any changes made to the command using the [`commands.update()`](update) function.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.commands.reset(
  name // string
);

```
### Parameters


 `name`  `string`. Name of the command to reset, as given by the `name` property of the [`commands.Command`](command) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the shortcut has been reset.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `reset` | No | No | 60 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Resets the command named "my-command" when the user clicks the "reset" button:

 
```
const commandName = 'my-command';

function resetShortcut() {
  browser.commands.reset(commandName);
}

document.querySelector('#reset').addEventListener('click', resetShortcut);

```

### Example extensions


* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands/reset>

commands.update()
=================



Change the description or keyboard shortcut for the given command.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.commands.update(
  details // object
);

```
### Parameters


 `details`  `object`. An object with the following properties:

  `name`  `string`. The name of the command to update. This must match the name of an existing command, as given for example in the `name` property of the [`commands.Command`](command) object.

  
`description` Optional
  `string`. A new description to set for the command.

  
`shortcut` Optional
  `string`. A new shortcut to set for the command. This can be:

 * an empty string to clear the shortcut.
* a string matching the format of the [`commands` manifest.json key](../../manifest.json/commands) to set a new shortcut key. If the string does not match this format, the function throws an error.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the shortcut has been updated. The promise will be rejected with an error if the command could not be found.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | No | No | 60 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Updates the command named "my-command" with the given shortcut value, when the user clicks "update":

 
```
const commandName = 'my-command';

function updateShortcut() {
  browser.commands.update({
    name: commandName,
    shortcut: document.querySelector('#shortcut').value
  });
}

document.querySelector('#update').addEventListener('click', updateShortcut);

```

### Example extensions


* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands/update>

alarms.onAlarm
==============


Fired when any alarm set by the extension goes off.


Syntax
------




```
browser.alarms.onAlarm.addListener(listener)
browser.alarms.onAlarm.removeListener(listener)
browser.alarms.onAlarm.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `listener`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `alarm`  [`alarms.Alarm`](alarm). The alarm that fired. Use `Alarm.name` to figure out which alarm fired.

    Examples
--------



Handle an alarm going off:

 
```
function handleAlarm(alarmInfo) {
  console.log(`on alarm: ${alarmInfo.name}`);
}

browser.alarms.onAlarm.addListener(handleAlarm);

```

### Example extensions


* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)
* [dynamic-theme](https://github.com/mdn/webextensions-examples/tree/master/dynamic-theme)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onAlarm` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/onAlarm>

pageAction.hide()
=================



Hides the page action for a given tab.

 `hide()` overrides pattern matching, so the page action will not be shown in the specified tab even if its URL is matched by [`show_matches`](../../manifest.json/page_action).



Syntax
------



```
browser.pageAction.hide(
  tabId // integer
)

```
### Parameters


 `tabId`  `integer`. The ID of the tab for which you want to hide the page action.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `hide` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 50Before version 56, the 'tabId' parameter was ignored, and the page action was hidden for all tabs. | ? | No | ? |


Examples
--------



Hide the page action for the current tab when the user clicks it:

 
```
browser.pageAction.onClicked.addListener((tab) => {
  browser.pageAction.hide(tab.id);
});

```

### Example extensions



* [chill-out](https://github.com/mdn/webextensions-examples/tree/master/chill-out)

  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-hide) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/hide>

onCommand
=========



Fired when a command is executed using its associated keyboard shortcut.

 The listener is passed the command's name. This matches the name given to the command in its [manifest.json entry](../../manifest.json/commands).



Syntax
------




```
browser.commands.onCommand.addListener(listener)
browser.commands.onCommand.removeListener(listener)
browser.commands.onCommand.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when a user enters the command's shortcut. The function will be passed the following arguments:

  `name`  `string`. Name of the command. This matches the name given to the command in its [manifest.json entry](../../manifest.json/commands).

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCommand` | Yes | 79 | 48Before version 63, the `onCommand` listener was not treated as a [handler for a user action](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/User_actions). | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Given a manifest.json entry like this:

 
```
"commands": {
  "toggle-feature": {
    "suggested\_key": {
      "default": "Ctrl+Shift+Y"
    },
    "description": "Send a 'toggle-feature' event"
  }
}

```
 You could listen for this particular command like this:

 
```
browser.commands.onCommand.addListener((command) => {
  if (command === "toggle-feature") {
    console.log("toggling the feature!");
  }
});

```

### Example extensions



* [commands](https://github.com/mdn/webextensions-examples/tree/master/commands)

  **Note:** This API is based on Chromium's [`chrome.commands`](https://developer.chrome.com/docs/extensions/reference/commands/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands/onCommand>

contentScripts.register()
=========================



Use this function to register one or more content scripts.

 It accepts one parameter, which is an object with similar properties to the objects given in the [`content_scripts`](../../manifest.json/content_scripts) manifest key (but note that `content_scripts` is an array of objects, while the argument to `register()` is a single object).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let registering = browser.contentScripts.register(
  contentScriptOptions       // object
)

```
### Parameters


 `contentScriptOptions`  `object`. A `RegisteredContentScriptOptions` object representing the content scripts to register. It has similar syntax to the objects in the [`content_scripts`](../../manifest.json/content_scripts) manifest key array. The differences are:

 * property names use camelCase, rather than underscores (for example, `excludeMatches`, not `exclude_matches`
* the `js` and `css` properties allow you to register strings as well as URLs, so their syntax has to distinguish these types.

 The `RegisteredContentScriptOptions` object has the following properties:

  
`allFrames` Optional
  Same as `all_frames` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`cookieStoreId` Optional
  A string or array of strings. Registers the content script in the tabs that belong to one or more cookie store IDs. This enables scripts to be registered for all default or non-contextual identity tabs, private browsing tabs (if the [extension is enabled in private browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing)), the tabs of a [contextual identity](../../work_with_contextual_identities), or a combination of these.

  
`css` Optional
  An array of objects. Each object has either a property named `file`, which is a URL starting at the extension's manifest.json and pointing to a CSS file to register, or a property named `code`, which is some CSS code to register.

  
`excludeGlobs` Optional
  Same as `exclude_globs` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`excludeMatches` Optional
  Same as `exclude_matches` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`includeGlobs` Optional
  Same as `include_globs` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`js` Optional
  An array of objects. Each object has either a property named `file`, which is a URL starting at the extension's manifest.json and pointing to a JavaScript file to register, or a property named `code`, which is some JavaScript code to register.

  
`matchAboutBlank` Optional
  Same as `match_about_blank` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  `matches`  Same as `matches` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`runAt` Optional
  Same as `run_at` in the [`content_scripts`](../../manifest.json/content_scripts) key.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`contentScripts.RegisteredContentScript`](registeredcontentscript) object that you can use to unregister the content scripts.

 Currently, content scripts are unregistered when the related extension page (from which the content scripts were registered) is unloaded, so you should register a content script from an extension page that persists at least as long as you want the content scripts to stay registered.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `register` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `cookieStoreId` | No | No | 97 | ? | No | No | ? | ? | 97 | ? | No | ? |


Examples
--------



This example registers the `defaultCode` content script for all `.org` URLs:

 
```
const defaultHosts = "\*://\*.org/\*";
const defaultCode = "document.body.innerHTML = '<h1>This page has been eaten<h1>'";

async function register(hosts, code) {

  return await browser.contentScripts.register({
    matches: [hosts],
    js: [{code}],
    runAt: "document\_idle"
  });

}

let registered = register(defaultHosts, defaultCode);

```
 This code registers the JS file at content\_scripts/example.js:

 
```
const scriptObj = await browser.contentScripts.register({
  "js": [{file: "/content\_scripts/example.js"}],
  "matches": ["<all\_urls>"],
  "allFrames": true,
  "runAt": "document\_start"
});

```

### Example extensions


* [content-script-register](https://github.com/mdn/webextensions-examples/tree/master/content-script-register)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts/register>

menus.create()
==============



Creates a new menu item, given an options object defining properties for the item.

 Unlike other asynchronous functions, this one does not return a promise, but uses an optional callback to communicate success or failure. This is because its return value is the ID of the new item.

 For compatibility with other browsers, Firefox makes this method available via the `contextMenus` namespace as well as the `menus` namespace. Note though that it's not possible to create tools menu items (`contexts: ["tools_menu"]`) using the `contextMenus` namespace.



Syntax
------



```
browser.menus.create(
  createProperties, // object
  () => {/\* … \*/}   // optional function
)

```
### Parameters


 `createProperties`  `object`. Properties for the new menu item.

  
`checked` Optional
  `boolean`. The initial state of a checkbox or radio item: `true` for selected and `false` for unselected. Only one radio item can be selected at a time in a given group of radio items.

  
`command` Optional
  `string`. String describing an action that should be taken when the user clicks the item. The recognized values are:

 * `"_execute_browser_action"`: simulate a click on the extension's browser action, opening its popup if it has one (Manifest V2 only)
* `"_execute_action"`: simulate a click on the extension's action, opening its popup if it has one (Manifest V3 only)
* `"_execute_page_action"`: simulate a click on the extension's page action, opening its popup if it has one
* `"_execute_sidebar_action"`: open the extension's sidebar

 See the documentation of special shortcuts in the manifest.json key [`commands`](../../manifest.json/commands#special_shortcuts) for details.

 When one of the recognized values is specified, clicking the item does not trigger the [`menus.onClicked`](onclicked) event; instead, the default action triggers, such as opening a pop-up. Otherwise, clicking the item triggers [`menus.onClicked`](onclicked) and the event can be used to implement fallback behavior.

  
`contexts` Optional
  `array` of `[`menus.ContextType`](contexttype)`. Array of contexts in which this menu item will appear. If this option is omitted:

 * if the item's parent has contexts set, then this item will inherit its parent's contexts
* otherwise, the item is given a context array of ["page"].

  
`documentUrlPatterns` Optional
  `array` of `string`. Lets you restrict the item to apply only to documents whose URL matches one of the given [match patterns](../../match_patterns). This applies to frames as well.

  
`enabled` Optional
  `boolean`. Whether this menu item is enabled or disabled. Defaults to `true`.

  
`icons` Optional
  `object`. One or more custom icons to display next to the item. Custom icons can only be set for items appearing in submenus. This property is an object with one property for each supplied icon: the property's name should include the icon's size in pixels, and path is relative to the icon from the extension's root directory. The browser tries to choose a 16x16 pixel icon for a normal display or a 32x32 pixel icon for a high-density display. To avoid any scaling, you can specify icons like this:

 
```
"icons": {
        "16": "path/to/geo-16.png",
        "32": "path/to/geo-32.png"
      }

```
 Alternatively, you can specify a single SVG icon, and it will be scaled appropriately:

 
```
"icons": {
        "16": "path/to/geo.svg"
      }

```
  **Note:** The top-level menu item uses the [icons](../../manifest.json/icons) specified in the manifest rather than what is specified with this key.

   
`id` Optional
  `string`. The unique ID to assign to this item. Is mandatory for non-persistent [background (event) pages](../../background_scripts) in Manifest V2 and in Manifest V3. Cannot be the same as another ID for this extension.

  
`onclick` Optional
  `function`. A function that will be called when the menu item is clicked. Event pages cannot use this: instead, they should register a listener for [`menus.onClicked`](onclicked).

  
`parentId` Optional
  `integer` or `string`. The ID of a parent menu item; this makes the item a child of a previously added item. Note: If you have created more than one menu item, then the items will be placed in a submenu. The submenu's parent will be labeled with the name of the extension.

  
`targetUrlPatterns` Optional
  `array` of `string`. Similar to `documentUrlPatterns`, but lets you filter based on the `href` of anchor tags and the `src` attribute of img/audio/video tags. This parameter supports any URL scheme, even those that are usually not allowed in a match pattern.

  
`title` Optional
  `string`. The text to be displayed in the item. Mandatory unless `type` is "separator".

 You can use "`%s`" in the string. If you do this in a menu item, and some text is selected in the page when the menu is shown, then the selected text will be interpolated into the title. For example, if `title` is "Translate '%s' to Pig Latin" and the user selects the word "cool", then activates the menu, then the menu item's title will be: "Translate 'cool' to Pig Latin".

 If the title contains an ampersand "&" then the next character will be used as an access key for the item, and the ampersand will not be displayed. Exceptions to this are:

 * If the next character is also an ampersand: then a single ampersand will be displayed and no access key will be set. In effect, "&&" is used to display a single ampersand.
* If the next characters are the interpolation directive "%s": then the ampersand will not be displayed and no access key will be set.
* If the ampersand is the last character in the title: then the ampersand will not be displayed and no access key will be set.

 Only the first ampersand will be used to set an access key: subsequent ampersands will not be displayed but will not set keys. So "&A and &B" will be shown as "A and B" and set "A" as the access key.

 In some localized versions of Firefox (Japanese and Chinese), the access key is surrounded by parentheses and appended to the menu label, *unless* the menu title itself already ends with the access key (`"toolkit(&K)"` for example). For more details, see [Firefox bug 1647373](https://bugzil.la/1647373).

  
`type` Optional
  `[`menus.ItemType`](itemtype)`. The type of menu item: "normal", "checkbox", "radio", "separator". Defaults to "normal".

  
`viewTypes` Optional
  `[`extension.ViewType`](../extension/viewtype)`. List of view types where the menu item will be shown. Defaults to any view, including those without a `viewType`.

  
`visible` Optional
  `boolean`. Whether the item is shown in the menu. Defaults to `true`.

    
`callback` Optional
  `function`. Called when the item has been created. If there were any problems creating the item, details will be available in [`runtime.lastError`](../runtime/lasterror).

  ### Return value


`integer` or `string`. The `ID` of the newly created item.

Examples
--------



This example creates a context menu item that's shown when the user has selected some text in the page. It just logs the selected text to the console:

 
```
browser.menus.create({
  id: "log-selection",
  title: "Log '%s' to the console",
  contexts: ["selection"]
});

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "log-selection") {
    console.log(info.selectionText);
  }
});

```
 This example adds two radio items, which you can use to choose whether to apply a green or a blue border to the page. Note that this example will need the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 
```
function onCreated() {
  if (browser.runtime.lastError) {
    console.log("error creating item:", browser.runtime.lastError);
  } else {
    console.log("item created successfully");
  }
}

browser.menus.create({
  id: "radio-green",
  type: "radio",
  title: "Make it green",
  contexts: ["all"],
  checked: false
}, onCreated);

browser.menus.create({
  id: "radio-blue",
  type: "radio",
  title: "Make it blue",
  contexts: ["all"],
  checked: false
}, onCreated);

let makeItBlue = 'document.body.style.border = "5px solid blue"';
let makeItGreen = 'document.body.style.border = "5px solid green"';

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "radio-blue") {
    browser.tabs.executeScript(tab.id, {
      code: makeItBlue
    });
  } else if (info.menuItemId === "radio-green") {
    browser.tabs.executeScript(tab.id, {
      code: makeItGreen
    });
  }
});

```

### Example extensions


* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | 5548Before version 53, items that don't specify 'contexts' do not inherit contexts from their parents. | ? | YesItems that don't specify 'contexts' do not inherit contexts from their parents. | 14Items that don't specify 'contexts' do not inherit contexts from their parents. | ? | ? | No | ? | No | ? |
| `accessKey` | Yes | Yes | 63 | ? | Yes | 14Safari removes `&` from menu items' displayed titles, but does not support invoking menu items via access keys. | ? | ? | No | ? | No | ? |
| `command` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `icons` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `visible` | 62 | 79 | 63 | ? | 49 | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#method-create) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/create>

menus.onClicked
===============



Fired when a menu item is clicked.

 For compatibility with other browsers, Firefox makes this event available via the `contextMenus` namespace as well as the `menus` namespace.



Syntax
------




```
browser.menus.onClicked.addListener(listener)
browser.menus.onClicked.removeListener(listener)
browser.menus.onClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `info`  [`menus.OnClickData`](onclickdata). Information about the item clicked and the context where the click happened.

  `tab`  [`tabs.Tab`](../tabs/tab). The details of the tab where the click took place. If the click did not take place in or on a tab, this parameter will be missing.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onClicked` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


Examples
--------



This example listens for clicks on a menu item, then log the item's ID and the tab ID:

 
```
browser.menus.create({
  id: "click-me",
  title: "Click me!",
  contexts: ["all"],
});

browser.menus.onClicked.addListener((info, tab) => {
  console.log(`Item ${info.menuItemId} clicked in tab ${tab.id}`);
});

```

### Example extensions



* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)
* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)
* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)

  **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#event-onClicked) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/onClicked>

contextualIdentities.query()
============================



Gets information about all contextual identities, or about those contextual identities that match a given filter argument.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getContext = browser.contextualIdentities.query(
  details                  // object
)

```
### Parameters


 `details`  `object`. An object that can be used to filter the contextual identities returned. This may contain any of the following properties:

  
`name` Optional
  `string`. Return only contextual identities with this name.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`ContextualIdentity`](contextualidentity) objects, each describing a single identity. If the contextual identities feature is not enabled, the promise is rejected.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `query` | No | No | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | No | ? | ? | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | ? |


Examples
--------



Retrieve all contextual identities, and log their names:

 
```
function onGot(contexts) {
  for (const context of contexts) {
    console.log(`Name: ${context.name}`);
  }
}

function onError(error) {
  console.error(error);
}

browser.contextualIdentities.query({}).then(onGot, onError);

```
 Retrieve all contextual identities whose names are "my-thing", and log their names:

 
```
function onGot(contexts) {
  for (const context of contexts) {
    console.log(`Name: ${context.name}`);
  }
}

function onError(error) {
  console.error(error);
}

browser.contextualIdentities
  .query({
    name: "my-thing",
  })
  .then(onGot, onError);

```

### Example extensions


* [contextual-identities](https://github.com/mdn/webextensions-examples/tree/master/contextual-identities)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/query>

cookies.get()
=============



The `get()` method of the [`cookies`](../cookies) API retrieves information about a single cookie, given its name and URL.

 If more than one cookie with the same name exists for a given URL, the one with the longest path will be returned. For cookies with the same path length, the cookie with the earliest creation time will be returned. If no matching cookie could be found, `null` is returned.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.cookies.get(
  details                // object
)

```
### Parameters


 `details`  An `object` containing details that can be used to match a cookie to be retrieved. It can include the following properties:

  
`firstPartyDomain` Optional
  A `string` representing the first-party domain with which the cookie to retrieve is associated. This property must be supplied if the browser has first-party isolation enabled. See [First-party isolation](../cookies#first-party_isolation).

  `name`  A `string` representing the name of the cookie to retrieve.

  
`partitionKey` Optional
  An `object` representing the [storage partition](../cookies#storage_partitioning) containing the cookie. Include this object with `topLevelSite` to obtain a cookie from partitioned storage. Otherwise, returns the cookie from unpartitioned storage. This object contains:

  
`topLevelSite` Optional
  A `string` representing the first-party URL of the top-level site storage partition containing the cookie.

    
`storeId` Optional
  A `string` representing the ID of the [`cookie store`](cookiestore) in which to look for the cookie (as returned by [`cookies.getAllCookieStores()`](getallcookiestores)). By default, the current execution context's cookie store will be used.

  `url`  A `string` representing the URL with which the cookie to retrieve is associated. This argument may be a full URL, in which case any data following the URL path (e.g. the query string) is ignored. If [host permissions](../../manifest.json/permissions) for this URL are not specified in the extension's [manifest file](../../manifest.json), the API call will fail.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`Cookie`](cookie) object containing details about the cookie, or `null` if the cookie was not found.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 14 | 45Provides access to cookies from private browsing mode and container tabs since version 52. | ? | Yes | 14HTTPOnly cookies are not retrieved. | ? | ? | 48 | ? | 15HTTPOnly cookies are not retrieved. | ? |
| `firstPartyDomain` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | No | ? |


Examples
--------



This example tries to get the cookie named "favorite-color", associated with the URL for the currently active tab:

 
```
function logCookie(cookie) {
  if (cookie) {
    console.log(cookie.value);
  }
}

function getCookie(tabs) {
  let getting = browser.cookies.get({
    url: tabs[0].url,
    name: "favorite-color"
  });
  getting.then(logCookie);
}

let getActive = browser.tabs.query({
  active: true,
  currentWindow: true
});
getActive.then(getCookie);

```

### Example extensions



* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#method-get) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/get>

cookies.set()
=============



The `set()` method of the [`cookies`](../cookies) API sets a cookie containing the specified cookie data. This method is equivalent to issuing an HTTP `Set-Cookie` header during a request to a given URL.

 The call succeeds only if you include the "cookies" [API permission](../../manifest.json/permissions#api_permissions) in your [manifest.json](../../manifest.json) file, as well as [host permissions](../../manifest.json/permissions#host_permissions) for the given URL specified in its manifest. The given URL also needs the necessary permissions to create a cookie with the given parameters.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let setting = browser.cookies.set(
  details               // object
)

```
### Parameters


 `details`  An `object` containing the details of the cookie you wish to set. It can have the following properties:

  
`domain` Optional
  A `string` representing the domain of the cookie. If omitted, the cookie becomes a host-only cookie.

  
`expirationDate` Optional
  A `number` that represents the expiration date of the cookie as the number of seconds since the UNIX epoch. If omitted, the cookie becomes a session cookie.

  
`firstPartyDomain` Optional
  A `string` representing the first-party domain with which the cookie to will be associated. This property must be supplied if the browser has first-party isolation enabled. See [First-party isolation](../cookies#first-party_isolation).

  
`httpOnly` Optional
  A `boolean` that specifies whether the cookie should be marked as HttpOnly (`true`), or not (false). If omitted, it defaults to false.

  
`name` Optional
  A `string` representing the name of the cookie. If omitted, this is empty by default.

  
`partitionKey` Optional
  An `object` representing the [storage partition](../cookies#storage_partitioning) to set the cookie in. Include this object to set a cookie in partitioned storage. This object contains:

  
`topLevelSite` Optional
  A `string` representing the first-party URL of the top-level site storage partition containing the cookie.

    
`path` Optional
  A `string` representing the path of the cookie. If omitted, this defaults to the path portion of the URL parameter.

  
`sameSite` Optional
  A [`cookies.SameSiteStatus`](samesitestatus) value that indicates the SameSite state of the cookie. If omitted, it defaults to 0, 'no\_restriction'.

  
`secure` Optional
  A `boolean` that specifies whether the cookie should be marked as secure (`true`), or not (false). If omitted, it defaults to false.

  
`storeId` Optional
  A `string` representing the ID of the cookie store in which to set the cookie. If omitted, the cookie is set in the current execution context's cookie store by default.

  `url`  A `string` representing the request-URI to associate with the cookie. This value can affect the default domain and path values of the created cookie. If host permissions for this URL are not specified in the manifest file, the method call will fail.

  
`value` Optional
  A `string` representing the value of the cookie. If omitted, this is empty by default.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`cookies.Cookie`](cookie) object containing details about the cookie that's been set. If the call fails for any reason, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `set` | Yes | 14 | 45Before version 56, this function did not modify cookies in private browsing mode. From version 56 onwards this is fixed. | ? | Yes | 14 | ? | ? | 48Before version 56, this function did not modify cookies in private browsing mode. From version 56 onwards this is fixed. | ? | 15 | ? |
| `firstPartyDomain` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | ? | ? |
| `sameSite` | Yes | 79 | 63 | ? | No | 14Only supports explicit. | ? | ? | 63 | ? | 15Only supports explicit. | ? |


Examples
--------



This example sets a cookie for the document hosted by the currently active tab:

 
```
let getActive = browser.tabs.query({active: true, currentWindow: true});
getActive.then(setCookie);

function setCookie(tabs) {
  browser.cookies.set({
    url: tabs[0].url,
    name: "favorite-color",
    value: "red"
  });
}

```

### Example extensions



* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#method-set) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/set>

runtime.openOptionsPage()
=========================



If your extension has an [options page](../../user_interface/options_pages) defined, this method opens it.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let openingPage = browser.runtime.openOptionsPage()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the options page has been created successfully, or rejected with an error message if the operation failed.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openOptionsPage` | 42 | 79 | 48 | ? | 29 | 14 | ? | ? | 57 | ? | 15 | ? |


Examples
--------



Open the options page when the user clicks a browser action's icon:

 
```
function onOpened() {
  console.log(`Options page opened`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let opening = browser.runtime.openOptionsPage();
opening.then(onOpened, onError);

```

### Example extensions



* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-openOptionsPage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/openOptionsPage>

cookies.onChanged
=================



The `onChanged` event of the [`cookies`](../cookies) API fires when a cookie that the extension can access is set or removed.

  **Note:** When [storage partitioning](../cookies#storage_partitioning) is active, `cookies.Cookie.partitionKey` contains the description of the cookie's storage partition. When modifying cookies, it's important to pass this value to [`cookies.set()`](set) or [`cookies.remove()`](remove) to ensure the extension works with the correct cookie.

  Note that updating a cookie's properties is implemented as a two step process:

 1. First, the cookie to be updated is first removed entirely, generating a notification with a [`cookies.OnChangedCause`](onchangedcause) of `overwrite`.
2. Next, a new cookie is written with the updated values, generating a second notification with a [`cookies.OnChangedCause`](onchangedcause) of `explicit`.



Syntax
------




```
browser.cookies.onChanged.addListener(listener)
browser.cookies.onChanged.removeListener(listener)
browser.cookies.onChanged.hasListener(listener)

```
 This API is also available as `browser.cookies.onChanged.*`.

 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `changeInfo`  An `object` containing details of the change that occurred. Its properties are as follows:

  `removed`  A `boolean` that is set to `true` if a cookie was removed, and false if not.

  `cookie`  A [`cookies.Cookie`](cookie) object containing information about the cookie that was set or removed.

  `cause`  A [`cookies.OnChangedCause`](onchangedcause) value representing the underlying reason behind the cookie's change.

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | No | ? |


Examples
--------



This example listens for `onChanged` events and logs details from the `changeInfo` argument:

 
```
browser.cookies.onChanged.addListener((changeInfo) => {
  console.log(`Cookie changed: \n`
    + ` \* Cookie: ${JSON.stringify(changeInfo.cookie)}\n`
    + ` \* Cause: ${changeInfo.cause}\n`
    + ` \* Removed: ${changeInfo.removed}`);
});

```

### Example extensions



* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#event-onChanged) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/onChanged>

cookies.remove()
================



The `remove()` method of the [`cookies`](../cookies) API deletes a cookie, given its name and URL.

 The call succeeds only if you include the "cookies" [API permission](../../manifest.json/permissions#api_permissions) in your [manifest.json](../../manifest.json) file, as well as [host permissions](../../manifest.json/permissions#host_permissions) for the given URL specified in its manifest.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.cookies.remove(
  details               // object
)

```
### Parameters


 `details`  An `object` containing information to identify the cookie to remove. It contains the following properties:

  
`firstPartyDomain` Optional
  A `string` representing the first-party domain with which the cookie to remove is associated. This property must be supplied if the browser has first-party isolation enabled. See [First-party isolation](../cookies#first-party_isolation).

  `name`  A `string` representing the name of the cookie to remove.

  
`partitionKey` Optional
  An `object` representing the [storage partition](../cookies#storage_partitioning) containing the cookie. Include this object to remove a cookie from partitioned storage. This object contains:

  
`topLevelSite` Optional
  A `string` representing the first-party URL of the top-level site storage partition containing the cookie.

    
`storeId` Optional
  A `string` representing the ID of the cookie store to find the cookie in. If unspecified, the cookie is looked for by default in the current execution context's cookie store.

  `url`  A `string` representing the URL associated with the cookie. If the extension does not have [host permissions](../../manifest.json/permissions#host_permissions) for this URL, the API call will fail.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`cookies.Cookie`](cookie) object containing details about the cookie that's been removed. If a cookie matching the `details` parameter could not be found, the promise is fulfilled with `null`. If the call fails for any reason, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 14 | 45Before version 56, this function did not remove cookies from private browsing mode. From version 56 onwards this is fixed. | ? | Yes | 14 | ? | ? | 48Before version 56, this function did not remove cookies from private browsing mode. From version 56 onwards this is fixed. | ? | 15 | ? |
| `firstPartyDomain` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | No | ? |


Examples
--------



This example tries to remove the cookie named "favorite-color", whose URL matches the URL of the document hosted by the currently active tab:

 
```
function onRemoved(cookie) {
  console.log(`Removed: ${cookie}`);
}

function onError(error) {
  console.log(`Error removing cookie: ${error}`);
}

function removeCookie(tabs) {
  let removing = browser.cookies.remove({
    url: tabs[0].url,
    name: "favorite-color"
  });
  removing.then(onRemoved, onError);
}

let getActive = browser.tabs.query({active: true, currentWindow: true});
getActive.then(removeCookie);

```

### Example extensions



* [cookie-bg-picker](https://github.com/mdn/webextensions-examples/tree/master/cookie-bg-picker)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#method-remove) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/remove>

theme.update()
==============


Updates the browser theme according to the content of given [`Theme`](theme) object.


Syntax
------



```
browser.theme.update(
  windowId,    // integer
  theme        // object
)

```
### Parameters


 
`windowId` Optional
  `integer`. The ID of a window. If this is provided, the theme is applied only to that window. If it is omitted the theme is applied to all windows.

  `theme`  `object`. A [`Theme`](theme) object specifying values for the UI elements you want to modify.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `windowId` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Sets the browser theme to use a sun graphic with complementary background color:

 
```
const suntheme = {
 images: {
   theme\_frame: 'sun.jpg',
 },
 colors: {
   frame: '#CF723F',
   tab\_background\_text: '#111',
 }
};

browser.theme.update(suntheme);

```
 Set the theme for just the currently focused window:

 
```
const day = {
    images: {
      theme\_frame: 'sun.jpg',
    },
    colors: {
      frame: '#CF723F',
      tab\_background\_text: '#111',
    }
};

browser.menus.create({
  id: "set-theme",
  title: "set theme",
  contexts: ["all"]
});

async function updateThemeForCurrentWindow() {
  let currentWindow = await browser.windows.getLastFocused();
  browser.theme.update(currentWindow.id, day);
}

browser.menus.onClicked.addListener(updateThemeForCurrentWindow);

```

### Example extensions


* [dynamic-theme](https://github.com/mdn/webextensions-examples/tree/master/dynamic-theme)
* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme/update>

notifications.create()
======================



Creates and displays a notification.

 Pass a [`notifications.NotificationOptions`](notificationoptions) to define the notification's content and behavior.

 You can optionally provide an ID for the notification. If you omit the ID, an ID will be generated. You can use the ID to [`update`](update) or [`clear`](clear) the notification.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Warning:** If you call `notifications.create()` more than once in rapid succession, Firefox may end up not displaying any notification at all.

 

Syntax
------



```
let creating = browser.notifications.create(
  id,                   // optional string
  options               // NotificationOptions
)

```
### Parameters


 
`id` Optional
  `string`. This is used to refer to this notification in [`notifications.update()`](update), [`notifications.clear()`](clear), and event listeners. If you omit this argument or pass an empty string, then a new ID will be generated for this notification. If the ID you provide matches the ID of an existing notification from this extension, then the other notification will be cleared.

  `options`  [`notifications.NotificationOptions`](notificationoptions). Defines the notification's content and behavior.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled when the notification is created and the display process has been started, which is before the notification is actually displayed to the user. It is fulfilled with a string representing the notification's ID.

Examples
--------



This example displays a notification periodically, using [`alarm`](../alarms). Clicking the browser action dismisses the notification. You need the "alarms" [permission](../../manifest.json/permissions) to create alarms (as well as the "notifications" permission to create notifications).

 
```
let cakeNotification = "cake-notification";

/\*

CAKE\_INTERVAL is set to 6 seconds in this example.
Such a short period is chosen to make the extension's behavior
more obvious, but this is not recommended in real life.
Note that in Chrome, alarms cannot be set for less
than a minute.

\*/
let CAKE\_INTERVAL = 0.1;

browser.alarms.create("", { periodInMinutes: CAKE\_INTERVAL });

browser.alarms.onAlarm.addListener((alarm) => {
  browser.notifications.create(cakeNotification, {
    type: "basic",
    iconUrl: browser.runtime.getURL("icons/cake-96.png"),
    title: "Time for cake!",
    message: "Something something cake",
  });
});

browser.browserAction.onClicked.addListener(() => {
  const clearing = browser.notifications.clear(cakeNotification);
  clearing.then(() => {
    console.log("cleared");
  });
});

```

### Example extensions


* [export-helpers](https://github.com/mdn/webextensions-examples/tree/master/export-helpers)
* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)
* [notify-link-clicks-i18n](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/#method-create) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/create>

extension.getBackgroundPage()
=============================



Returns the [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) of the background page if the background script is running. If the script is not running, null is returned.

 This a synchronous function.

  **Note:** This method cannot be used in Private Browsing mode — it always returns null. Consider using [`runtime.sendMessage()`](../runtime/sendmessage) or [`runtime.connect()`](../runtime/connect). See [Firefox bug 1329304](https://bugzil.la/1329304) for more information.

 

Syntax
------



```
let page = browser.extension.getBackgroundPage()

```
### Parameters


None.

### Return value


`object`. [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) of the background page or null.

Examples
--------



Suppose a [background script](../../anatomy_of_a_webextension#background_scripts) defines a function `foo()`:

 
```
// background.js

function foo() {
  console.log("I'm defined in background.js");
}

```
 A script running in a [popup](../../anatomy_of_a_webextension#browser_actions_2) can call this function directly like this:

 
```
// popup.js

let page = browser.extension.getBackgroundPage();
page.foo(); // -> "I'm defined in background.js"

```

### Example extensions


* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)
* [user-agent-rewriter](https://github.com/mdn/webextensions-examples/tree/master/user-agent-rewriter)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBackgroundPage` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-getBackgroundPage) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/getBackgroundPage>

find.highlightResults()
=======================



Highlights the results of a previous call to [`find.find()`](find).

 When an extension calls `find()`, the matches are not highlighted automatically, but they are stored by the browser. Call `highlightResults()` to highlight them.

 Note that the stored results are global across all extensions, so for example, if extension A calls `find("apple")`, then extension B calls `find("banana")`, then if extension A calls `highlightResults()`, the results for "banana" will be highlighted.



Syntax
------



```
browser.find.highlightResults(
  options // optional object
)

```
### Parameters


 
`options` Optional
  `object`. An object specifying additional options. It may take any of the following properties, all optional:

  `tabId`  `integer`. ID of the tab to highlight. Defaults to the active tab.

  `rangeIndex`  `integer`. Index of the range to highlight. Defaults to highlighting all ranges.

  `noScroll`  `boolean`. Don't scroll to highlighted item. Defaults to `true`.

    ### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `highlightResults` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Search the active tab for "banana", log the number of matches, and highlight them:

 
```
function found(results) {
  console.log(`There were: ${results.count} matches.`);
  if (results.count > 0) {
    browser.find.highlightResults();
  }
}

browser.find.find("banana").then(found);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find/highlightResults>

omnibox.onInputChanged
======================



Fired whenever the user changes their input, after they have started interacting with your extension by entering its keyword in the address bar and then pressing the space key.

 This is the event you'll use to populate the address bar's drop-down list with suggestions. The event listener is passed:

 * the current user input (not including the keyword itself or the space after it)
* a callback function which the listener can call with an array of [`omnibox.SuggestResult`](suggestresult) objects, one for each suggestion. Only the first six suggestions will be displayed.



Syntax
------




```
browser.omnibox.onInputChanged.addListener(listener)
browser.omnibox.onInputChanged.removeListener(listener)
browser.omnibox.onInputChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


The listener function will be passed two parameters: a string `text`, and a callback function `suggest`.

### Parameters


 `text`  `String`. The current user input in the address bar, not including the extension's keyword itself or the space after the keyword. Use this to decide which suggestions to display in the drop-down list.

  `suggest`  `Function`. A callback function that the event listener can call to supply suggestions for the address bar's drop-down list. The callback function expects to receive an array of [`omnibox.SuggestResult`](suggestresult) objects, one for each suggestion. Only the first six suggestions will be displayed.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInputChanged` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------



This example interprets the user's input as a CSS property name and populates the drop-down list with one [`omnibox.SuggestResult`](suggestresult) object for each CSS property matching the input. The `description` property of `SuggestResult` is the full name of the property, and the `content` is the MDN page for that property.

 The example also listens to [`omnibox.onInputEntered`](oninputentered), and opens the MDN page corresponding to the selection, according to the [`omnibox.OnInputEnteredDisposition`](oninputentereddisposition) argument.

 
```
browser.omnibox.setDefaultSuggestion({
  description: "Type the name of a CSS property"
});

/\*
Very short list of a few CSS properties.
\*/
const props = [
  "animation",
  "background",
  "border",
  "box-shadow",
  "color",
  "display",
  "flex",
  "flex",
  "float",
  "font",
  "grid",
  "margin",
  "opacity",
  "overflow",
  "padding",
  "position",
  "transform",
  "transition"
];

const baseURL = "https://developer.mozilla.org/en-US/docs/Web/CSS/";

/\*
Return an array of SuggestResult objects,
one for each CSS property that matches the user's input.
\*/
function getMatchingProperties(input) {
  const result = [];
  for (const prop of props) {
    if (prop.startsWith(input)) {
      console.log(prop);
      const suggestion = {
        content: `${baseURL}${prop}`,
        description: prop
      }
      result.push(suggestion);
    } else if (result.length !== 0) {
      return result;
    }
  }
  return result;
}

browser.omnibox.onInputChanged.addListener((input, suggest) => {
  suggest(getMatchingProperties(input));
});

browser.omnibox.onInputEntered.addListener((url, disposition) => {
  switch (disposition) {
    case "currentTab":
      browser.tabs.update({url});
      break;
    case "newForegroundTab":
      browser.tabs.create({url});
      break;
    case "newBackgroundTab":
      browser.tabs.create({url, active: false});
      break;
  }
});

```

### Example extensions



* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)

  **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/onInputChanged>

omnibox.onInputEntered
======================



Fired when the user has selected one of the suggestions your extension has added to the address bar's drop-down list.

 Use this event to handle the user's selection, generally by opening the corresponding page. The event listener is passed:

 * the user's selection
* a [`omnibox.OnInputEnteredDisposition`](oninputentereddisposition): use this to determine whether to open the new page in the current tab, in a new foreground tab, or in a new background tab.



Syntax
------




```
browser.omnibox.onInputEntered.addListener(listener)
browser.omnibox.onInputEntered.removeListener(listener)
browser.omnibox.onInputEntered.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


The listener function will be passed two parameters: a string `text`, and an [`omnibox.OnInputEnteredDisposition`](oninputentereddisposition).

### Parameters


 `text`  `String`. This is the value of the `content` property of the [`omnibox.SuggestResult`](suggestresult) object that the user selected.

  `disposition`  [`OnInputEnteredDisposition`](oninputentereddisposition). A [`omnibox.OnInputEnteredDisposition`](oninputentereddisposition) enumeration, indicating whether the extension should open the page in the current tab, in a new foreground tab, or in a new background tab.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInputEntered` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------



This example interprets the user's input as a CSS property name and populates the drop-down list with one [`omnibox.SuggestResult`](suggestresult) object for each CSS property matching the input. The `description` property of `SuggestResult` is the full name of the property, and the `content` is the MDN page for that property.

 The example also listens to [`omnibox.onInputEntered`](oninputentered), and opens the MDN page corresponding to the selection, according to the [`omnibox.OnInputEnteredDisposition`](oninputentereddisposition) argument.

 
```
browser.omnibox.setDefaultSuggestion({
  description: "Type the name of a CSS property"
});

/\*
Very short list of a few CSS properties.
\*/
const props = [
  "animation",
  "background",
  "border",
  "box-shadow",
  "color",
  "display",
  "flex",
  "flex",
  "float",
  "font",
  "grid",
  "margin",
  "opacity",
  "overflow",
  "padding",
  "position",
  "transform",
  "transition"
];

const baseURL = "https://developer.mozilla.org/en-US/docs/Web/CSS/";

/\*
Return an array of SuggestResult objects,
one for each CSS property that matches the user's input.
\*/
function getMatchingProperties(input) {
  const result = [];
  for (const prop of props) {
    if (prop.startsWith(input)) {
      console.log(prop);
      const suggestion = {
        content: `${baseURL}${prop}`,
        description: prop
      }
      result.push(suggestion);
    } else if (result.length !== 0) {
      return result;
    }
  }
  return result;
}

browser.omnibox.onInputChanged.addListener((input, suggest) => {
  suggest(getMatchingProperties(input));
});

browser.omnibox.onInputEntered.addListener((url, disposition) => {
  switch (disposition) {
    case "currentTab":
      browser.tabs.update({url});
      break;
    case "newForegroundTab":
      browser.tabs.create({url});
      break;
    case "newBackgroundTab":
      browser.tabs.create({url, active: false});
      break;
  }
});

```

### Example extensions



* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)

  **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/onInputEntered>

storage.sync
============



Represents the `sync` storage area. Items in `sync` storage are synced by the browser. The data is then available on all instances of the browser the user is logged into (for example, when using Firefox account on desktop versions of Firefox or a Google account on Chrome) across different devices.

 For Firefox, a user must have `Add-ons` checked under the "Sync Settings" options in `"about:preferences"`.

 Note that the implementation of `storage.sync` in Firefox relies on the Add-on ID. If you use `storage.sync`, you must set an ID for your extension using the [`browser_specific_settings`](../../manifest.json/browser_specific_settings) manifest.json key.

 The main use case of this API is to store preferences about your extension and allow the user to sync them to different profiles.



Storage quotas for sync data
----------------------------



The browser enforces limits on the amount of data each extension is allowed to store in the sync area:

 

| Name | Description | Value in bytes |
| --- | --- | --- |
| Maximum total size |  The maximum total amount of data that each extension is allowed to store in the sync storage area, as measured by the JSON stringification of every value plus every key's length.  | 102400 |
| Maximum item size |  The maximum size of any one item that each extension is allowed to store in the sync storage area, as measured by the JSON stringification of the item's value plus the length of its key.  | 8192 |
| Maximum number of items |  The maximum number of items that each extension can store in the sync storage area.  | 512 |

 If an extension attempts to store items that exceed these limits, calls to [`storage.sync.set()`](storagearea/set) are rejected with an error. An extension can use [`storage.sync.getBytesInUse()`](storagearea/getbytesinuse) to find out how much of its quota is in use.


Synchronization process
-----------------------



In Firefox, extension data is synced every 10 minutes or whenever the user selects **Sync Now** in **Settings** > **Sync** or Firefox account. When the browser performs a sync, for each key stored, it:

 * compares the value on the server with the value at the last sync; if they are different, the value from the server is written to the key in the browser's sync storage.
* compares the browser's sync storage values with the value on the server; if they are different, writes the browser's key value to the server.

 This means that, for each key, a change on the server takes precedence over a change in the browser's sync storage.

 This mechanism is generally OK for data such as user preferences or other global settings changed by the user.

 However, a key's value can be updated on one browser and synchronized then updated on a second browser before the second browser is synchronized, resulting in the local update being overwritten during sync. This mechanism is, therefore, not ideal for data aggregated across devices, such as a count of page views or how many times an option is used. To handle such cases, use [`storage.sync.onChanged`](storagearea/onchanged) to listen for sync updates from the server (for example, a count of page views on another browser instance). Then adjust the value locally to take the remote value into account (for example, update the total views based on the remote count and new local count).


Methods
-------



The `sync` object implements the methods defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.sync.get()`](storagearea/get)  Retrieves one or more items from the storage area.

  [`storage.sync.getBytesInUse()`](storagearea/getbytesinuse)  Gets the amount of storage space (in bytes) used for one or more items in the storage area.

  [`storage.sync.set()`](storagearea/set)  Stores one or more items in the storage area. If the item exists, its value is updated.

  [`storage.sync.remove()`](storagearea/remove)  Removes one or more items from the storage area.

  [`storage.sync.clear()`](storagearea/clear)  Removes all items from the storage area.

  
Events
------



The `sync` object implements the events defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.sync.onChanged`](storagearea/onchanged)  Fires when one or more items in the storage area change.

  
### Example extensions


* [favourite-colour](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sync` | Yes | 15 | 53Before version 79, storage quota limits are not enforced. | ? | No | 14["Safari does not sync items saved in the `sync` storage area, i.e. it behaves the same as the `local` storage area.", "Safari 15 and 15.1 erroneously store sync items in the `local` storage area. If unable to locate sync items, check for sync items in the `local` storage area and do a one-time migration to the `sync` storage area."] | ? | ? | No | ? | 15["Safari does not sync items saved in the `sync` storage area, i.e. it behaves the same as the `local` storage area.", "Safari 15 and 15.1 erroneously store sync items in the `local` storage area. If unable to locate sync items, check for sync items in the `local` storage area and do a one-time migration to the `sync` storage area."] | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#property-sync) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/sync>

find.find()
===========



Searches for text in a tab.

 You can use this function to search normal HTTP(S) web pages. It searches a single tab: you can specify the ID of a particular tab to search, or it will search the active tab by default. It searches all frames in the tab.

 You can make the search case-sensitive and make it match whole words only.

 By default, the function just returns the number of matches found. By passing in the `includeRangeData` and `includeRectData` options, you can get more information about the location of the matches in the target tab.

 This function stores the results internally, so the next time any extension calls [`find.highlightResults()`](highlightresults), then the results of this find call will be highlighted, until the next time someone calls `find()`.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.find.find(
  queryphrase,       // string
  options            // optional object
)

```
### Parameters


 
`options` Optional
  `object`. An object specifying additional options. It may take any of the following properties, all optional:

  `caseSensitive`  `boolean`. If `true` the, the search is case-sensitive. Defaults to `false`.

  `entireWord`  `boolean`. Match only entire words: so "Tok" will not be matched inside "Tokyo". Defaults to `false`.

  `includeRangeData`  `boolean`. Include range data in the response, which describe where in the page DOM the match was found. Defaults to `false`.

  `includeRectData`  `boolean`. Include rectangle data in the response, which describes where in the rendered page the match was found. Defaults to `false`

  `matchDiacritics`  `boolean`. If `true`, the search distinguishes between accented letters and their base letters. For example, when set to `true`, searching for "résumé" does not find a match for "resume". Defaults to `false`.

  `tabId`  `integer`. ID of the tab to search. Defaults to the active tab.

    `queryphrase`  `string`. The text to search for.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object containing up to three properties:

  `count`  `integer`. The number of results found.

  
`rangeData` Optional
  `array`. If `includeRangeData` was given in the `options` parameter, then this property will be included. It is provided as an array of `RangeData` objects, one for each match. Each `RangeData` object describes where in the DOM tree the match was found. This would enable, for example, an extension to get the text surrounding each match, so as to display context for the matches.

 The items correspond to the items given in `rectData`, so `rangeData[i]` describes the same match as `rectData[i]`.

 Each `RangeData` contains the following properties:

  `endOffset`  The ordinal position of the end of the match within its text node.

  `endTextNodePos`  The ordinal position of the text node in which the match ended.

  `framePos`  The index of the frame containing the match. 0 corresponds to the parent window. Note that the order of objects in the `rangeData` array will sequentially line up with the order of frame indexes: for example, `framePos` for the first sequence of `rangeData` objects will be 0, `framePos` for the next sequence will be 1, and so on.

  `startOffset`  The ordinal position of the start of the match within its text node.

  `startTextNodePos`  The ordinal position of the text node in which the match started.

    
`rectData` Optional
  `array`. If `includeRectData` was given in the `options` parameter, then this property will be included. It is an array of `RectData` objects. It contains client rectangles for all the text matched in the search, relative to the top-left of the viewport. Extensions can use this to provide custom highlighting of the results.

 Each `RectData` object contains rectangle data for a single match. It has two properties:

  `rectsAndTexts`  An object containing two properties, both arrays:

 * `rectList`: an array of objects which each have four integer properties: `top`, `left`, `bottom`, `right`. These describe a rectangle relative to the top-left of the viewport.
* `textList`: an array of strings, corresponding to the `rectList` array. The entry at `textList[i]` contains the part of the match bounded by the rectangle at `rectList[i]`.

 For example, consider part of a web page that looks like this:

  ![Text reading "this domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission." and a "More information" link.] 

 If you search for "You may", the match needs to be described by two rectangles:

  ![This domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission.". The words "you may" are highlighted.] 

 In this case, in the `RectData` that describes this match, `rectsAndTexts.rectList` and `rectsAndTexts.textList` will each have 2 items.

 * `textList[0]` will contain "You ", and `rectList[0]` will contain its bounding rectangle.
* `textList[1]` will contain "may", and `rectList[1]` will contain *its* bounding rectangle.

  `text`  The complete text of the match, "You may" in the example above.

    
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `find` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |
| `options` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------


### Basic examples



Search the active tab for "banana", log the number of matches, and highlight them:

 
```
function found(results) {
  console.log(`There were: ${results.count} matches.`);
  if (results.count > 0) {
    browser.find.highlightResults();
  }
}

browser.find.find("banana").then(found);

```
 Search for "banana" across all tabs (note that this requires the "tabs" [permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions), because it accesses `tab.url`):

 
```
async function findInAllTabs(allTabs) {
  for (const tab of allTabs) {
    const results = await browser.find.find("banana", { tabId: tab.id });
    console.log(`In page "${tab.url}": ${results.count} matches.`);
  }
}

browser.tabs.query({}).then(findInAllTabs);

```

### Using rangeData



In this example the extension uses `rangeData` to get the context in which the match was found. The context is the complete `textContent` of the node in which the match was found. If the match spanned nodes, the context is the concatenation of the `textContent` of all spanned nodes.

 Note that for simplicity, this example doesn't handle pages that contain frames. To support this you'd need to split `rangeData` into groups, one per frame, and execute the script in each frame.

 The background script:

 
```
// background.js

async function getContexts(matches) {
  // get the active tab ID
  const activeTabArray = await browser.tabs.query({
    active: true,
    currentWindow: true,
  });
  const tabId = activeTabArray[0].id;

  // execute the content script in the active tab
  await browser.tabs.executeScript(tabId, { file: "get-context.js" });
  // ask the content script to get the contexts for us
  const contexts = await browser.tabs.sendMessage(tabId, {
    ranges: matches.rangeData,
  });
  for (const context of contexts) {
    console.log(context);
  }
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.find.find("example", { includeRangeData: true }).then(getContexts);
});

```
 The content script:

 
```
/\*\*
 \* Get all the text nodes into a single array
 \*/
function getNodes() {
  const walker = document.createTreeWalker(
    document,
    window.NodeFilter.SHOW\_TEXT,
    null,
    false
  );
  const nodes = [];
  while ((node = walker.nextNode())) {
    nodes.push(node);
  }

  return nodes;
}

/\*\*
 \* Gets all text nodes in the document, then for each match, return the
 \* complete text content of nodes that contained the match.
 \* If a match spanned more than one node, concatenate the textContent
 \* of each node.
 \*/
function getContexts(ranges) {
  const contexts = [];
  const nodes = getNodes();

  for (const range of ranges) {
    let context = nodes[range.startTextNodePos].textContent;
    let pos = range.startTextNodePos;
    while (pos < range.endTextNodePos) {
      pos++;
      context += nodes[pos].textContent;
    }
    contexts.push(context);
  }
  return contexts;
}

browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
  sendResponse(getContexts(message.ranges));
});

```

### Using rectData



In this example the extension uses `rectData` to "redact" the matches, by adding black DIVs over the top of their bounding rectangles:

  ![Three search results with some texted redacted by black rectangles.] 

 Note that in many ways this is a poor way to redact pages.

 The background script:

 
```
// background.js

async function redact(matches) {
  // get the active tab ID
  const activeTabArray = await browser.tabs.query({
    active: true,
    currentWindow: true,
  });
  const tabId = activeTabArray[0].id;

  // execute the content script in the active tab
  await browser.tabs.executeScript(tabId, { file: "redact.js" });
  // ask the content script to redact matches for us
  await browser.tabs.sendMessage(tabId, { rects: matches.rectData });
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.find.find("banana", { includeRectData: true }).then(redact);
});

```
 The content script:

 
```
// redact.js

/\*\*
 \* Add a black DIV where the rect is.
 \*/
function redactRect(rect) {
  const redaction = document.createElement("div");
  redaction.style.backgroundColor = "black";
  redaction.style.position = "absolute";
  redaction.style.top = `${rect.top}px`;
  redaction.style.left = `${rect.left}px`;
  redaction.style.width = `${rect.right - rect.left}px`;
  redaction.style.height = `${rect.bottom - rect.top}px`;
  document.body.appendChild(redaction);
}

/\*\*
 \* Go through every rect, redacting them.
 \*/
function redactAll(rectData) {
  for (const match of rectData) {
    for (const rect of match.rectsAndTexts.rectList) {
      redactRect(rect);
    }
  }
}

browser.runtime.onMessage.addListener((message) => {
  redactAll(message.rects);
});

```

### Example extensions


* [find-across-tabs](https://github.com/mdn/webextensions-examples/tree/master/find-across-tabs)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find/find>

omnibox.setDefaultSuggestion()
==============================



Set the default suggestion to appear in the address bar drop-down list when the user starts interacting with your extension.

 Once the user has entered your keyword and started interacting with your extension, the default suggestion will always appear first in the drop-down list. Unlike the suggestions you supply in [`omnibox.onInputChanged`](oninputchanged), this item can't be selected. Use it to provide the user with some guidance about what to type and what they can expect to see when they do.



Syntax
------



```
browser.omnibox.setDefaultSuggestion(
  suggestion            // object
)

```
### Parameters


 `suggestion`  `object`. An object containing a single string property `description`, which will be displayed as the first item in the drop-down when the user starts interacting with your extension.

  ### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setDefaultSuggestion` | 9 | 79 | 52'description' is interpreted as plain text, and XML markup is not recognized. | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------



```
browser.omnibox.setDefaultSuggestion({
  description: "Type the name of a CSS property"
});

```
### Example extensions



* [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search)

  **Note:** This API is based on Chromium's [chrome.omnibox](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/setDefaultSuggestion>

browsingData.remove()
=====================



Removes the specified browsing data.

 The browsing data to be removed is specified in the `dataTypes` option, which is a [`browsingData.DataTypeSet`](datatypeset) object.

 You can use the `removalOptions` option, which is a [`browsingData.RemovalOptions`](removaloptions) object, to control how far back in time to remove data and whether to remove data only from normal web pages or to remove data from hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.remove(
  removalOptions,            // RemovalOptions object
  dataTypes                  // DataTypeSet object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to control how far back in time to remove data, and whether to remove data from hosted web apps and extensions, or just normal web pages.

  `dataTypes`  `object`. A [`browsingData.DataTypeSet`](datatypeset) object, describing the types of data to remove (e.g. history, downloads, …).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove download history and browsing history for the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .remove({ since: oneWeekAgo }, { downloads: true, history: true })
  .then(onRemoved, onError);

```
 Remove all download and browsing history:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData
  .remove({}, { downloads: true, history: true })
  .then(onRemoved, onError);

```

### Example extensions


* [forget-it](https://github.com/mdn/webextensions-examples/tree/master/forget-it)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 79 | 53Specifying `dataTypes.history` will also remove download history and service workers. | ? | Yes | No | ? | ? | 85Specifying `dataTypes.history` will also remove download history and service workers.57–79Specifying `dataTypes.history` will also remove download history and service workers. | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/remove>

identity.launchWebAuthFlow
==========================



Performs the first part of an [OAuth2](https://oauth.net/2/) flow, including user authentication and client authorization.

 This function's only mandatory parameter is the service provider's authorization URL, which must contain a number of URL parameters including the [redirect URL](../identity#getting_the_redirect_url) and the extension's [client ID](../identity#registering_your_add-on). The service provider then:

 * authenticates the user with the service provider, if necessary (that is: if they are not already signed in)
* asks the user to authorize the extension to access the requested data, if necessary (that is: if the user has not already authorized the extension)

 Note that if neither authentication or authorization are needed, then this function will complete silently, without any user interaction.

 This function also takes an optional parameter `interactive`: if this is omitted or set to false, then the flow is forced to complete silently. In this case, if the user has to authenticate or authorize, then the operation will just fail.

 This function returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise): if authentication and authorization were successful, the promise is fulfilled with a redirect URL that contains a number of URL parameters. Depending on the OAuth2 flow implemented by the service provider in question, the extension will need to go through further steps to get a valid access code, which it can then use to access the user's data.

 If there's any error, the promise is rejected with an error message. Error conditions may include:

 * the service provider's URL could not be reached
* the client ID did not match the ID of a registered client
* the redirect URL did not match any redirect URLs registered for this client
* the user did not authenticate successfully
* the user did not authorize the extension
* the `interactive` parameter was omitted or false, but user interaction would have been needed to authorize the extension.



Syntax
------



```
let authorizing = browser.identity.launchWebAuthFlow(
  details   // object
)

```
### Parameters


 `details`  `object`. Options for the flow, containing the following properties:

  `url`  `string`. The URL offered by the OAuth2 service provider to get an access token. The details of this URL should be given in the documentation for the service provider in question, but the URL parameters should always include:

  
`redirect_uri` Optional
  `string`. This represents the URI your extension is redirected to when the flow has finished. Not required for the flow to work on the browser side if it matches the generated redirect URL. See [Getting the redirect URL](../identity#getting_the_redirect_url).

  
`interactive` Optional
  `boolean`. If omitted or `false`, forces the flow to complete silently, without any user interaction.

 If the user is already signed in and has already granted access for the extension, then `launchWebAuthFlow()` can complete silently, without any user interaction. Otherwise (if the service provider needs the user to sign in, or to authorize the extension), then `launchWebAuthFlow()` will prompt the user: that is, the flow will be interactive.

 Extensions should not launch interactive flows except in response to a user action. However, sometimes extensions still want to access the user's data without a direct user action (for example, imagine an extension that wants to access data when the browser launches).

 This is the purpose of `interactive`: if you omit `interactive` or set it to `false`, then the flow is forced to conclude silently: if the service provider needs to interact with the user, the flow will just fail. So as a general rule: set `interactive` to `true` if you're launching the flow in response to a user action, and omit it otherwise.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the extension is authorized successfully, this will be fulfilled with a string containing the redirect URL. The URL will include a parameter that either is an access token or can be exchanged for an access token, using the documented flow for the particular service provider.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `launchWebAuthFlow` | Yes | 79 | 53 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `redirect_uri` | No | No | 53["Since Firefox 86, the `redirect_url` parameter now supports a loopback address, see [Getting the redirect URL](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/identity#getting_the_redirect_url) for details.", "Between Firefox 75 and Firefox 86, the `redirect_uri` URL parameter must be set to the URL returned by `identity.getRedirectURL()`.", "Between Firefox 63 and Firefox 75, the `redirect_uri` URL parameter was optional."] | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This function authorizes an extension to access a user's Google data, according to the documentation at <https://developers.google.com/identity/protocols/OAuth2UserAgent>. Validation of the returned access token isn't shown here:

 
```
function validate(redirectURL) {
  // validate the access token
}

function authorize() {
  const redirectURL = browser.identity.getRedirectURL();
  const clientID = "664583959686-fhvksj46jkd9j5v96vsmvs406jgndmic.apps.googleusercontent.com";
  const scopes = ["openid", "email", "profile"];
  let authURL = "https://accounts.google.com/o/oauth2/auth";
  authURL += `?client\_id=${clientID}`;
  authURL += `&response\_type=token`;
  authURL += `&redirect\_uri=${encodeURIComponent(redirectURL)}`;
  authURL += `&scope=${encodeURIComponent(scopes.join(' '))}`;

  return browser.identity.launchWebAuthFlow({
    interactive: true,
    url: authURL
  });
}

function getAccessToken() {
  return authorize().then(validate);
}

```

### Example extensions



* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)

  **Note:** This API is based on Chromium's [`identity`](https://developer.chrome.com/docs/extensions/reference/identity/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/identity/launchWebAuthFlow>

history.deleteUrl()
===================



Removes all visits to the given URL from the browser history.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let deletingUrl = browser.history.deleteUrl(
  details         // object
)

```
### Parameters


 `details`  `object`. Object containing the URL whose visits to remove.

  `url`  `string`. The URL whose visits should be removed.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with no parameters when the visits have been removed.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `deleteUrl` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Remove all visits to "<https://example.org/>" from history, then check that this URL no longer returned from [`history.search()`](search):

 
```
let urlToRemove = "https://example.org/";

function onGot(results) {
  if (!results.length) {
    console.log(`${urlToRemove} was removed`);
  } else {
    console.log(`${urlToRemove} was not removed`);
  }
}

function onRemoved() {
  let searching = browser.history.search({
    text: urlToRemove,
    startTime: 0
  });

  searching.then(onGot);
}

let deletingUrl = browser.history.deleteUrl({url: urlToRemove});

deletingUrl.then(onRemoved);

```
 Remove the last-visited page from history, with a listener to [`history.onVisitRemoved`](onvisitremoved) to log the URL of the removed page:

 
```
function onRemoved(removeInfo) {
  if (removeInfo.urls.length) {
    console.log(`Removed: ${removeInfo.urls[0]}`);
  }
}

browser.history.onVisitRemoved.addListener(onRemoved);

function onGot(results) {
  if (results.length) {
    console.log(`Removing: ${results[0].url}`);
    browser.history.deleteUrl({url: results[0].url});
  }
}

let searching = browser.history.search({
  text: "",
  startTime: 0,
  maxResults: 1
});

searching.then(onGot);

```

### Example extensions



* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)

  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-deleteUrl) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/deleteUrl>

history.search()
================



Searches the browser's history for [`history.HistoryItem`](historyitem) objects matching the given criteria.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let searching = browser.history.search(
  query                  // object
)

```
### Parameters


 `query`  An object which indicates what to look for in the browser's history. This object has the following fields:

  `text`  `string`. Search history items by URL and title. The string is split up into separate search terms at space boundaries. Each search term is matched case-insensitively against the history item's URL and title. The history item will be returned if all search terms match.

 For example, consider this item:

 URL: `"http://example.org"`

 Title: `"Example Domain"`

 
```
"http"              -> matches
"domain"            -> matches
"MAIN ample"        -> matches
"main tt"           -> matches
"main https"        -> does not match

```
 Specify an empty string (`""`) to retrieve all [`history.HistoryItem`](historyitem) objects that meet all the other criteria.

  
`startTime` Optional
  `number` or `string` or `object`. A value indicating a date and time. This can be represented as: a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object, an [ISO 8601 date string](https://www.iso.org/iso-8601-date-and-time-format.html), or the number of milliseconds since the epoch. If it is supplied, this option excludes results whose `lastVisitTime` is earlier than this time. If it is omitted, the search is limited to the last 24 hours.

  
`endTime` Optional
  `number` or `string` or `object`. A value indicating a date and time. This can be represented as: a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object, an [ISO 8601 date string](https://www.iso.org/iso-8601-date-and-time-format.html), or the number of milliseconds since the epoch. If it is supplied, this option limits results to those visited before this date. If it is omitted, then all entries are considered from the start time onwards.

  
`maxResults` Optional
  `number`. The maximum number of results to retrieve. Defaults to 100, with a minimum value of 1. The function will throw an error if you pass it a `maxResults` value less than 1.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with an array of objects of type [`history.HistoryItem`](historyitem), each describing a single matching history item. Items are sorted in reverse chronological order.

Examples
--------



Logs the URL and last visit time for all history items visited in the last 24 hours:

 
```
function onGot(historyItems) {
  for (const item of historyItems) {
    console.log(item.url);
    console.log(new Date(item.lastVisitTime));
  }
}

browser.history.search({ text: "" }).then(onGot);

```
 Logs the URL and last visit time for all history items ever visited:

 
```
function onGot(historyItems) {
  for (const item of historyItems) {
    console.log(item.url);
    console.log(new Date(item.lastVisitTime));
  }
}

browser.history
  .search({
    text: "",
    startTime: 0,
  })
  .then(onGot);

```
 Logs the URL and last visit time of the most recent visit to a page that contain the string "mozilla":

 
```
function onGot(historyItems) {
  for (const item of historyItems) {
    console.log(item.url);
    console.log(new Date(item.lastVisitTime));
  }
}

browser.history
  .search({
    text: "mozilla",
    startTime: 0,
    maxResults: 1,
  })
  .then(onGot);

```

### Example extensions


* [history-deleter](https://github.com/mdn/webextensions-examples/tree/master/history-deleter)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `search` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-search) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/search>

downloads.erase()
=================



The `erase()` function of the [`downloads`](../downloads) API erases matching [`DownloadItems`](downloaditem) from the browser's download history, without deleting the downloaded files from disk.

 To remove the files from disk, you need to use [`downloads.removeFile()`](removefile).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** If you want to remove a downloaded file from disk *and* erase it from history, you have to call [`downloads.removeFile()`](removefile) before you call `erase()`. If you try it the other way around you'll get an error when calling [`downloads.removeFile()`](removefile), because it no longer exists according to the browser.

 

Syntax
------



```
let erasing = browser.downloads.erase(
  query                    // DownloadQuery
)

```
### Parameters


 `query`  A [`downloads.DownloadQuery`](downloadquery) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the call was successful, the promise will be fulfilled with an array of integers representing the ids of the erased [`DownloadItems`](downloaditem). If no items matching the query parameter could be found, the array will be empty. If the call failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `erase` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



Erase the most recent download:

 
```
function onErased(ids) {
  console.log(`Erased: ${ids}`);
}

function onError(error) {
  console.log(`Error erasing item: ${error}`);
}

let erasing = browser.downloads.erase({
  limit: 1,
  orderBy: ["-startTime"]
});

erasing.then(onErased, onError);

```
 Erase everything:

 
```
function onErased(ids) {
  console.log(`Erased: ${ids}`);
}

function onError(error) {
  console.log(`Error erasing item: ${error}`);
}

let erasing = browser.downloads.erase({});
erasing.then(onErased, onError);

```

### Example extensions



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-erase) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/erase>

downloads.getFileIcon()
=======================



The `getFileIcon()` function of the [`downloads`](../downloads) API retrieves an icon for the specified download.

 For new downloads, file icons are available after the [`downloads.onCreated`](oncreated) event has been received. The image returned by this function while a download is in progress may be different from the image returned after the download is complete.

 Icon retrieval is done by querying the underlying platform. The icon that is returned will therefore depend on a number of factors including state of the download, platform, registered file types and visual theme.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingIcon = browser.downloads.getFileIcon(
  downloadId,           // integer
  options               // optional object
)

```
### Parameters


 `downloadId`  An `integer` representing the ID of the download.

  
`options` Optional
  An options `object` representing preferences for the icon to be retrieved. It can take the following properties:

  
`size` Optional
  An `integer` representing the size of the icon. The returned icon's size will be the provided size squared (in pixels). If omitted, the default size for the icon is 32x32 pixels.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request succeeds, the promise will be fulfilled with a string representing the absolute URL of the icon. If the request fails, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getFileIcon` | Yes | 79 | 48 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This example logs the icon URL for the most recent download:

 
```
function gotIcon(iconUrl) {
  console.log(iconUrl);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function getIcon(downloadItems) {
    if (downloadItems.length > 0) {
      latestDownloadId = downloadItems[0].id;
      let gettingIcon = browser.downloads.getFileIcon(latestDownloadId);
      gettingIcon.then(gotIcon, onError);
    }
  }

let searching = browser.downloads.search({
  limit: 1,
  orderBy: ["-startTime"]
});

searching.then(getIcon, onError);

```

### Example extensions



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-getFileIcon) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/getFileIcon>

downloads.open()
================



The `open()` function of the [`downloads`](../downloads) API opens the downloaded file with its associated application. A [`downloads.onChanged`](onchanged) event will fire when the item is opened for the first time.

 To use this function in your extension you must ask for the "downloads.open" [manifest permission](../../manifest.json/permissions), as well as the "downloads" permission. Also, you can only call this function from inside the handler for a [user action](../../user_actions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let opening = browser.downloads.open(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the `id` of the [`downloads.DownloadItem`](downloaditem) you want to open.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request was successful, the promise will be fulfilled with no arguments. If the request failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `open` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



This example opens the most recently downloaded item:

 
```
function onOpened() {
  console.log(`Opened download item`);
}

function onError(error) {
  console.log(`Error opening item: ${error}`);
}

function openDownload(downloadItems) {
    if (downloadItems.length > 0) {
      let opening = browser.downloads.open(downloadItems[0].id);
      opening.then(onOpened, onError);
    }
  }

let searching = browser.downloads.search({
  limit: 1,
  orderBy: ["-startTime"]
});

searching.then(openDownload, onError);

```

### Example extensions



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-open) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/open>

identity.getRedirectURL()
=========================



Generates a URL that you can use as a redirect URL.

 The URL is derived from your extension's ID, so if you use this function you should probably set your extension's ID explicitly using the [`browser_specific_settings`](../../manifest.json/browser_specific_settings) key (otherwise, each time you [temporarily install the extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/), you'll get a different redirect URL).

 See [Getting a redirect URL](../identity#getting_the_redirect_url) for more information on redirect URLs.



Syntax
------



```
let redirectURL = browser.identity.getRedirectURL()

```
### Parameters


None.

### Return value


A string containing a redirect URL value.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getRedirectURL` | Yes | 79 | 53 | ? | 60 | No | ? | ? | No | ? | No | ? |


Examples
--------



Get the redirect URL:

 
```
let redirectURL = browser.identity.getRedirectURL();

```

### Example extensions



* [google-userinfo](https://github.com/mdn/webextensions-examples/tree/master/google-userinfo)

  **Note:** This API is based on Chromium's [`identity`](https://developer.chrome.com/docs/extensions/reference/identity/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/identity/getRedirectURL>

webRequest.filterResponseData()
===============================



Use this function to create a [`webRequest.StreamFilter`](streamfilter) object for a request. The stream filter gives the web extension full control over the stream, with the ability to monitor and modify the response. It's the extension's responsibility to write and close or disconnect the stream, as the default behavior is to keep the request open without a response.

 You typically call this function from a `webRequest` event listener.

 Firefox uses an optimized byte cache for script requests. This optimized byte cache overrides the normal request caching. Data from this cache is not available in a form useful to extensions. If your extension needs to filter scripts, create your filter in [`webRequest.onBeforeRequest`](onbeforerequest). Doing this ensures that the filter is created prior to the attempt to load from cache, thereby avoiding the optimized cache.



Permissions
-----------



To use this API, you must have the `"webRequest"` and `"webRequestBlocking"` [API permissions](../../manifest.json/permissions#api_permissions), and for the event listener, the [host permission](../../manifest.json/permissions#host_permissions) for the host. In addition:

 * From Firefox 95, to use this API to intercept requests related to the loading of service worker scripts, the `"webRequestFilterResponse.serviceWorkerScript"` permission is also required.
* From Firefox 110, Manifest V3 extensions must also request the `"webRequestFilterResponse"` permission to use this API.


Syntax
------



```
let filter = browser.webRequest.filterResponseData(
  requestId       // string
)

```
### Parameters


 `requestId`  `string`. ID of the request to filter. You can get this from the `details` object that is passed into any `webRequest` event listeners.

  ### Return value


A [`webRequest.StreamFilter`](streamfilter) object that you can use to monitor and modify the response.

Examples
--------



This example shows a minimal implementation that passes through the stream data and closes the filter stream when the stream finishes receiving data. The code would be called from a [`webRequest`](../webrequest) event listener and the event listener provides `details`.

 
```
let filter = browser.webRequest.filterResponseData(details.requestId);
filter.ondata = (event) => {
  console.log(`filter.ondata received ${event.data.byteLength} bytes`);
  filter.write(event.data);
};
filter.onstop = (event) => {
  // The extension should always call filter.close() or filter.disconnect()
  // after creating the StreamFilter, otherwise the response is kept alive forever.
  // If processing of the response data is finished, use close. If any remaining
  // response data should be processed by Firefox, use disconnect.
  filter.close();
};

```
 This example, taken from the [http-response](https://github.com/mdn/webextensions-examples/tree/master/http-response) example extension, creates a filter in [`webRequest.onBeforeRequest`](onbeforerequest) and uses it, to modify the first chunk of the response:

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);
  let decoder = new TextDecoder("utf-8");
  let encoder = new TextEncoder();

  filter.ondata = (event) => {
    let str = decoder.decode(event.data, {stream: true});
    // Just change any instance of Example in the HTTP response
    // to WebExtension Example.
    str = str.replace(/Example/g, 'WebExtension Example');
    filter.write(encoder.encode(str));
    filter.disconnect();
  }

  return {};
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.com/\*"], types: ["main\_frame"]},
  ["blocking"]
);

```

### Example extensions



* [http-response](https://github.com/mdn/webextensions-examples/tree/master/http-response)

  **Note:** The example above only works for small requests that aren't chunked or streamed. More advanced examples are documented with [`webRequest.StreamFilter.ondata`](streamfilter/ondata).

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `filterResponseData` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/filterResponseData>

downloads.removeFile()
======================



The `removeFile()` function of the [`downloads`](../downloads) API removes a downloaded file from disk.

 This API removes the file from disk, but does not remove it from the browser's downloads history, therefore a call to [`downloads.search()`](search) will still return the item as a [`DownloadItem`](downloaditem), but its `exists` attribute will be `false`.

 To remove a file from the downloads history, you need to use [`downloads.erase()`](erase).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** If you want to remove a downloaded file from disk *and* erase it from history, you have to call `removeFile()` before you call [`downloads.erase()`](erase). If you try it the other way around you'll get an error when calling `removeFile()`, because the browser will no longer have a record of the download.

 

Syntax
------



```
let removing = browser.downloads.removeFile(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the id of the [`DownloadItem`](downloaditem) you want to delete from disk.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request was successful, the promise will be fulfilled with no arguments. If the request failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeFile` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



Remove the most recently downloaded file:

 
```
function onRemoved() {
  console.log(`Removed item`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

function remove(downloadItems) {
  if (downloadItems.length > 0) {
    let removing = browser.downloads.removeFile(downloadItems[0].id);
    removing.then(onRemoved, onError);
  }
}

let searching = browser.downloads.search({
  limit: 1,
  orderBy: ["-startTime"]
});

searching.then(remove, onError);

```

### Example extensions



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-removeFile) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/removeFile>

menus.remove()
==============



Removes a menu item.

 For compatibility with other browsers, Firefox makes this method available via the `contextMenus` namespace as well as the `menus` namespace.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.menus.remove(
  menuItemId      // integer or string
)

```
### Parameters


 `menuItemId`  `integer` or `string`. The ID of the menu item to remove.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if removal was successful, or rejected with an error message if removal failed (for example, because the item could not be found).

Examples
--------



This extension adds a menu item labeled "Remove me!". If you click the item, the extension removes it.

 
```
function onRemoved() {
  console.log("item removed successfully");
}

function onError() {
  console.log("error removing item:", browser.runtime.lastError);
}

browser.menus.create({
  id: "remove-me",
  title: "Remove me!",
  contexts: ["all"],
});

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "remove-me") {
    let removing = browser.menus.remove(info.menuItemId);
    removing.then(onRemoved, onError);
  }
});

```

### Example extensions


* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#method-remove) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/remove>

menus.onShown
=============



Fired when the browser has shown a menu.

 An extension can use this event to update its menu items using information that's only available once the menu is shown. Typically an extension will figure out the update in its `onShown` handler and then call [`menus.refresh()`](refresh) to update the menu itself.

 The handler can add, remove, or update menu items.

 For example, the [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open) example extension adds a menu item that's shown when the user clicks a link, and that, when clicked, just opens the link. It uses `onShown` and `refresh()` to annotate the menu item with the hostname for the link, so the user can easily see where they will go before they click.

 Note that an extension should not take too much time before calling `refresh()`, or the update will be noticeable to the user.

 The handler is passed some information about the menu and its contents, and some information from the page (such as the link and/or selection text). To get access to the information from the page, your extension must have the [host permission](../../manifest.json/permissions#host_permissions) for it.

 If the `onShown` handler calls any asynchronous APIs, then it's possible that the menu has been closed again before the handler resumes execution. Because of this, if a handler calls any asynchronous APIs, it should check that the menu is still being displayed before it updates the menu. For example:

 
```
let lastMenuInstanceId = 0;
let nextMenuInstanceId = 1;

browser.menus.onShown.addListener(async (info, tab) => {
  let menuInstanceId = nextMenuInstanceId++;
  lastMenuInstanceId = menuInstanceId;

  // Call an async function
  await /\* the function to call \*/ ;

  // After completing the async operation, check whether the menu is still shown.
  if (menuInstanceId !== lastMenuInstanceId) {
    return; // Menu was closed and shown again.
  }
  // Now use menus.create/update + menus.refresh.
});

browser.menus.onHidden.addListener(() => {
  lastMenuInstanceId = 0;
});

```
 Note that it is possible to call menus API functions synchronously, and in this case you don't have to perform this check:

 
```
browser.menus.onShown.addListener(async (info, tab) => {
  browser.menus.update(menuId /\*, …\*/);
  // Note: Not waiting for returned promise.
  browser.menus.refresh();
});

```
 However, if you call these APIs asynchronously, then you do have to perform the check:

 
```
browser.menus.onShown.addListener(async (info, tab) => {
  let menuInstanceId = nextMenuInstanceId++;
  lastMenuInstanceId = menuInstanceId;

  await browser.menus.update(menuId /\*, …\*/);
  // must now perform the check
  if (menuInstanceId !== lastMenuInstanceId) {
    return;
  }
  browser.menus.refresh();
});

```
 Firefox makes this event available via the `contextMenus` namespace as well as the `menus` namespace.



Syntax
------




```
browser.menus.onShown.addListener(listener)
browser.menus.onShown.removeListener(listener)
browser.menus.onShown.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `info`  `Object`. This is just like the [`menus.OnClickData`](onclickdata) object, except it contains two extra properties:

 * `contexts`: an array of all the [`contexts`](contexttype) that are applicable to this menu.
* `menuIds`: an array of IDs of all menu items belonging to this extension that are being shown in this menu.

 Compared with `menus.OnClickData`, the `info` object also omits the `menuItemId` and `modifiers` properties, because of course these are not available until a menu item has been selected.

 The `contexts`, `menuIds`, `frameId`, and `editable` properties are always provided. All the other properties in `info` are only provided if the extension has the [host permission](../../manifest.json/permissions#host_permissions) for the page.

  `tab`  [`tabs.Tab`](../tabs/tab). The details of the tab where the click took place. If the click did not take place in or on a tab, this parameter will be missing.

    Examples
--------



This example listens for the context menu to be shown over a link, then updates the `openLabelledId` menu item with the link's hostname:

 
```
function updateMenuItem(linkHostname) {
  browser.menus.update(openLabelledId, {
    title: `Open (${linkHostname})`,
  });
  browser.menus.refresh();
}

browser.menus.onShown.addListener((info) => {
  if (!info.linkUrl) {
    return;
  }
  let linkElement = document.createElement("a");
  linkElement.href = info.linkUrl;
  updateMenuItem(linkElement.hostname);
});

```

### Example extensions


* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onShown` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/onShown>

menus.refresh()
===============



Refreshes a menu that's being shown.

 Updates the extension's menu items in the menu that the browser is currently showing, including changes that have been made since the menu was shown. Has no effect if the menu is not being shown. Rebuilding a shown menu is an expensive operation, only invoke this method when necessary.

 This would typically be called from inside a [`menus.onShown`](onshown) event handler, after the handler has made any updates to the menu.

 Firefox makes this function available via the `contextMenus` namespace as well as the `menus` namespace.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.menus.refresh()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `refresh` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This example listens for the context menu to be shown over a link, then updates the `openLabelledId` menu item with the link's hostname:

 
```
function updateMenuItem(linkHostname) {
  browser.menus.update(openLabelledId, {
    title: `Open (${linkHostname})`,
  });
  browser.menus.refresh();
}

browser.menus.onShown.addListener((info) => {
  if (!info.linkUrl) {
    return;
  }
  let linkElement = document.createElement("a");
  linkElement.href = info.linkUrl;
  updateMenuItem(linkElement.hostname);
});

```

### Example extensions


* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/refresh>

downloads.search()
==================



The `search()` function of the [`downloads`](../downloads) API queries the [`DownloadItems`](downloaditem) available in the browser's downloads manager, and returns those that match the specified search criteria.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let searching = browser.downloads.search(query);

```
### Parameters


 `query`  A [`downloads.DownloadQuery`](downloadquery) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). The promise is fulfilled with an `array` of `[`downloads.DownloadItem`](downloaditem)` objects that match the given criteria.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `search` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------


In general, you restrict the items retrieved using the `query` parameter.

### Get downloads matching "query"



```
function logDownloads(downloads) {
  for (const download of downloads) {
    console.log(download.id);
    console.log(download.url);
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.downloads
  .search({
    query: ["imgur"],
  })
  .then(logDownloads, onError);

```
### Get a specific item



To get a specific [`DownloadItem`](downloaditem), the easiest way is to set only the `id` field, as seen in the snippet below:

 
```
function logDownloads(downloads) {
  for (const download of downloads) {
    console.log(download.id);
    console.log(download.url);
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

const id = 13;

browser.downloads.search({ id }).then(logDownloads, onError);

```

### Get all downloads



If you want to return all [`DownloadItems`](downloaditem), set `query` to an empty object.

 
```
function logDownloads(downloads) {
  for (const download of downloads) {
    console.log(download.id);
    console.log(download.url);
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.downloads.search({}).then(logDownloads, onError);

```

### Get the most recent download



You can get the most recent download by specifying the following search parameters:

 
```
function logDownloads(downloads) {
  for (const download of downloads) {
    console.log(download.id);
    console.log(download.url);
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.downloads
  .search({
    limit: 1,
    orderBy: ["-startTime"],
  })
  .then(logDownloads, onError);

```
 You can see this code in action in our [latest-download](https://github.com/mdn/webextensions-examples/blob/master/latest-download/popup/latest_download.js) example.


### Example extensions



* [latest-download](https://github.com/mdn/webextensions-examples/tree/master/latest-download)

  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-search) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/search>

cookies.getAll()
================



The `getAll()` method of the [`cookies`](../cookies) API retrieves all cookies from a single cookie store that match the given information.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.cookies.getAll(
  details                // object
)

```
### Parameters


 `details`  An `object` containing details that can be used to match cookies to be retrieved. Included properties are as follows (see [Cookie type](cookie#type) for more information on these):

  
`domain` Optional
  A `string` representing a domain that cookies must be associated with (they can be associated either with this exact domain or one of its subdomains).

  
`firstPartyDomain` Optional
  A `string` representing the first-party domain with which the cookie to retrieve is associated.

 This property must be supplied if the browser has first-party isolation enabled. You can however pass `null` in this situation. If you do this, then cookies with any value for `firstPartyDomain`, as well as cookies which do not have `firstPartyDomain` set at all, will be included in the results. See [First-party isolation](../cookies#first-party_isolation).

  
`name` Optional
  A `string` representing a name that the cookies should have.

  
`partitionKey` Optional
  An `object` defining which [storage partitions](../cookies#storage_partitioning) to return cookies from:

 * if omitted, returns only cookies from unpartitioned storage.
* if included without `topLevelSite`, returns all cookies from partitioned and unpartitioned storage.
* if included with `topLevelSite` specified, returns cookies from the specified partition storage.

 This object contains:

  
`topLevelSite` Optional
  A `string` representing the first-party URL of the top-level site storage partition containing the cookies.

    
`path` Optional
  A `string` representing a path — the cookies' path must be identical to this one.

  
`secure` Optional
  A `boolean` — filters cookies by their `secure` property, allowing you to filter secure cookies vs. non-secure cookies.

  
`session` Optional
  A `boolean` — filters the cookies by their `session` property, allowing you to filter session cookies vs. persistent cookies.

  
`storeId` Optional
  A `string` representing the cookie store to retrieve cookies from. If omitted, the current execution context's cookie store will be used.

  
`url` Optional
  A `string` representing a URL that the retrieved cookies must be associated with.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of `[`cookies.Cookie`](cookie)` objects that match the properties given in the `details` parameter. Only unexpired cookies are returned. The cookies returned will be sorted by path length, longest to shortest. If multiple cookies have the same path length, those with the earliest creation time will be first.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 14If no URL is provided, cookies are retrieved only for URLs in currently opened tabs. In Chrome, this gets all cookies on a user's machine. | 45Before version 52, the 'tabIds' list was empty and only cookies from the default cookie store were returned. From version 52 onwards, this has been fixed and the result includes cookies from private browsing mode and container tabs. | ? | Yes | 14["Only the cookies in the default cookie store are retrieved.", "HTTPOnly cookies are not retrieved."] | ? | ? | 48 | ? | 15["Only the cookies in the default cookie store are retrieved.", "HTTPOnly cookies are not retrieved."] | ? |
| `firstPartyDomain` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | No | ? |


Examples
--------



In the following snippet, we are making a call to get all of the cookies the browser currently has stored that have a name of "favorite-color". When the result is returned, we are printing the value of each result to the console.

 
```
function logCookies(cookies) {
  for (const cookie of cookies) {
    console.log(cookie.value);
  }
}

browser.cookies
  .getAll({
    name: "favorite-color",
  })
  .then(logCookies);

```

### Example extensions



* [list-cookies](https://github.com/mdn/webextensions-examples/tree/master/list-cookies)

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#method-getAll) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/getAll>

menus.update()
==============



Updates a previously created menu item.

 For compatibility with other browsers, Firefox makes this method available via the `contextMenus` namespace as well as the `menus` namespace.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let updating = browser.menus.update(
  id,               // integer or string
  updateProperties // object
)

```
### Parameters


 `id`  `integer` or `string`. The ID of the item to update.

  `updateProperties`  `object`. The properties to update. The same as the `createProperties` object passed to [`menus.create()`](create), except that `id` can't be set. In addition, `icons` can only be changed on menu commands, not on the top-level context menu. The top-level icon matches the extension's primary icon as declared in the extension's manifest file.

  
`checked` Optional
  `boolean`. The initial state of a checkbox or radio item: `true` for selected and `false` for unselected. Only one radio item can be selected at a time in a given group of radio items.

  
`command` Optional
  `string`. String describing an action that should be taken when the user clicks the item. The recognized values are:

 * `"_execute_browser_action"`: simulate a click on the extension's browser action, opening its popup if it has one (Manifest V2 only)
* `"_execute_action"`: simulate a click on the extension's action, opening its popup if it has one (Manifest V3 only)
* `"_execute_page_action"`: simulate a click on the extension's page action, opening its popup if it has one
* `"_execute_sidebar_action"`: open the extension's sidebar

 See the documentation of special shortcuts in the manifest.json key [`commands`](../../manifest.json/commands#special_shortcuts) for details.

 When one of the recognized values is specified, clicking the item does not trigger the [`menus.onClicked`](onclicked) event; instead, the default action triggers, such as opening a pop-up. Otherwise, clicking the item triggers [`menus.onClicked`](onclicked) and the event can be used to implement fallback behavior.

  
`contexts` Optional
  `array` of `[`menus.ContextType`](contexttype)`. Array of contexts in which this menu item will appear. If this option is omitted:

 * if the item's parent has contexts set, then this item will inherit its parent's contexts
* otherwise, the item is given a context array of ["page"].

  
`documentUrlPatterns` Optional
  `array` of `string`. Lets you restrict the item to apply only to documents whose URL matches one of the given [match patterns](../../match_patterns). This applies to frames as well.

  
`enabled` Optional
  `boolean`. Whether this menu item is enabled or disabled. Defaults to `true`.

  
`icons` Optional
  `object`. One or more custom icons to display next to the item. Custom icons can only be set for items appearing in submenus. This property is an object with one property for each supplied icon: the property's name should include the icon's size in pixels, and path is relative to the icon from the extension's root directory. The browser tries to choose a 16x16 pixel icon for a normal display or a 32x32 pixel icon for a high-density display. To avoid any scaling, you can specify icons like this:

 
```
"icons": {
      "16": "path/to/geo-16.png",
      "32": "path/to/geo-32.png"
    }

```
 Alternatively, you can specify a single SVG icon, and it will be scaled appropriately:

 
```
"icons": {
      "16": "path/to/geo.svg"
    }

```
  **Note:** The top-level menu item uses the [icons](../../manifest.json/icons) specified in the manifest rather than what is specified with this key.

   
`id` Optional
  `string`. The unique ID to assign to this item. Mandatory for event pages. Cannot be the same as another ID for this extension.

  
`onclick` Optional
  `function`. A function that will be called when the menu item is clicked. Event pages cannot use this: instead, they should register a listener for [`menus.onClicked`](onclicked).

  
`parentId` Optional
  `integer` or `string`. The ID of a parent menu item; this makes the item a child of a previously added item. Note: If you have created more than one menu item, then the items will be placed in a submenu. The submenu's parent will be labeled with the name of the extension.

  
`targetUrlPatterns` Optional
  `array` of `string`. Similar to `documentUrlPatterns`, but lets you filter based on the `href` of anchor tags and the `src` attribute of img/audio/video tags. This parameter supports any URL scheme, even those that are usually not allowed in a match pattern.

  
`title` Optional
  `string`. The text to be displayed in the item. Mandatory unless `type` is "separator".

 You can use "`%s`" in the string. If you do this in a menu item, and some text is selected in the page when the menu is shown, then the selected text will be interpolated into the title. For example, if `title` is "Translate '%s' to Pig Latin" and the user selects the word "cool", then activates the menu, then the menu item's title will be: "Translate 'cool' to Pig Latin".

 If the title contains an ampersand "&" then the next character will be used as an access key for the item, and the ampersand will not be displayed. Exceptions to this are:

 * If the next character is also an ampersand: then a single ampersand will be displayed and no access key will be set. In effect, "&&" is used to display a single ampersand.
* If the next characters are the interpolation directive "%s": then the ampersand will not be displayed and no access key will be set.
* If the ampersand is the last character in the title: then the ampersand will not be displayed and no access key will be set.

 Only the first ampersand will be used to set an access key: subsequent ampersands will not be displayed but will not set keys. So "&A and &B" will be shown as "A and B" and set "A" as the access key.

  
`type` Optional
  `[`menus.ItemType`](itemtype)`. The type of menu item: "normal", "checkbox", "radio", "separator". Defaults to "normal".

  
`viewTypes` Optional
  `[`extension.ViewType`](../extension/viewtype)`. List of view types where the menu item will be shown. Defaults to any view, including those without a `viewType`.

  
`visible` Optional
  `boolean`. Whether the item is shown in the menu. Defaults to `true`.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if the update was successful, or rejected with an error message if the update failed.

Examples
--------



This example creates a menu item, then updates its title when the user clicks it:

 
```
function onUpdated() {
  console.log("item updated successfully");
}

function onError() {
  console.log("error updating item:", browser.runtime.lastError);
}

browser.menus.create({
  id: "do-not-click-me",
  title: "Do not click this button",
  contexts: ["all"]
});

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "do-not-click-me") {
    let updating = browser.menus.update(info.menuItemId, {
      title: "Do not click this button again"
    });
    updating.then(onUpdated, onError);
  }
});

```

### Example extensions


* [menu-accesskey-visible](https://github.com/mdn/webextensions-examples/tree/master/menu-accesskey-visible)
* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)
* [menu-labelled-open](https://github.com/mdn/webextensions-examples/tree/master/menu-labelled-open)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#method-update) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/update>

runtime.lastError
=================



This value is used to report an error message from an asynchronous API, when the asynchronous API is given a callback. This is useful for extensions that are using the callback-based version of the WebExtension APIs.

 You don't need to check this property if you are using the promise-based version of the APIs: instead, pass an error handler to the promise:

 
```
const gettingCookies = browser.cookies.getAll();
gettingCookies.then(onGot, onError);

```
 The `runtime.lastError` property is set when an asynchronous function has an error condition that it needs to report to its caller.

 If you call an asynchronous function that may set `lastError`, you are expected to check for the error when you handle the result of the function. If `lastError` has been set and you don't check it within the callback function, then an error will be raised.



Syntax
------



```
let myError = browser.runtime.lastError;  // null or Error object

```
### Value


An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object representing the error. The [`message`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message) property is a `string` with a human-readable description of the error. If `lastError` has not been set, the value is `null`.

Examples
--------



Set a cookie, using a callback to log the new cookie or report an error:

 
```
function logCookie(c) {
  if (browser.runtime.lastError) {
    console.error(browser.runtime.lastError);
  } else {
    console.log(c);
  }
}

browser.cookies.set(
  {url: "https://developer.mozilla.org/"},
  logCookie
);

```
 The same, but using a promise to handle the result of `setCookie()`:

 
```
function logCookie(c) {
  console.log(c);
}

function logError(e) {
  console.error(e);
}

const setCookie = browser.cookies.set(
  {url: "https://developer.mozilla.org/"}
);

setCookie.then(logCookie, logError);

```
  **Note:** `runtime.lastError` is an alias for [`extension.lastError`](../extension/lasterror). They are set together, and checking either one will work.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `lastError` | YeslastError is not an Error object. Instead, it is a plain Object with the error text as the string value of the 'message' property. | 14 | 47 | ? | YeslastError is not an Error object. Instead, it is a plain Object with the error text as the string value of the 'message' property. | 14`lastError` is only set if a callback is used. `Promise` results that fail will be rejected with an `Error` object. | ? | ? | 48 | ? | 15`lastError` is only set if a callback is used. `Promise` results that fail will be rejected with an `Error` object. | ? |


### Example extensions



* [menu-demo](https://github.com/mdn/webextensions-examples/tree/master/menu-demo)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#property-lastError) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/lastError>

pageAction.openPopup()
======================



Open the page action's popup.

 You can only call this function from inside the handler for a [user action](../../user_actions).



Syntax
------



```
browser.pageAction.openPopup()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openPopup` | No | No | 57 | ? | No | 16 | ? | ? | 79 | ? | 16 | ? |


Examples
--------



Open the popup when the user selects a context menu item:

 
```
browser.menus.create({
  id: "open-popup",
  title: "open popup",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(() => {
  browser.pageAction.openPopup();
});

```

### Example extensions


* [menu-remove-element](https://github.com/mdn/webextensions-examples/tree/master/menu-remove-element)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/openPopup>

search.search()
===============



Perform a search using the search engine specified or the default search engine if no search engine is specified.

 The results are displayed in the current tab, a new tab, or a new window according to the `disposition` property or in the tab specified in the `tabId` property. If neither is specified, the results display in a new tab.

 To use this function, your extension must have the `"search"` [manifest permission](../../manifest.json/permissions).

 To get the installed search engines, use [`search.get()`](get).



Syntax
------



```
browser.search.search(
  searchProperties       // object
)

```
### Parameters


 `searchProperties`  `object`. An object with the following properties:

  
`disposition` Optional
  `string`. The location where the search results are displayed. Valid values are `CURRENT_TAB`, `NEW_TAB`, and `NEW_WINDOW`. Defaults to `NEW_TAB`. Cannot be specified with `tabId`.

  
`engine` Optional
  `string`. The name of the search engine. If the search engine name doesn't exist, the function rejects the call with an error. If this property is omitted, the default search engine is used.

  `query`  `string`. The search query.

  
`tabId` Optional
  `integer`. An optional identifier for the tab you want to execute the search in. If this property is omitted, the search results are displayed in a new tab. Cannot be specified with `disposition`.

    ### Return value


None.

Examples
--------



A search using the default search engine with the results shown in the current tab (default):

 
```
function search() {
  browser.search.search({
    query: "styracosaurus"
  });
}

browser.browserAction.onClicked.addListener(search);

```
 A search using Wikipedia with the results shown in a new window:

 
```
function search() {
  browser.search.search({
    query: "styracosaurus",
    engine: "Wikipedia (en)"
    disposition: "NEW\_WINDOW"
  });
}

browser.browserAction.onClicked.addListener(search);

```
 A search using Wikipedia with the results shown in the current tab:

 
```
function search(tab) {
  browser.search.search({
    query: "styracosaurus",
    engine: "Wikipedia (en)",
    tabId: tab.id
  });
}

browser.browserAction.onClicked.addListener(search);

```

### Example extensions


* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `search` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |
| `searchProperties` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/search/search>

webNavigation.onCompleted
=========================


Fired when a document, including the resources it refers to, is completely loaded and initialized. This is equivalent to the DOM [`load`](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event) event.


Syntax
------




```
browser.webNavigation.onCompleted.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onCompleted.removeListener(listener)
browser.webNavigation.onCompleted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation has occurred.

  `url`  `string`. The URL to which the given frame has navigated.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation has occurred. `0` indicates that navigation happened in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happened in a nested iframe. Frame IDs are unique for a given tab and process.

  `timeStamp`  `number`. The time at which the page finished loading, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCompleted` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |


Examples
--------



Logs the target URLs for `onCompleted`, if the target URL's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnCompleted(details) {
  console.log(`onCompleted: ${details.url}`);
}

browser.webNavigation.onCompleted.addListener(logOnCompleted, filter);

```

### Example extensions



* [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats)

  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onCompleted>

permissions.remove()
====================



Ask to give up the permissions listed in the given [`permissions.Permissions`](permissions) object.

 The `Permissions` argument may contain either an `origins` property, which is an array of [host permissions](../../manifest.json/permissions#host_permissions), or a `permissions` property, which is an array of [API permissions](../../manifest.json/permissions#api_permissions), or both. Permissions must come from the set of permissions defined in the [`optional_permissions`](../../manifest.json/optional_permissions) manifest.json key.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.permissions.remove(
  permissions                // Permissions object
)

```
### Parameters


 `permissions`  A [`permissions.Permissions`](permissions) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with `true` if the permissions listed in the `permissions` argument are now not granted to the extension, or `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 79 | 55 | ? | Yes | 14Removing `<all_urls>` or `*://*/*` origins will remove previously granted permission to request specific origin patterns and will stop automatically prompting the user for access to any visited website via the extension's access popover in the toolbar. | ? | ? | 79 | ? | 15Removing `<all_urls>` or `*://*/*` origins will remove previously granted permission to request specific origin patterns and will stop automatically prompting the user for access to any visited website via the extension's access popover in the toolbar. | ? |


Examples
--------



This code adds a click handler that removes a given permission.

 
```
const permissionToRemove = {
  permissions: ["history"]
}

async function remove() {
  console.log("removing");
  const removed = await browser.permissions.remove(permissionToRemove);
  console.log(removed);
}

document.querySelector("#remove").addEventListener("click", remove);

```

### Example extensions



* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)

  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/remove>

permissions.request()
=====================



Ask for the set of permissions listed in the given [`permissions.Permissions`](permissions) object.

 The `Permissions` argument may contain either an `origins` property, which is an array of [host permissions](../../manifest.json/permissions#host_permissions), or a `permissions` property, which is an array of [API permissions](../../manifest.json/permissions#api_permissions), or both. Permissions must come from the set of permissions defined in the [`optional_permissions`](../../manifest.json/optional_permissions) manifest.json key. The `origins` property may include permissions that match a subset of the hosts matched by an optional permission: for example, if optional\_permissions include "\*://mozilla.org/", then `permissions.origins` may include "<https://developer.mozilla.org/>".

 The request can only be made inside the handler for a [user action](../../user_actions).

 Depending on a circumstances, the browser will probably handle the request by asking the user whether to grant the requested permissions. Only a single request is made for all requested permissions: thus either all permissions are granted or none of them are.

 Any permissions granted are retained by the extension, even over upgrade and disable/enable cycling.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let requesting = browser.permissions.request(
  permissions                // Permissions object
)

```
### Parameters


 `permissions`  A [`permissions.Permissions`](permissions) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with `true` if the extension is now granted all the permissions listed in the `permissions` argument, or `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `request` | Yes | 79 | 55["It's not possible to request permissions from a sidebar document ([bug 1493396](https://bugzil.la/1493396)).", "Before version 75, permissions cannot be requested from popup panels (see [bug 1432083](https://bugzil.la/1432083)).", "Before version 61, permissions cannot be requested from options pages embedded in `about:addons` (see [bug 1382953](https://bugzil.la/1382953))."] | ? | Yes | 14["Requesting `<all_urls>` or `*://*/*` origins will grant permission to request specific origin patterns and automatically prompt the user for access to any visited website via the extension's access popover in the toolbar.", "The user will be prompted again for permissions that have been previously granted and then removed.", "Supported permissions will be granted without prompting the user. Only specific origin patterns will prompt the user."] | ? | ? | 102 | ? | 15["Requesting `<all_urls>` or `*://*/*` origins will grant permission to request specific origin patterns and automatically prompt the user for access to any visited website via the extension's banner.", "The user will be prompted again for permissions that have been previously granted and then removed.", "Supported permissions will be granted without prompting the user. Only specific origin patterns will prompt the user."] | ? |


Examples
--------



This code adds a click handler that asks for various permissions, then logs the result of the request and the extension's permissions after the request completed.

 
```
const permissionsToRequest = {
  permissions: ["bookmarks", "history"],
  origins: ["https://developer.mozilla.org/"]
}

async function requestPermissions() {

  function onResponse(response) {
    if (response) {
      console.log("Permission was granted");
    } else {
      console.log("Permission was refused");
    }
    return browser.permissions.getAll();
  }

  const response = await browser.permissions.request(permissionsToRequest);
  const currentPermissions = await onResponse(response);

  console.log(`Current permissions:`, currentPermissions);
}

document.querySelector("#request").addEventListener("click", requestPermissions);

```

### Example extensions



* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)

  **Note:** Currently has a [bug with requesting origins](https://bugzil.la/1411873) and [requesting permissions on the about:addons page](https://bugzil.la/1382953).

   **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/request>

theme.reset()
=============



Resets any theme that was applied using the [`theme.update()`](update) method.

 Note that this will always reset the theme back to the original default theme, even if the user had selected a different theme before this extension's theme was applied (see [bug 1415267](https://bugzil.la/1415267)).



Syntax
------



```
browser.theme.reset(
  windowId     // integer
)

```
### Parameters


 
`windowId` Optional
  `integer`. The ID of a window. If this is provided, the theme applied to that window will be reset. If it is omitted the theme will be reset on all windows.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `reset` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `windowId` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code applies a theme, then removes it when the user clicks a browser action:

 
```
browser.theme.update(themes.night);

browser.browserAction.onClicked.addListener(() => {
  browser.theme.reset();
});

```

### Example extensions


* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme/reset>

windows.getAll()
================



Gets information about all open windows, passing them into a callback.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingAll = browser.windows.getAll(
  getInfo                // optional object
)

```
### Parameters


 
`getInfo` Optional
  `object`. This controls what [`windows.Window`](window) objects are retrieved.

  
`populate` Optional
  `boolean`. Defaults to `false`. If set to `true`, each [`windows.Window`](window) object will have a `tabs` property that contains a list of [`tabs.Tab`](../tabs/tab) objects representing the tabs in that window. The `Tab` objects will contain the `url`, `title` and `favIconUrl` properties only if the extension's manifest file includes the `"tabs"` permission or [host permissions](../../manifest.json/permissions#host_permissions) that match the tab's URL.

  
`windowTypes` Optional
  An `array` of [`windows.WindowType`](windowtype) objects. If set, the [`windows.Window`](window) objects returned will be filtered based on their type. If unset the default filter is set to `['normal', 'panel', 'popup']`, with `'panel'` window types limited to the extension's own windows.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`windows.Window`](window) objects, representing all windows that match the given criteria. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `populate` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `windowTypes` | 46 | 14 | 58 | ? | 33 | 14 | ? | ? | No | ? | No | ? |


Examples
--------



Log the URLs for the tabs across all "normal" browser windows. Note that you'll need the "tabs" [permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions) to access tab URLs.

 
```
function logTabsForWindows(windowInfoArray) {
  for (const windowInfo of windowInfoArray) {
    console.log(`Window: ${windowInfo.id}`);
    console.log(windowInfo.tabs.map((tab) => tab.url));
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.windows
    .getAll({
      populate: true,
      windowTypes: ["normal"],
    })
    .then(logTabsForWindows, onError);
});

```

### Example extensions



* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)
* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-getAll) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/getAll>

search.get()
============



Gets an array of all installed search engines.

 Each search engine returned is identified with a name, which you can pass into [`search.search()`](search) to use that particular engine to make a search.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingEngines = browser.search.get()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of search engine objects. Each search engine object may contain the following properties:

  `name`  `string`. The search engine's name.

  `isDefault`  `boolean`. `true` if the search engine is the default. Only one search engine can be the default at any given time.

  
`alias` Optional
  `string`. If a search engine has an alias, the user can search with a particular search engine by entering the alias in address bar before the search term. For example, if the Wikipedia engine has an alias "wk", the user can search Wikipedia for pandas by entering "wk pandas" in the address bar. The alias is sometimes also called a "keyword".

  
`favIconUrl` Optional
  `string`. The search engine's icon, as a data: URL.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Get all installed search engines:

 
```
function retrieved(results) {
  console.log(`There were: ${results.length} search engines retrieved.`);
  for (const searchEngine of results) {
    console.log(JSON.stringify(searchEngine.name));
  }
}

browser.search.get().then(retrieved);

```

### Example extensions


* [menu-search](https://github.com/mdn/webextensions-examples/tree/master/menu-search)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/search/get>

webNavigation.onCommitted
=========================


Fired when a navigation is committed. At least part of the new document has been received from the server and the browser has decided to switch to the new document.


Syntax
------




```
browser.webNavigation.onCommitted.addListener(
  listener,                 // function
  filter                    // optional object
)
browser.webNavigation.onCommitted.removeListener(listener)
browser.webNavigation.onCommitted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation is about to occur.

  `url`  `string`. The URL to which the given frame will navigate.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation will occur. `0` indicates that navigation happens in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happens in a nested iframe. Frame IDs are unique for a given tab and process.

  `parentFrameId`  `integer`. ID of this frame's parent. Set to `-1` if this is a top-level frame.

  `timeStamp`  `number`. The time that the navigation was committed, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `transitionType`  [`transitionType`](transitiontype). The reason for the navigation. (For example, `"link"` if the user clicked a link, or `"reload"` if the user reloaded the page.)

  `transitionQualifiers`  `Array` of [`transitionQualifier`](transitionqualifier). Extra information about the navigation: for example, whether there was a server or client redirect.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCommitted` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `transitionQualifiers` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `transitionType` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



Logs the target URLs and extra transition information for `onCommitted`, if the target URL's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnCommitted(details) {
  console.log(`target URL: ${details.url}`);
  console.log(`transition type: ${details.transitionType}`);
  console.log(`transition qualifiers: ${details.transitionQualifiers}`);
}

browser.webNavigation.onCommitted.addListener(logOnCommitted, filter);

```

### Example extensions



* [navigation-stats](https://github.com/mdn/webextensions-examples/tree/master/navigation-stats)

  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onCommitted>

permissions.getAll()
====================



Retrieve a [`permissions.Permissions`](permissions) object containing all the permissions currently granted to the extension.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingAll = browser.permissions.getAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`permissions.Permissions`](permissions) object containing all the permissions currently granted to the extension. This includes all permissions the extension has listed in the [`permissions`](../../manifest.json/permissions) key, and any permissions listed in [`optional_permissions`](../../manifest.json/optional_permissions) that the extension has been granted by calling [`permissions.request()`](request).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



```
// Extension permissions are:
// "webRequest", "tabs", "\*://\*.mozilla.org/\*"

const currentPermissions = await browser.permissions.getAll();

console.log(currentPermissions.permissions); // [ "webRequest", "tabs" ]
console.log(currentPermissions.origins); // [ "\*://\*.mozilla.org/\*" ]

```
### Example extensions



* [permissions](https://github.com/mdn/webextensions-examples/tree/master/permissions)

  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/getAll>

proxy.onRequest
===============



Fired when a web request is about to be made, to give the extension an opportunity to proxy it.

 This event is closely modeled on the events defined in the [`webRequest`](../webrequest) API. Like those events, its `addListener()` function takes three arguments:

 * the listener that is called when the event is fired.
* a [`RequestFilter`](../webrequest/requestfilter) object controlling which requests cause the event to fire.
* an array of strings to control other aspects of the event's behavior.

 The event is fired before any of the `webRequest` events for the same request.

 When the event is fired, the listener is called with an object containing information about the request. The listener returns a [`proxy.ProxyInfo`](proxyinfo) object representing a proxy to use (or an array of [`proxy.ProxyInfo`](proxyinfo) objects, enabling the browser to fail over if a proxy is unreachable).

 To use `proxy.onRequest`, an extension must have the "proxy" [API permission](../../manifest.json/permissions#api_permissions) and the [host permission](../../manifest.json/permissions#host_permissions) for the URLs of the requests that it intercepts, which means that the match patterns in the `filter` argument must be a subset of the extension's host permissions.



Syntax
------




```
browser.proxy.onRequest.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.proxy.onRequest.removeListener(listener)
browser.proxy.onRequest.hasListener(listener)

```
 Events have three functions:

  `addListener(listener, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `listener`  The function that is called when this event occurs. The function is passed a single argument, which is a [`proxy.RequestDetails`](requestdetails) object containing details of the request.

 The listener can return any of:

 * a [`proxy.ProxyInfo`](proxyinfo) object.
* an array of [`proxy.ProxyInfo`](proxyinfo) objects.
* a `Promise` that resolves to a `ProxyInfo` object.
* a `Promise` that resolves to an array of `ProxyInfo` objects.

 If the listener returns an array, or a Promise that resolves to an array, then all `ProxyInfo` objects after the first one represent failovers: if the proxy at position N in the array is not reachable when its `ProxyInfo.failoverTimeout` expires the browser will try the proxy at position N+1.

 If there is an error specifying the [`proxy.ProxyInfo`](proxyinfo) objects, then [`proxy.onError`](onerror) is called.

  `filter`  [`webRequest.RequestFilter`](../webrequest/requestfilter). A set of filters that restricts the events that are sent to the listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. Pass `"requestHeaders"` to include the request headers in the `details` object passed to the listener.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRequest` | No | No | 60Before version 78, the `tabId` and `windowId` filter properties are ignored. | ? | No | No | ? | ? | 60 | ? | No | ? |


Examples
--------



This code intercepts requests to `<all_urls>`, and proxies them if they are not for a top-level frame.

 
```
function shouldProxyRequest(requestInfo) {
  return requestInfo.parentFrameId !== -1;
}

function handleProxyRequest(requestInfo) {
  if (shouldProxyRequest(requestInfo)) {
    console.log(`Proxying: ${requestInfo.url}`);
    return {type: "http", host: "127.0.0.1", port: 65535};
  }
  return {type: "direct"};
}

browser.proxy.onRequest.addListener(handleProxyRequest, {urls: ["<all\_urls>"]});

```

### Example extensions


* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/onRequest>

proxy.onError
=============



Fired when there is an error evaluating the PAC file or the `onRequest` listener.

 The error can be triggered by throwing or returning an invalid value in the proxy.onRequest event handler.



Syntax
------




```
browser.proxy.onError.addListener(listener)
browser.proxy.onError.removeListener(listener)
browser.proxy.onError.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `newState`  `Object`. An [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object representing the error.

    ### Example extensions


* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onError` | No | No | 6055–71 | ? | No | No | ? | ? | 6055 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/onError>

storage.onChanged
=================



Fired when [`storageArea.set`](storagearea/set), [`storageArea.remove`](storagearea/remove), or [`storageArea.clear`](storagearea/clear) executes against a storage area.

 When this event is triggered by [`storageArea.set`](storagearea/set), it's possible to receive a callback when there is no change to the underlying data. Also, the information returned includes all keys within the storage area [`storageArea.set`](storagearea/set) ran against. The extension can determine the changes that occurred by examining the content of the `changes` argument received by the `onChanged` listeners.



Syntax
------




```
browser.storage.onChanged.addListener(callback)
browser.storage.onChanged.removeListener(listener)
browser.storage.onChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  The function called when this event occurs. The function is passed these arguments:

  `changes`  `object`. Object describing the change. This object contains properties for all the keys in the storage area included in the [`storageArea.set`](storagearea/set) call, even if key values are unchanged. The name of each property is the name of each key. The value of each key is a [`storage.StorageChange`](storagechange) object describing the change to that item.

  `areaName`  `string`. The name of the storage area (`"sync"`, `"local"`, or `"managed"`) to which the changes were made.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



```
/\*
Log the storage area that changed,
then for each item changed,
log its old value and its new value.
\*/
function logStorageChange(changes, area) {
  console.log(`Change in storage area: ${area}`);

  const changedItems = Object.keys(changes);

  for (const item of changedItems) {
    console.log(`${item} has changed:`);
    console.log("Old value: ", changes[item].oldValue);
    console.log("New value: ", changes[item].newValue);
  }
}

browser.storage.onChanged.addListener(logStorageChange);

```
### Example extensions



* [proxy-blocker](https://github.com/mdn/webextensions-examples/tree/master/proxy-blocker)

  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#event-onChanged) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/onChanged>

webRequest.getSecurityInfo()
============================



Use this function to get detailed information about the [TLS](https://developer.mozilla.org/en-US/docs/Glossary/TLS) connection associated with a particular request.

 You pass this function the `requestId` for the request in question, and some optional extra parameters. It returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which will resolve to a [`SecurityInfo`](securityinfo) object.

 You can only call this function from inside the [`webRequest.onHeadersReceived`](onheadersreceived) listener. The `requestId` can be found in the `details` object which is passed into the listener.

 You must also pass the "blocking" option to `webRequest.onHeadersReceived.addListener()`. So to use this API you must have the "webRequestBlocking" [API permission](../../manifest.json/permissions#api_permissions), as well as the normal permissions needed for using `webRequest` listeners (the "webRequest" permission and the [host permission](../../manifest.json/permissions#host_permissions) for the host).



Syntax
------



```
let gettingInfo = browser.webRequest.getSecurityInfo(
  requestId,       // string
  options          // object
)

```
### Parameters


 `requestId`  `string`. ID of the request for which you want security info. You can get this from the `details` object that is passed into any `webRequest` event listeners.

  `options`  `object`. An object which may contain any of the following properties, all optional:

  
`certificateChain` Optional
  `boolean`. If `true`, the [`SecurityInfo`](securityinfo) object returned will include the entire certificate chain up to and including the trust root. If `false`, it will include only the server certificate. Defaults to `false`.

  
`rawDER` Optional
  `boolean`. If true, every [`CertificateInfo`](certificateinfo) in the [`SecurityInfo.certificates`](securityinfo) property will contain a property `rawDER`. This contains the DER-encoded ASN.1 that comprises the certificate data.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which resolves to a [`SecurityInfo`](securityinfo) object.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getSecurityInfo` | NoSee [bug 628819](https://crbug.com/628819). | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |


Examples
--------



This example listens for all HTTPS requests to "mozilla.org" or its subdomains, and logs the subject name in the server certificate:

 
```
async function logSubject(details) {
  try {
    let securityInfo = await browser.webRequest.getSecurityInfo(details.requestId, {});
    console.log(details.url);
    if (securityInfo.state === "secure" || securityInfo.state === "weak") {
      console.log(securityInfo.certificates[0].subject);
    }
  }
  catch (error) {
    console.error(error);
  }
}

browser.webRequest.onHeadersReceived.addListener(logSubject,
  {urls: ["https://\*.mozilla.org/\*"]},
  ["blocking"]
);

```
 This example listens for all HTTPS requests to "mozilla.org" or its subdomains, and logs the name in the trusted root certificate:

 
```
async function logRoot(details) {
  try {
    let securityInfo = await browser.webRequest.getSecurityInfo(
      details.requestId,
      {"certificateChain": true}
    );
    console.log(details.url);
    if (securityInfo.state === "secure" || securityInfo.state === "weak") {
      console.log(securityInfo.certificates[securityInfo.certificates.length - 1].issuer);
    }
  }
  catch (error) {
    console.error(error);
  }
}

browser.webRequest.onHeadersReceived.addListener(logRoot,
  {urls: ["https://\*.mozilla.org/\*"]},
  ["blocking"]
);

```

### Example extensions


* [root-cert-stats](https://github.com/mdn/webextensions-examples/tree/master/root-cert-stats)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/getSecurityInfo>

runtime.onInstalled
===================



Fired when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.

 Note that `runtime.onInstalled` is not the same as [`management.onInstalled`](../management/oninstalled). The `runtime.onInstalled` event is fired only for your extension. The `browser.management.onInstalled` event is fired for any extensions.



Syntax
------




```
browser.runtime.onInstalled.addListener(listener)
browser.runtime.onInstalled.removeListener(listener)
browser.runtime.onInstalled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  The callback function called when this event occurs. The function will be passed the following arguments:

  `details`  An object with the following properties:

  
`id` Optional
  `string`. The ID of the imported shared module extension that updated. This is present only if the `reason` value is `shared_module_update`.

  
`previousVersion` Optional
  `string`. The previous version of the extension just updated. This is only present if the `reason` value is `update`.

  `reason`  An [`runtime.OnInstalledReason`](oninstalledreason) value, stating the reason that this event is being dispatched.

  `temporary`  `boolean`. True if the add-on was installed temporarily. For example, using the "about:debugging" page in Firefox or using [web-ext run](https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/). False otherwise.

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInstalled` | 22 | 14 | 52Before version 55, this event is not triggered for temporarily installed add-ons. | ? | 15 | 14 | ? | ? | 52Before version 55, this event is not triggered for temporarily installed add-ons. | ? | 15 | ? |


Examples
--------



When the extension is installed, log the install reason and open <https://example.com>:

 
```
function handleInstalled(details) {
  console.log(details.reason);
  browser.tabs.create({
    url: "https://example.com"
  });
}

browser.runtime.onInstalled.addListener(handleInstalled);

```

### Example extensions



* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onInstalled) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onInstalled>

windows.onCreated
=================


Fired when a window is created.


Syntax
------




```
browser.windows.onCreated.addListener(listener)
browser.windows.onCreated.removeListener(listener)
browser.windows.onCreated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `window`  A [`windows.Window`](window) object containing details of the window that was created.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15Fires a pair of events: one for private browsing, one for regular browsing. | ? |


Examples
--------



Log the IDs of new windows as they are created:

 
```
browser.windows.onCreated.addListener((window) => {
  console.log(`New window: ${window.id}`);
});

```

### Example extensions



* [private-browsing-theme](https://github.com/mdn/webextensions-examples/tree/master/private-browsing-theme)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#event-onCreated) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/onCreated>

runtime.reload()
================



Reloads the extension.

 If there are any pending updates for the extension, that it has deferred by listening to [`runtime.onUpdateAvailable`](onupdateavailable), then they will be applied on reload.



Syntax
------



```
browser.runtime.reload()

```
### Parameters


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `reload` | 25 | 15 | 51 | ? | 15 | 14 | ? | ? | 51 | ? | 15 | ? |


Examples
--------



Reload the extension when the user clicks a browser action's icon:

 
```
browser.browserAction.onClicked.addListener((tab) => {
  browser.runtime.reload();
});

```

### Example extensions



* [runtime-examples](https://github.com/mdn/webextensions-examples/tree/master/runtime-examples)

  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-reload) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/reload>

sessions.getTabValue()
======================



Retrieves a value previously stored by a call to [`sessions.setTabValue`](settabvalue).

 You can retrieve a value from a tab even over a close/restore cycle: meaning that if you set a value, then the user closes the tab, then restores the tab using the browser's "restore tab" feature (for example, by pressing Control+Shift+T), then you will be able to retrieve the value from the restored tab. Note, though, that a restored tab does not get the same ID as the original, so the ID you pass into `getTabValue()` will be different from the ID you passed into `setTabValue()`, even though they both refer to the same tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let retrieving = browser.sessions.getTabValue(
  tabId,    // integer
  key       // string
)

```
### Parameters


 `tabId`  `integer`. ID of the tab whose data you are trying to retrieve. Error is thrown if ID is invalid.

  `key`  `string`. Key identifying the particular value to retrieve. This needs to match the key previously given in [`sessions.setTabValue`](settabvalue).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved with the value if it exists, or `undefined` if it does not exist. If the call failed (for example, because the tab ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the value of "my-key" for all newly created tabs (this will include any tabs that have been restored):

 
```
function onGetResolved(r) {
  console.log(`success: ${r}`);
}

function onGetRejected(e) {
  console.log(`error: ${e}`);
}

browser.tabs.onCreated.addListener((tab) => {
  browser.sessions.getTabValue(tab.id, "my-key").then(onGetResolved, onGetRejected);
});

```

### Example extensions


* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/getTabValue>

sessions.setTabValue()
======================



Stores a key/value pair to associate with a given tab. You can subsequently retrieve this value using [`sessions.getTabValue`](gettabvalue).

 Note that this data will only be visible to the extension that set it, and not to any other extensions.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let storing = browser.sessions.setTabValue(
  tabId,    // integer
  key,      // string
  value     // string or object
)

```
### Parameters


 `tabId`  `integer`. ID of the tab with which you want to associate the data. Error is thrown if ID is invalid.

  `key`  `string`. Key that you can later use to retrieve this particular data value.

  `value`  `string` or `object`. If this is an object it is [stringified](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify), so object methods, for example, will be omitted. If a function is given here it will be stored as the value `null`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved with no arguments if the call succeeded. If the call failed (for example, because the tab ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Set a value on the active tab when the user selects a menu item. Note that you'll need the "menus" [permission](../../manifest.json/permissions) to run this example:

 
```
async function setOnActiveTab() {
  let tabArray = await browser.tabs.query({currentWindow: true, active: true});
  let tabId = tabArray[0].id;
  await browser.sessions.setTabValue(tabId, "my-key", "my-value");
}

browser.menus.create({
  id: "my-item",
  title: "my item",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(setOnActiveTab);

```

### Example extensions


* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/setTabValue>

webRequest.onCompleted
======================



Fired when a request has completed.

 This event is informational only.



Syntax
------




```
browser.webRequest.onCompleted.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onCompleted.removeListener(listener)
browser.webRequest.onCompleted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

    `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass just one value:

 * `"responseHeaders"`: include `responseHeaders` in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Indicates if this response was fetched from disk cache.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `ip`  `string`. The IP address of the server the request was sent to. It may be a literal IPv6 address.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  
`responseHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP response headers that were received along with this response.

  `statusCode`  `integer`. Standard HTTP status code returned by the server.

  `statusLine`  `string`. HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers.

  `tabId`  `integer`. The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCompleted` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


Examples
--------



```
let target = "https://developer.mozilla.org/\*";

/\*
e.g.
"https://developer.mozilla.org/en-US/"
200

or:

"https://developer.mozilla.org/en-US/xfgkdkjdfhs"
404
\*/
function logResponse(responseDetails) {
  console.log(responseDetails.url);
  console.log(responseDetails.statusCode);
}

browser.webRequest.onCompleted.addListener(
  logResponse,
  {urls: [target]}
);

```
### Example extensions



* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onCompleted) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onCompleted>

webRequest.onErrorOccurred
==========================



Fired when a request could not be processed due to an error: for example, a lack of Internet connectivity.

 The error is passed to the listener as the `error` property of the [`details`](#details) object.

 Note that this event is not fired for HTTP errors (4XX or 5XX responses): these will go through the normal stages of a request, calling any event listeners, and setting `details.statusCode` to report the error.

 This event is informational only.



Syntax
------




```
browser.webRequest.onErrorOccurred.addListener(
  listener,             // function
  filter                // object
)
browser.webRequest.onErrorOccurred.removeListener(listener)
browser.webRequest.onErrorOccurred.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

    `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `error`  `string`. The error description. This string is an internal error string, may vary from one browser to another, and is not guaranteed to stay the same between releases.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Indicates if this response was fetched from disk cache.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `ip`  `string`. The IP address of the server the request was sent to. It may be a literal IPv6 address.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  `tabId`  `integer`. The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with these properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

 **Note** If Firefox Tracking Protection blocks the request an empty object is returned and `error` returns one of these codes:

 * `NS_ERROR_MALWARE_URI` indicating a malware URI.
* `NS_ERROR_PHISHING_URI` indicating a phishing URI.
* `NS_ERROR_TRACKING_URI` indicating a tracking URI.
* `NS_ERROR_UNWANTED_URI` indicating an unwanted URI.
* `NS_ERROR_BLOCKED_URI` indicating a blocked URI.
* `NS_ERROR_HARMFUL_URI` indicating a harmful URI.
* `NS_ERROR_FINGERPRINTING` indicating a fingerprinting URI.
* `NS_ERROR_CRYPTOMINING_URI` indicating a cryptomining URI.
* `NS_ERROR_SOCIALTRACKING_URI` indicating a social tracking URI.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onErrorOccurred` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


Examples
--------



```
let target = "<all\_urls>";

/\*
e.g., with no network:
"https://developer.mozilla.org/en-US/"
NS\_ERROR\_NET\_ON\_RESOLVED in Firefox
net::ERR\_INTERNET\_DISCONNECTED in Chrome
\*/
function logError(responseDetails) {
  console.log(responseDetails.url);
  console.log(responseDetails.error);
}

browser.webRequest.onErrorOccurred.addListener(
  logError,
  {urls: [target]}
);

```
### Example extensions



* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onErrorOccurred) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onErrorOccurred>

browserAction.setBadgeBackgroundColor()
=======================================



Sets the background color for the badge. Tabs without a specific badge background color will inherit the global badge background color, which defaults to `[217, 0, 0, 255]` in Firefox.

 From Firefox 63, unless the badge text color is explicitly set using [`browserAction.setBadgeTextColor()`](setbadgetextcolor), then the badge text color will be automatically set to black or white so as to maximize contrast with the specified badge background color. For example, if you set the badge background color to white, the default badge text color will be set to black, and vice versa.

 Other browsers always use a white text color, so setting a dark background may be preferable to ensure the text is readable.



Syntax
------



```
browser.browserAction.setBadgeBackgroundColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  `color`  The color, specified as one of:

 * a string: any CSS [<color>](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) value, for example `"red"`, `"#FF0000"`, or `"rgb(255,0,0)"`. If the string is not a valid color, the returned promise will be rejected and the background color won't be altered.
* a `[`browserAction.ColorArray`](colorarray)` object.
* `null`. If a `tabId` is specified, it removes the tab-specific badge background color so that the tab inherits the global badge background color. Otherwise it reverts the global badge background color to the default value.

  
`tabId` Optional
  `integer`. Sets the badge background color only for the given tab. The color is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the badge background color only for the given tab.

     * If `windowId` and `tabId` are both supplied, the function fails and the color is not set.
* If `windowId` and `tabId` are both omitted, the global badge background color is set instead.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeBackgroundColor` | Yes | 14 | 4545–58Tab-specific badge background color is not cleared when a new page is loaded. | ? | Yes | 14The API exists, but has no effect. | ? | ? | 79 | ? | 15The API exists, but has no effect. | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |
| `null` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `string` | Yes | 79 | YesBefore Firefox 59, invalid color strings behaved as `null`. | ? | Yes | No | ? | ? | 79 | ? | No | ? |


The default color in Firefox is: `[217, 0, 0, 255]`.


Examples
--------



A background color that starts off as red, and turns green when the browser action is clicked:

 
```
browser.browserAction.setBadgeText({ text: "1234" });
browser.browserAction.setBadgeBackgroundColor({ color: "red" });

browser.browserAction.onClicked.addListener(() => {
  browser.browserAction.setBadgeBackgroundColor({ color: "green" });
});

```
 Set the badge background color only for the active tab:

 
```
browser.browserAction.setBadgeText({ text: "1234" });
browser.browserAction.setBadgeBackgroundColor({ color: "red" });

browser.browserAction.onClicked.addListener((tab) => {
  browser.browserAction.setBadgeBackgroundColor({
    color: "green",
    tabId: tab.id,
  });
});

```

### Example extensions



* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)

  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setBadgeBackgroundColor>

browserAction.setBadgeText()
============================



Sets the badge text for the browser action. The badge is displayed on top of the icon.

 Tabs without an specific badge text will inherit the global badge text, which is `""` by default.



Syntax
------




```
browser.browserAction.setBadgeText(
  details // object
)

```
 This API is also available as `chrome.browserAction.setBadgeText()`.


### Parameters



 `details`  An object with the following properties:

  `text`  `string` or `null`. Any number of characters can be passed, but only about four can fit in the space.

 Use an empty string - `""` - if you don't want any badge.

 If a `tabId` is specified, `null` removes the tab-specific badge text so that the tab inherits the global badge text. Otherwise it reverts the global badge text to `""`.

 If a `windowId` is specified, `null` removes the window-specific badge text so that the tab inherits the global badge text. Otherwise it reverts the global badge text to `""`.

  
`tabId` Optional
  `integer`. Set the badge text only for the given tab. The text is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Set the badge text for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge is set.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeText` | Yes | 14 | 4545–58Tab-specific badge text is not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `null` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Add a badge indicating how many times the user clicked the button:

 
```
let clicks = 0;

function increment() {
  browser.browserAction.setBadgeText({ text: (++clicks).toString() });
}

browser.browserAction.onClicked.addListener(increment);

```

### Example extensions



* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)

  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setBadgeText) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setBadgeText>

tabs.onCreated
==============



Fired when a tab is created.

 Note that the tab's URL may not be given its final value at the time this event fired. In particular, Firefox opens a new tab with the URL "about:blank" before loading the new page into it. You can listen to [`tabs.onUpdated`](onupdated) events to be notified when a URL is set.



Syntax
------




```
browser.tabs.onCreated.addListener(callback)
browser.tabs.onCreated.removeListener(listener)
browser.tabs.onCreated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tab`  [`tabs.Tab`](tab). Details of the tab that was created.

    Examples
--------



Log the IDs of newly created tabs:

 
```
function handleCreated(tab) {
  console.log(tab.id);
}

browser.tabs.onCreated.addListener(handleCreated);

```

### Example extensions


* [session-state](https://github.com/mdn/webextensions-examples/tree/master/session-state)
* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreated` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onCreated) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onCreated>

webRequest.onAuthRequired
=========================



Fired when the server sends a `401` or `407` status code (that is, when the server is asking the client to provide authentication credentials, such as a username and password).

 The listener can respond in one of four different ways:

  Take no action  The listener can do nothing, just observing the request. If this happens, it will have no effect on the handling of the request, and the browser will probably just ask the user to log in.

  Cancel the request  The listener can cancel the request. If they do this, then authentication will fail, and the user will not be asked to log in. Extensions can cancel requests as follows:

 * in addListener, pass `"blocking"` in the `extraInfoSpec` parameter
* in the listener itself, return an object with a `cancel` property set to `true`

  Provide credentials synchronously  If credentials are available synchronously, the extension can supply them synchronously. If the extension does this, then the browser will attempt to log in with the given credentials. The listener can provide credentials synchronously as follows:

 * in addListener, pass `"blocking"` in the `extraInfoSpec` parameter
* in the listener, return an object with an `authCredentials` property set to the credentials to supply

  Provide credentials asynchronously  The extension might need to fetch credentials asynchronously. For example, the extension might need to fetch credentials from storage, or ask the user. In this case, the listener can supply credentials asynchronously as follows:

 * in addListener, pass `"blocking"` in the `extraInfoSpec` parameter
* in the listener, return a `Promise` that is resolved with an object containing an `authCredentials` property, set to the credentials to supply

   See [Examples](#examples).

 If you use `"blocking"` you must have the ["webRequestBlocking" API permission](../../manifest.json/permissions#api_permissions) in your `manifest.json`.

 If your extension provides bad credentials, then the listener will be called again. For this reason, take care not to enter an infinite loop by repeatedly providing bad credentials.



Proxy authorization
-------------------



In general, Firefox does not fire `webRequest` events for system requests, such as browser or extension upgrades, or search engine queries. To enable proxy authorization to work smoothly for system requests, from version 57 Firefox implements an exception to this.

 If an extension has the `"webRequest"`, `"webRequestBlocking"`, `"proxy"`, and `"<all_urls>"` permissions, then it will be able to use `onAuthRequired` to supply credentials for proxy authorization (but not for normal web authorization). The listener will not be able to cancel system requests or make any other modifications to any system requests.


Syntax
------




```
browser.webRequest.onAuthRequired.addListener(
  listener,                    // function
  filter,                      // object
  extraInfoSpec                // optional array of strings
)
browser.webRequest.onAuthRequired.removeListener(listener)
browser.webRequest.onAuthRequired.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

   Returns: [`webRequest.BlockingResponse`](blockingresponse) or a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 * To handle the request synchronously, include `"blocking"` in the `extraInfoSpec` parameter and return a `BlockingResponse` object, with its `cancel` or its `authCredentials` properties set.
* To handle the request asynchronously, include `"blocking"` in the `extraInfoSpec` parameter and return a `Promise` that is resolved with a `BlockingResponse` object, with its `cancel` or its `authCredentials` properties set.

  `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass any of the following values:

 * `"blocking"`: make the request block, so you can cancel the request or supply authentication credentials
* `"responseHeaders"`: include `responseHeaders` in the `details` object passed to the listener

  Additional objects
------------------


### details


 `challenger`  `object`. The server requesting authentication. This is an object with the following properties:

  `host`  `string`. The server's [hostname](https://en.wikipedia.org/wiki/Hostname#Internet_hostnames).

  `port`  `integer`. The server's port number.

    `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `frameId`  `integer`. This is `0` if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `isProxy`  `boolean`. `true` for `Proxy-Authenticate`, `false` for `WWW-Authenticate`.

  **Note:** `webRequest.onAuthRequired` is only called for HTTP and HTTPS/SSL proxy servers requiring authentication, and not for SOCKS proxy servers requiring authentication.

   `method`  `string`. Standard HTTP method (For example, `"GET"` or `"POST"`).

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to `-1` if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * `"http"`: HTTP proxy (or SSL CONNECT for HTTPS)
* `"https"`: HTTP proxying over TLS connection to proxy
* `"socks"`: SOCKS v5 proxy
* `"socks4"`: SOCKS v4 proxy
* `"direct"`: no proxy
* `"unknown"`: unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the connection fails to connect the proxy server after this number of seconds, the next proxy server in the array returned from [FindProxyForURL()](../proxy#findproxyforurl()_return_value) will be used.

    
`realm` Optional
  `string`. The authentication [realm](https://datatracker.ietf.org/doc/html/rfc1945#section-11) provided by the server, if there is one.

  `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  
`responseHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP response headers that were received along with this response.

  `scheme`  `string`. The authentication scheme: `"basic"` or `"digest`".

  `statusCode`  `integer`. Standard HTTP status code returned by the server.

  `statusLine`  `string`. HTTP status line of the response or the `'HTTP/0.9 200 OK'` string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers.

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to `-1` if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, `"image"`, `"script"`, `"stylesheet"`.

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onAuthRequired` | Yes | 14 | 54To handle a request asynchronously, return a Promise from the listener. | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 54To handle a request asynchronously, return a Promise from the listener. | ? | No | ? |
| `asyncBlocking` | Yes | 14 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This code just observes authentication requests for the target URL:

 
```
const target = "https://intranet.company.com/";

function observe(requestDetails) {
  console.log(`observing: ${requestDetails.requestId}`);
}

browser.webRequest.onAuthRequired.addListener(
  observe,
  {urls: [target]}
);

```
 This code cancels authentication requests for the target URL:

 
```
const target = "https://intranet.company.com/";

function cancel(requestDetails) {
  console.log(`canceling: ${requestDetails.requestId}`);
  return {cancel: true};
}

browser.webRequest.onAuthRequired.addListener(
  cancel,
  {urls: [target]},
  ["blocking"]
);

```
 This code supplies credentials synchronously. It has to keep track of outstanding requests, to ensure that it doesn't repeatedly try to submit bad credentials:

 
```
const target = "https://intranet.company.com/";

const myCredentials = {
  username: "me@company.com",
  password: "zDR$ERHGDFy"
}

const pendingRequests = [];

// A request has completed.
// We can stop worrying about it.
function completed(requestDetails) {
  console.log(`completed: ${requestDetails.requestId}`);
  let index = pendingRequests.indexOf(requestDetails.requestId);
  if (index > -1) {
    pendingRequests.splice(index, 1);
  }
}

function provideCredentialsSync(requestDetails) {
  // If we have seen this request before, then
  // assume our credentials were bad, and give up.
  if (pendingRequests.includes(requestDetails.requestId)) {
    console.log(`bad credentials for: ${requestDetails.requestId}`);
    return {cancel:true};
  }
  pendingRequests.push(requestDetails.requestId);
  console.log(`providing credentials for: ${requestDetails.requestId}`);
  return {authCredentials: myCredentials};
}

browser.webRequest.onAuthRequired.addListener(
    provideCredentialsSync,
    {urls: [target]},
    ["blocking"]
  );

browser.webRequest.onCompleted.addListener(
  completed,
  {urls: [target]}
);

browser.webRequest.onErrorOccurred.addListener(
  completed,
  {urls: [target]}
);

```
 This code supplies credentials asynchronously, fetching them from storage. It also has to keep track of outstanding requests, to ensure that it doesn't repeatedly try to submit bad credentials:

 
```
const target = "https://httpbin.org/basic-auth/\*";

const pendingRequests = [];

/\*
\* A request has completed. We can stop worrying about it.
\*/
function completed(requestDetails) {
  console.log(`completed: ${requestDetails.requestId}`);
  let index = pendingRequests.indexOf(requestDetails.requestId);
  if (index > -1) {
    pendingRequests.splice(index, 1);
  }
}

function provideCredentialsAsync(requestDetails) {
  // If we have seen this request before,
  // then assume our credentials were bad,
  // and give up.
  if (pendingRequests.includes(requestDetails.requestId)) {
    console.log(`bad credentials for: ${requestDetails.requestId}`);
    return {cancel: true};

  } else {
    pendingRequests.push(requestDetails.requestId);
    console.log(`providing credentials for: ${requestDetails.requestId}`);
    // we can return a promise that will be resolved
    // with the stored credentials
    return browser.storage.local.get(null);
  }
}

browser.webRequest.onAuthRequired.addListener(
    provideCredentialsAsync,
    {urls: [target]},
    ["blocking"]
  );

browser.webRequest.onCompleted.addListener(
  completed,
  {urls: [target]}
);

browser.webRequest.onErrorOccurred.addListener(
  completed,
  {urls: [target]}
);

```

### Example extensions



* [stored-credentials](https://github.com/mdn/webextensions-examples/tree/master/stored-credentials)

  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onAuthRequired) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onAuthRequired>

tabs.onMoved
============



Fired when a tab is moved within a window.

 Only one move event is fired, representing the tab the user directly moved. Move events are not fired for the other tabs that must move in response. This event is not fired when a tab is moved between windows. For that, see [`tabs.onDetached`](ondetached).



Syntax
------




```
browser.tabs.onMoved.addListener(listener)
browser.tabs.onMoved.removeListener(listener)
browser.tabs.onMoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. ID of the tab the user moved.

  `moveInfo`  `object`. Information about the move. See the [moveInfo](#moveinfo_2) section for more details.

    Additional objects
------------------


### moveInfo


 `windowId`  `integer`. ID of this tab's window.

  `fromIndex`  `integer`. Initial index of this tab in the window.

  `toIndex`  `integer`. Final index of this tab in the window.

  Examples
--------



Listen for and log move events:

 
```
function handleMoved(tabId, moveInfo) {
  console.log(`Tab ${tabId} moved from ${moveInfo.fromIndex} to ${moveInfo.toIndex}`);
}

browser.tabs.onMoved.addListener(handleMoved);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onMoved` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onMoved) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onMoved>

tabs.onRemoved
==============


Fired when a tab is closed.


Syntax
------




```
browser.tabs.onRemoved.addListener(callback)
browser.tabs.onRemoved.removeListener(listener)
browser.tabs.onRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. ID of the tab that closed.

  `removeInfo`  `object`. The tab's window ID, and a boolean indicating whether the window is also being closed. See the [removeInfo](#removeinfo_2) section for more details.

    Additional objects
------------------


### removeInfo


 `windowId`  `integer`. The window whose tab is closed.

  `isWindowClosing`  `boolean`. `true` if the tab is being closed because its window is being closed.

  Examples
--------



Listen for close events, and log the info:

 
```
function handleRemoved(tabId, removeInfo) {
  console.log(`Tab: ${tabId} is closing`);
  console.log(`Window ID: ${removeInfo.windowId}`);
  console.log(`Window is closing: ${removeInfo.isWindowClosing}`);
}

browser.tabs.onRemoved.addListener(handleRemoved);

```

### Example extensions


* [tabs-tabs-tabs](https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs)
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRemoved` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onRemoved) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onRemoved>

theme.getCurrent()
==================



Gets the currently used theme as a [`Theme`](theme) object. The arguments available in the color object are listed in the [properties of the color](../../manifest.json/theme#colors).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.theme.getCurrent(
  windowId    // integer
)

```
### Parameters


 
`windowId` Optional
  `integer`. The ID of a window. If this is provided, the theme applied on that window will be provided. If it is omitted the theme applied on the last focused window will be provided.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). The promise will be fulfilled with a [`theme.Theme`](theme) object representing the theme applied to the given window. If no extension-supplied theme has been applied to the given window, it will be fulfilled with an empty object.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getCurrent` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Gets the properties `frame` and `toolbar` colors of the current theme

 
```
function getStyle(themeInfo) {
  if (themeInfo.colors) {
    console.log(`accent color: ${themeInfo.colors.frame}`);
    console.log(`toolbar: ${themeInfo.colors.toolbar}`);
  }
}

async function getCurrentThemeInfo() {
  const themeInfo = await browser.theme.getCurrent();
  getStyle(themeInfo);
}

getCurrentThemeInfo();

```

### Example extensions


* [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme/getCurrent>

userScripts.register()
======================



This method enables user scripts to be registered from an extension's pages (such as the background page).

 This method is very similar to the [`contentScripts.register()`](../contentscripts/register) API method (for example, they both return a promise that resolves to an API object with an [`unregister()`](registereduserscript/unregister) method for unregistering the script). There are, however, differences in the options supported.

 This is an asynchronous method that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
const registeredUserScript = await browser.userScripts.register(
  userScriptOptions       // object
);
// …
await registeredUserScript.unregister();

```
### Parameters



 `userScriptOptions`  `object`. Represents the user scripts to register. It has similar syntax to [`contentScripts.register()`](../contentscripts/register).

 The `UserScriptOptions` object has the following properties:

  
`scriptMetadata` Optional
  A `JSON` object containing arbitrary metadata properties associated with the registered user scripts. However, while arbitrary, the object must be serializable, so it is compatible with [the structured clone algorithm.](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) This metadata is used to pass details from the script to the [`API script`](../../manifest.json/user_scripts). For example, providing details of a subset of the APIs that need to be injected by the [`API script`](../../manifest.json/user_scripts). The API does not use this metadata,

  
`allFrames` Optional
  Same as `all_frames` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`cookieStoreId` Optional
  An array of cookie store ID strings or a string containing a cookie store ID. Registers the user script in the tabs that belong to the cookie store IDs. This enables scripts to be registered for all default or non-contextual identity tabs, private browsing tabs (if the [extension is enabled in private browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing)), the tabs of a [contextual identity](../../work_with_contextual_identities), or a combination of these.

  
`excludeGlobs` Optional
  Same as `exclude_globs` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`excludeMatches` Optional
  Same as `exclude_matches` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  
`includeGlobs` Optional
  Same as `include_globs` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  `js`  An array of objects. Each object has either a property named `file`, which is a URL starting at the extension's manifest.json and pointing to a JavaScript file to register, or a property named `code`, which contains JavaScript code to register.

  
`matchAboutBlank` Optional
  Same as `match_about_blank` in the [`content_scripts`](../../manifest.json/content_scripts) key.

  `matches`   Same as `matches` in the [`content_scripts`](../../manifest.json/content_scripts) key. The URL patterns provided in `matches` must be enabled by the host permissions defined in the manifest [`permission`](../../manifest.json/permissions) property or enabled by the user from the [`optional_permissions`](../../manifest.json/optional_permissions) list. For example, if matches includes `https://mozilla.org/a` a script is only registered if host permissions include, for example, `https://mozilla.org/*`. If the URL pattern isn't enabled, the call to register fails with the error "Permission denied to register a user script for ORIGIN". 

  
`runAt` Optional
  Same as `run_at` in the [`content_scripts`](../../manifest.json/content_scripts) key.

     Unlike content script options, the userScriptOptions object does not have a CSS property. Use [`contentScripts.register()`](../contentscripts/register) to dynamically register and unregister stylesheets.


### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with a [`RegisteredUserScript`](registereduserscript) object that is use to unregister the user scripts.

  **Note:** User scripts are unregistered when the related extension page (from which the user scripts were registered) is unloaded, so you should register user scripts from an extension page that persists at least as long as you want the user scripts to stay registered.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `register` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |


See also
--------


* [`contentScripts.register()`](../contentscripts/register)
* [`RegisteredUserScript.unregister()`](registereduserscript/unregister)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/register>

windows.update()
================



Updates the properties of a window. Use this to move, resize, and (un)focus a window, etc.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let updating = browser.windows.update(
  windowId,              // integer
  updateInfo             // object
)

```
### Parameters


 `windowId`  `integer`. ID of the window to update.

  `updateInfo`  `object`. Object containing the properties to update.

  
`drawAttention` Optional
  `boolean`. If `true`, causes the window to be displayed in a manner that draws the user's attention to the window, without changing the focused window. The effect lasts until the user changes focus to the window. This option has no effect if the window already has focus. Set to `false` to cancel a previous `drawAttention` request.

  
`focused` Optional
  `boolean`. If `true`, brings the window to the front. If false, brings the next window in the z-order to the front.

  
`height` Optional
  `integer`. The height to resize the window to in pixels. This value is ignored for panels.

  
`left` Optional
  `integer`. The offset from the left edge of the screen to move the window to in pixels. This value is ignored for panels.

  
`state` Optional
  [`windows.WindowState`](windowstate). The new state of the window. The `minimized`, `maximized` and `fullscreen` states cannot be combined with `left`, `top`, `width` or `height`.

  
`titlePreface` Optional
  `string`. Use this to add a string to the beginning of the browser window's title. Depending on the underlying operating system, this might not work on browser windows that don't have a title (such as about:blank in Firefox).

  
`top` Optional
  `integer`. The offset from the top edge of the screen to move the window to in pixels. This value is ignored for panels.

  
`width` Optional
  `integer`. The width to resize the window to in pixels. This value is ignored for panels.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](window) object containing the details of the updated window. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `drawAttention` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `focused` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15`update()` will not switch between side-by-side Safari on iPadOS. | ? |
| `height` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `left` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `state` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `titlePreface` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `top` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `width` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


Examples
--------



When the user clicks a browser action's icon, move the window to the top left corner:

 
```
function onUpdated(windowInfo) {
  console.log(`Updated window: ${windowInfo.id}`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {

  let updating = browser.windows.update(tab.windowId, {
    left: 0,
    top: 0
  });
  updating.then(onUpdated, onError);

});

```

### Example extensions



* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-update) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/update>

theme.onUpdated
===============



Fires when a theme supplied as a browser extension is applied or removed. Specifically:

 * when a [static theme](https://extensionworkshop.com/documentation/themes/static-themes/) is installed
* when a [dynamic theme](../theme) calls [`theme.update()`](update) or [`theme.reset()`](reset)
* when a theme gets uninstalled.

 Note that this event is not fired for changes to the built-in themes.



Syntax
------




```
browser.theme.onUpdated.addListener(listener)
browser.theme.onUpdated.removeListener(listener)
browser.theme.onUpdated.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `updateInfo`  `object`. An object containing two properties:

  `theme`  `object`. If the event fired because an extension-supplied theme was removed, this will be an empty object. If it fired because an extension-supplied theme was applied, then it will be a [`theme.Theme`](theme) object representing the theme that was applied.

  
`windowId` Optional
  `integer`. The ID of the window for which theme has been updated. If this property is not present, it means that the theme was updated globally.

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onUpdated` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



```
function handleUpdated(updateInfo) {
  if (updateInfo.theme.colors) {
    console.log(`Theme was applied: ${updateInfo.theme}`);
  } else {
    console.log(`Theme was removed`);
  }
}

browser.theme.onUpdated.addListener(handleUpdated);

```
### Example extensions


* [theme-integrated-sidebar](https://github.com/mdn/webextensions-examples/tree/master/theme-integrated-sidebar)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme/onUpdated>

management.getAll()
===================



Retrieves an array of [`ExtensionInfo`](extensioninfo) objects, one for each installed add-on.

 Note that Google Chrome retrieves apps as well as add-ons. In Chrome you can distinguish apps from add-ons using the `type` property of [`ExtensionInfo`](extensioninfo).

 This API requires the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingAll = browser.management.getAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`ExtensionInfo`](extensioninfo) objects, one for each installed add-on.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 79 | 55Before version 56, only extensions whose 'type' is 'theme' are returned. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose 'type' is 'theme' are returned. | ? | No | ? |


Examples
--------



Log the name of all installed add-ons:

 
```
function gotAll(infoArray) {
  for (const info of infoArray) {
    if (info.type === "extension") {
      console.log(info.name);
    }
  }
}

let gettingAll = browser.management.getAll();
gettingAll.then(gotAll);

```

### Example extensions



* [theme-switcher](https://github.com/mdn/webextensions-examples/tree/master/theme-switcher)

  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-getAll) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/getAll>

management.setEnabled()
=======================



Enables or disables the given add-on.

 This function must usually be called in the context of a user action, such as the click handler for a button. The browser may also ask the user to confirm the change.

 This API requires the "management" [API permission](../../manifest.json/permissions).

 It is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 The function allows enabling/disabling of theme addons, but will return an error if used to enable or disable other types of web extension.



Syntax
------



```
let settingEnabled = browser.management.setEnabled(
  id,              // string
  enabled         // boolean
)

```
### Parameters


 `id`  `string`. ID of the add-on to enable/disable.

  `enabled`  `boolean`. Whether to enable or disable the add-on.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the add-on has been disabled or enabled.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setEnabled` | Yes | 79 | 55Only extensions whose 'type' is 'theme' can be enabled and disabled. | ? | Yes | No | ? | ? | 55Only extensions whose 'type' is 'theme' can be enabled and disabled. | ? | No | ? |


Examples
--------



Toggle enable/disable for the add-on whose ID is "my-add-on":

 
```
let id = "my-add-on";

function toggleEnabled(id) {
  let getting = browser.management.get(id);
  getting.then((info) => {
    browser.management.setEnabled(id, !info.enabled);
  });
}

toggleEnabled(id);

```

### Example extensions



* [theme-switcher](https://github.com/mdn/webextensions-examples/tree/master/theme-switcher)

  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-setEnabled) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/setEnabled>

topSites.get()
==============



Gets an array containing information about pages that the user has visited often and recently.

 Browsers keep a list of pages that the user visits often and recently. They use this list to help the user get back to these places easily. For example, Firefox by default provides a list of the most-visited pages in the "New Tab" page.

 To determine which pages appear in the list, and the order in which they appear, the browser combines "frequency" - how often the user has visited the page - and "recency" - how recently the user visited the page.

 The browser may then apply further filtering to this list before presenting it to the user. For example, in Firefox the "New Tab" page only lists one page per domain, and the user is able to block pages from appearing in the list.

 The `topSites.get()` API enables an extension to get access to this list. Called without any options, it will provide the filtered list of pages - that is, the one that appears in the "New Tab" page. However, by providing various options it's possible for an extension to get the unfiltered list of pages.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 To use the topSites API you must have the "topSites" [API permission](../../manifest.json/permissions#api_permissions).



Syntax
------



```
let gettingTopSites = browser.topSites.get(
    options  // object
)

```
### Parameters


 `options`  `object`. Options to modify the list of pages returned. This may include any of the following properties:

  
`includeBlocked` Optional
  `Boolean`. Include pages that the user has removed from the "New Tab" page. Defaults to `false`.

  
`includeFavicon` Optional
  `Boolean`. Include favicons in the results, for pages where they are available. Defaults to `false`.

  
`includePinned` Optional
   `Boolean`. Includes sites that the user has pinned to the Firefox new tab. Defaults to `false`. 

  
`includeSearchShortcuts` Optional
   `Boolean`. Includes search shortcuts that appear on the Firefox new tab. Defaults to `false`. 

  
`limit` Optional
  `Integer`. The number of pages to return. This must be a number between 1 and 100, inclusive. Defaults to 12.

  
`newtab` Optional
  `Boolean`. If included, the method returns the list of pages returned when the user opens a new tab. If included, and set to `true`, the method ignores all other parameters except `limit` and `includeFavicon`. Defaults to `false`.

  
`onePerDomain` Optional
  `Boolean`. Only include one page per domain. Defaults to `true`.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). This will be fulfilled with an array of [`MostVisitedURL`](mostvisitedurl) objects, one for each page listed in the browser's "New Tab" page. If an error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 79 | 52Since Firefox 78, a user may disable the browser's "Top Sites" feature by toggling the "browser.newtabpage.activity-stream.feeds.system.topsites" preference. In this case, `topSites.get()` will always return a list of the most-visited sites, regardless of the value of the `newtab` parameter. | ? | Yes | No | ? | ? | 52–79 | ? | No | ? |
| `options` | No | No | 63 | ? | No | No | ? | ? | 63–79 | ? | No | ? |


Examples
--------



This code logs the title and URL for all pages in the "New Tab" page:

 
```
function logTopSites(topSitesArray) {
  for (const topSite of topSitesArray) {
    console.log(`Title: ${topSite.title}, URL: ${topSite.url}`);
  }
}

function onError(error) {
  console.error(error);
}

browser.topSites.get().then(logTopSites, onError);

```
 This code logs the title and URL for all top pages, including ones the user has blocked, and potentially including multiple pages in the same domain:

 
```
function logTopSites(topSitesArray) {
  for (const topSite of topSitesArray) {
    console.log(`Title: ${topSite.title}, URL: ${topSite.url}`);
  }
}

function onError(error) {
  console.error(error);
}

browser.topSites
  .get({
    includeBlocked: true,
    onePerDomain: false,
  })
  .then(logTopSites, onError);

```

### Example extensions



* [top-sites](https://github.com/mdn/webextensions-examples/tree/master/top-sites)

  **Note:** This API is based on Chromium's [`chrome.topSites`](https://developer.chrome.com/docs/extensions/reference/topSites/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/topSites/get>

windows.remove()
================



Closes a window and all the tabs inside it, given the window's ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.windows.remove(
  windowId        // integer
)

```
### Parameters


 `windowId`  `integer`. ID of the window to close.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the window has been closed. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


Examples
--------



When the user clicks a browser action's icon, close the window in which the icon was clicked:

 
```
function onRemoved() {
  console.log(`Removed window`);
}

function onError(error) {
  console.error(`Error:`, error);
}

browser.browserAction.onClicked.addListener((tab) => {

  let removing = browser.windows.remove(tab.windowId);
  removing.then(onRemoved, onError);

});

```
 Close the current, e.g. popup, window when the user clicks a button on the page:

 
```
// in a script loaded by the page in the window
document.querySelector('#close').addEventListener(async ({ button, }) => { try {
  if (button) return; // not a left click
  const windowId = (await browser.windows.getCurrent()).id;
  await browser.windows.remove(windowId);
  // this point will never be reached, since the window is gone
} catch (error) { console.error('Closing failed:', error); } });

```
 In Firefox, the same could be achieved with the `.allowScriptsToClose` window creation property and `window.close()`.


### Example extensions



* [window-manipulator](https://github.com/mdn/webextensions-examples/tree/master/window-manipulator)

  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-remove) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/remove>

Browser actions
===============



A browser action is a button you can add to the browser toolbar. Users can click the button to interact with your extension.

  ![Play button browser action in the browser toolbar: it looks like a play button](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_actions/browser-action.png) 

 There are two ways to specify a browser action: with a [popup](user_interface/popups), or without a popup.

 If you don't specify a popup, then when the user clicks the button an event is dispatched to the extension, which you can listen for using [`browserAction.onClicked`](api/browseraction/onclicked):

 
```
browser.browserAction.onClicked.addListener(handleClick);

```
 If you do specify a popup, the click event is not dispatched: instead, the popup will be shown when the user clicks the button. The user will be able to interact with the popup and it will close automatically when the user clicks outside it.

 Note that your extension can have only one browser action.



Specifying the browser action
-----------------------------



You define the browser action's properties - icon, title, popup - using the [`browser_action`](manifest.json/browser_action) key in manifest.json:

 
```
"browser\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?",
  "default\_popup": "popup/geo.html"
}

```
 The only mandatory key is `default_icon`. You can change any of these properties programmatically using the [`browserAction`](api/browseraction) API.


Examples
--------



The [webextensions-examples](https://github.com/mdn/webextensions-examples) repo on GitHub contains several examples of extensions that use browser actions:

 * [bookmark-it](https://github.com/mdn/webextensions-examples/tree/master/bookmark-it) uses a browser action without a popup
* [beastify](https://github.com/mdn/webextensions-examples/tree/master/beastify) uses a browser action with a popup




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_actions>

Legacy Version Formats
======================


This page describes legacy web extension version string formats. See the manifest [version key](../version) documentation for information on the current version string format.


Firefox legacy version number
-----------------------------



A **version string** consists of one or more *version parts*, separated by dots.

 Each **version part** is parsed as a sequence of four parts: `<number-a><string-b><number-c><string-d>`. Each of the parts is optional. Numbers are integers base 10 (may be negative), and strings are non-numeric ASCII characters.

 Here are a few examples of valid version parts:

 * `0` (as in `1.0`): `<number-a>=0`
* `5a` (as in `1.5a`): `<number-a>=5`, `<string-b>=a`
* `5pre4` (as in `3.5pre4`): `<number-a>=5`, `<string-b>=pre`, `<number-c>=4`
* `*` (as in `1.0.*`): `<string-b>=*`

 A few special parsing rules are applied for backward compatibility and readability:

 * if the version part is a single asterisk, it is interpreted as an infinitely-large number: `1.5.0.*` is the same as `1.5.0.(infinity)`
* if string-b is a plus sign, number-a is incremented to be compatible with the Firefox 1.0.x version format: `1.0+` is the same as `1.1pre`

 The rationale behind splitting a version part into a sequence of strings and numbers is that when comparing version parts, the numeric parts are compared as numbers, for example, '1.0pre1' < '1.0pre10', while the strings are compared byte-wise. See the next section for details on how versions are compared.

 From Firefox 108, web extensions using this version string trigger a warning on installation.


Comparing versions
------------------



When two version strings are compared, their version parts are compared left to right. An empty or missing version part is equivalent to `0`.

 If at some point, a version part of one version string is greater than the corresponding version part of another version string, then the first version string is greater than the other one.

 Otherwise, the version strings are equal. As missing version parts are treated as if they were `0`, these version strings are equal: `1`, `1.0`, `1.0.`, `1.0.0`, and even `1.0..`.


### Comparing version parts


Version parts are also compared left to right; parts A and C are compared as numbers, while parts B and D are compared byte-wise. A string part that exists is always less than a string part that doesn't exist (`1.6a` is less than `1.6`).

Examples
--------



```
1.-1
< 1 == 1. == 1.0 == 1.0.0
< 1.1a < 1.1aa < 1.1ab < 1.1b < 1.1c
< 1.1pre == 1.1pre0 == 1.0+
< 1.1pre1a < 1.1pre1aa < 1.1pre1b < 1.1pre1
< 1.1pre2
< 1.1pre10
< 1.1.-1
< 1.1 == 1.1.0 == 1.1.00
< 1.10
< 1.* < 1.*.1
< 2.0

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version/format>

sidebarAction.setPanel()
========================


Sets the sidebar's panel: that is, the HTML document that defines the content of this sidebar.


Types of panel
--------------



Sidebars always have a *"manifest panel"*, which is the panel defined in the [`sidebar_action`](../../manifest.json/sidebar_action) manifest key.

 If you set a new panel using `setPanel()`, and include the `tabId` option, then the panel is set only for the given tab. This panel is referred to as the *"tab-specific panel"*.

 If you set a new panel using `setPanel()`, and include the `windowId` option, then the panel is set only for the given window. This panel is referred to as the *"window-specific panel"*, and will appear in all tabs of that window that do not have a tab-specific panel set.

 If you set a new panel using `setPanel()`, and omit both the `tabId` and `windowId` options, then this sets the *"global panel"*. The global panel will then appear in all tabs that do not have a tab-specific panel set and whose window does not have a window-specific panel.


Syntax
------



```
browser.sidebarAction.setPanel(
  details // object
)

```
### Parameters



 `details`  `object`. An object with the following properties:

  `panel`  `string` or `null`. The panel to load into the sidebar, specified as a URL pointing to an HTML document, or `null`, or an empty string.

 This can point to a file packaged within the extension (for example, created using [`runtime.getURL`](../runtime/geturl)), or a remote document (e.g. `https://example.org/`). It must be a valid URL.

 If `panel` is `null` or `""`, then a previously set panel will be removed, so that:

 * If `tabId` is specified, and the tab has a tab-specific panel set, then the tab will inherit the panel from the window it belongs to.
* If `windowId` is specified, and the window has a window-specific panel set, then the window will inherit the global panel.
* Otherwise, the global panel will be reset to the manifest panel.

  
`tabId` Optional
  `integer`. Sets the panel only for the given tab.

  
`windowId` Optional
  `integer`. Sets the panel only for the given window.

     * If `windowId` and `tabId` are both specified, the function fails and the panel is not set.
* If `windowId` and `tabId` are both omitted, the global panel is set.


Examples
--------



This code toggles the sidebar document when the user clicks a browser action:

 
```
let thisPanel = browser.runtime.getURL("/this.html");
let thatPanel = browser.runtime.getURL("/that.html");

function toggle(panel) {
  if (panel === thisPanel) {
    browser.sidebarAction.setPanel({panel: thatPanel});
  } else {
    browser.sidebarAction.setPanel({panel: thisPanel});
  }
}

browser.browserAction.onClicked.addListener(() => {
  browser.sidebarAction.getPanel({}).then(toggle);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setPanel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `null` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/setPanel>

windows.CreateType
==================


Specifies the type of browser window to create.


Type
----



Values of this type are `strings`. Possible values are:

 * `"normal"`
* `"popup"`
* `"panel"`
* `"detached_panel"`


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CreateType` | Yes`detached_panel` is not supported. | 14`panel` and `detached_panel` are not supported. | 45 | ? | Yes`detached_panel` is not supported. | 14`panel` and `detached_panel` are not supported. | ? | ? | No | ? | 15`panel` and `detached_panel` are not supported. | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#type-CreateType) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/CreateType>

windows.Window
==============


Information about a browser window.


Type
----



Values of this type are `objects`. They contain the following properties:

  `alwaysOnTop`  `boolean`. Whether the window is set to be always on top.

  `focused`  `boolean`. Whether the window is currently the focused window.

  
`height` Optional
  `integer`. The height of the window, including the frame, in pixels.

  
`id` Optional
  `integer`. The ID of the window. Window IDs are unique within a browser session.

  `incognito`  `boolean`. Whether the window is incognito (private).

  
`left` Optional
  `integer`. The offset of the window from the left edge of the screen in pixels.

  
`sessionId` Optional
  `string`. The session ID used to uniquely identify a Window obtained from the [`sessions`](../sessions) API.

  
`state` Optional
  A [`windows.WindowState`](windowstate) value representing the state of this browser window — maximized, minimized, etc.

  
`tabs` Optional
  Array of [`tabs.Tab`](../tabs/tab) objects representing the current tabs in the window.

  
`title` Optional
  The title of the browser window. Requires "tabs" permission or [host permissions](../../manifest.json/permissions#host_permissions) for the active tab's URL. Read only.

  
`top` Optional
  `integer`. The offset of the window from the top edge of the screen in pixels.

  
`type` Optional
  A [`windows.WindowType`](windowtype) value representing the type of browser window this is — normal browser window, popup, etc.

  
`width` Optional
  `integer`. The width of the window, including the frame, in pixels.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Window` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `alwaysOnTop` | 19 | 79 | 45 | ? | 15 | 14Always returns `false`. | ? | ? | No | ? | 15Always returns `false`. | ? |
| `focused` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `height` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `id` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `incognito` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `left` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `sessionId` | 31 | 79 | No | ? | 18 | No | ? | ? | No | ? | No | ? |
| `state` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `tabs` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `title` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `top` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `type` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `width` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#type-Window) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/Window>

windows.get()
=============



Gets details about a window, given its ID. The details are passed into a callback.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.windows.get(
  windowId,              // integer
  getInfo                // optional object
)

```
### Parameters



 `windowId`  `integer`. The ID of the window object you want returned.

  
`getInfo` Optional
  `object`. Contains options to filter the type of window.

  
`populate` Optional
  `boolean`. If `true`, the [`windows.Window`](window) object will have a `tabs` property that contains a list of [`tabs.Tab`](../tabs/tab) objects representing the tabs open in the window. The `Tab` objects only contain the `url`, `title` and `favIconUrl` properties if the extension's manifest file includes the `"tabs"` permission or a matching [host permission](../../manifest.json/permissions#host_permissions).

  
`windowTypes` Optional
  `array` of [`windows.WindowType`](windowtype) objects. If set, the [`windows.Window`](window) returned will be filtered based on its type. If unset the default filter is set to `['normal', 'panel', 'popup']`, with `'panel'` window types limited to the extension's own windows.

      **Note:** If supplied, the `windowTypes` component of `getInfo` is ignored. The use of `windowTypes` has been deprecated as of Firefox 62.

 
### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](window) object containing the details of the window. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getInfo` | 18 | 14 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



This example gets the current window and logs the URLs of the tabs it contains. Note that you'll need the "tabs" [permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions) to access tab URLs.

  **Note:** This example is a bit unrealistic: in this situation you would more probably use [`windows.getCurrent()`](getcurrent).

  
```
function logTabs(windowInfo) {
  for (const tabInfo of windowInfo.tabs) {
    console.log(tabInfo.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.windows.get(tab.windowId, { populate: true }).then(logTabs, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-get) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/get>

runtime.getBackgroundPage()
===========================



Retrieves the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for the background page running inside the current extension. If the background page is non-persistent (an event page) and it is not running, the background page is started.

 This provides a convenient way for other privileged extension scripts to get direct access to the background script's scope. This enables them to access variables or call functions defined in that scope. "Privileged script" here includes scripts running in [options pages](../../anatomy_of_a_webextension#options_pages), or scripts running in [browser action](../../anatomy_of_a_webextension#browser_actions_2) or [page action](../../anatomy_of_a_webextension#page_actions) popups, but does *not* include [content scripts](../../anatomy_of_a_webextension#content_scripts).

 Note that variables that were declared using [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) or [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) do not appear in the `Window` object returned by this function.

 **Also note that this method cannot be used in a private window in Firefox**—it always returns `null`. For more info see [related bug at bugzilla](https://bugzil.la/1329304).

 If the background page is an event page, the system will ensure it is loaded before resolving the promise.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

  **Note:** In Firefox, this method cannot be used in Private Browsing mode — it always returns `null`. For more info see [Firefox bug 1329304](https://bugzil.la/1329304).

 In Chrome, this method is available only with persistent background pages, which are not available in Manifest V3, so consider using Manifest V2. See the [this](https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/) for details.

 Consider using [`runtime.sendMessage()`](sendmessage) or [`runtime.connect()`](connect), which work correctly in both scenarios above.

 

Syntax
------



```
let gettingPage = browser.runtime.getBackgroundPage()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object for the background page, if there is one. If the extension does not include a background page, the promise is rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBackgroundPage` | 22 | 14 | 45If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then it will always return `null`. | ? | 15 | 14 | ? | ? | 48If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then it will always return `null`. | ? | 15 | ? |


Examples
--------



Suppose a [background script](../../anatomy_of_a_webextension#background_scripts) defines a function `foo()`:

 
```
// background.js

function foo() {
  console.log("I'm defined in background.js");
}

```
 A script running in a [popup](../../anatomy_of_a_webextension#browser_actions_2) can call this function directly like this:

 
```
// popup.js

function onGot(page) {
  page.foo();
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let getting = browser.runtime.getBackgroundPage();
getting.then(onGot, onError);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-getBackgroundPage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBackgroundPage>

windows.WindowState
===================


The state of this browser window.


Type
----



Values of this type are `strings`. Possible values are:

  `"normal"`  The window is at the default size or user-selected size.

  `"minimized"`  The window is only visible as an icon in the taskbar or .

  `"maximized"`  The window fills the screen on which it is displayed not including any screen areas reserved by the operating system.

  `"fullscreen"`  The window is running as a full screen application or content in a tab is using the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)

  `"docked"`  A docked window occupies a fixed position relative to other windows owned by the same application.

   macOS compatibility: Beginning in macOS 10.10, the default maximizing behavior for windows changed to run applications as full screen applications instead of "zoomed" windows. `fullscreen` refers to both the browser running as a full screen application and when content in a tab uses the Fullscreen API.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `WindowState` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `docked` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `fullscreen` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `maximized` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `minimized` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#type-WindowState) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/WindowState>

Interact with the clipboard
===========================



Working with the clipboard in extensions is transitioning from the Web API [`document.execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) method (which is deprecated) to the [`navigator.clipboard`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) method.

  **Note:** The [`navigator.clipboard`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) API is a recent addition to the specification and may not be fully implemented in all browsers. This article describes some limitations, but be sure to review the compatibility tables for each method before using them to ensure that the API supports your needs.

  The difference between the two APIs is that [`document.execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) this is analogous to the keyboard copy, cut, and paste actions – exchanging data between a webpage and clipboard – whereas [`navigator.clipboard`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) writes and reads arbitrary data to and from the clipboard.

 [`navigator.clipboard`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) provide separate methods to read or write:

 * text content, using [`navigator.clipboard.readText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText) and [`navigator.clipboard.writeText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText).
* images, rich text, HTML, and other rich content, using [`navigator.clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) and [`navigator.clipboard.write()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write).

 However, while [`navigator.clipboard.readText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText) and [`navigator.clipboard.writeText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText) work on all browsers, [`navigator.clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) and [`navigator.clipboard.write()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write) do not. For example, on Firefox at the time of writing, [`navigator.clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) and [`navigator.clipboard.write()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write) are not fully implemented, such that to:

 * work with images use [`browser.clipboard.setImageData()`](api/clipboard/setimagedata) to write images to the clipboard and [`document.execCommand("paste")`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) to paste images to a webpage.
* write rich content (such as, HTML, rich text including images, etc.) to the clipboard, use [`document.execCommand("copy")`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) or [`document.execCommand("cut")`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). Then, either [`navigator.clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) (recommended) or [`document.execCommand("paste")`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) to read the content from the clipboard.



Writing to the clipboard
------------------------


This section describes the options for writing data to the clipboard.

### Using the Clipboard API



The Clipboard API writes arbitrary data to the clipboard from your extension. Using the API requires the permission `"clipboardRead"` or `"clipboardWrite"` in your `manifest.json` file. As the API is only available to [Secure Contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts), it cannot be used from a content script running on `http:`-pages, only `https:`-pages.

 For page scripts, the `"clipboard-write"` permission needs to be requested using the Web API [`navigator.permissions`](https://developer.mozilla.org/en-US/docs/Web/API/Permissions). You can check for that permission using [`navigator.permissions.query()`](https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query):

 
```
navigator.permissions.query({name: "clipboard-write"}).then((result) => {
  if (result.state === "granted" || result.state === "prompt") {
    /\* write to the clipboard now \*/
  }
});

```
  **Note:** The `clipboard-write` permission name is not supported in Firefox, only Chromium browsers.

  This function takes a string and writes it to the clipboard:

 
```
function updateClipboard(newClip) {
  navigator.clipboard.writeText(newClip).then(() => {
    /\* clipboard successfully set \*/
  }, () => {
    /\* clipboard write failed \*/
  });
}

```

### Using execCommand()



The `"cut"` and `"copy"` commands of the [`document.execCommand()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) method are used to replace the clipboard's content with the selected material. These commands can be used without any special permission in short-lived event handlers for a user action (for example, a click handler).

 For example, suppose you've got a popup that includes the following HTML:

 
```
<input id="input" type="text" /> <button id="copy">Copy</button>

```
 To make the `"copy"` button copy the contents of the [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) element, you can use code like this:

 
```
function copy() {
  let copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copy);

```
 Because the `execCommand()` call is inside a click event handler, you don't need any special permissions.

 However, let's say that instead you trigger the copy from an alarm:

 
```
function copy() {
  let copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

browser.alarms.create({
  delayInMinutes: 0.1
});

browser.alarms.onAlarm.addListener(copy);

```
 Depending on the browser, this may not work. On Firefox, it will not work, and you'll see a message like this in your console:

 `document.execCommand('cut'/'copy') was denied because it was not called from inside a short running user-generated event handler.`

 To enable this use case, you need to ask for the `"clipboardWrite"` [permission](manifest.json/permissions). So: `"clipboardWrite"` enables you to write to the clipboard outside a short-lived event handler for a user action.

  **Note:**[`document.execCommand()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) does not work on input fields of `type="hidden"`, with the HTML5 attribute `"hidden"`, or any matching CSS rule using `"display: none;"`. So, to add a "copy to clipboard" button to a `span`, `div`, or `p` tag, you need to use a workaround, such as setting the input's position to absolute and moving it out of the viewport.

 
### Browser-specific considerations



The clipboard and other APIs involved here are evolving rapidly, so there are variations among browsers in how they work.

 In Chrome:

 * You don't need `"clipboardWrite"`, even to write to the clipboard outside a user-generated event handler.

 In Firefox:

 * [`navigator.clipboard.write()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write) is not supported.

 See the [browser compatibility tables](#browser_compatibility) for more information.


Reading from the clipboard
--------------------------


This section describes the options for reading or pasting data from the clipboard.

### Using the Clipboard API



The Clipboard API's [`navigator.clipboard.readText()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText) and [`navigator.clipboard.read()`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) methods let you read arbitrary text or binary data from the clipboard in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts). This lets you access the data in the clipboard without pasting it into an editable element.

 Once you have the `"clipboard-read"` permission from the [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API), you can read from the clipboard easily. For example, this snippet of code fetches the text from the clipboard and replaces the contents of the element with the ID `"outbox"` with that text.

 
```
navigator.clipboard.readText().then((clipText) =>
  document.getElementById("outbox").innerText = clipText);

```

### Using execCommand()



To use [`document.execCommand("paste")`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) your extension needs the `"clipboardRead"` [permission](manifest.json/permissions). This is the case even if you're using the `"paste"` command from within a user-generated event handler, such as [`click`](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) or [`keypress`](https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event).

 Consider HTML that includes something like this:

 
```
<textarea id="output"></textarea> <button id="paste">Paste</button>

```
 To set the content of the [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) element with the ID `"output"` from the clipboard when the user clicks the `"paste"` [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button), you can use code like this:

 
```
function paste() {
  let pasteText = document.querySelector("#output");
  pasteText.focus();
  document.execCommand("paste");
  console.log(pasteText.textContent);
}

document.querySelector("#paste").addEventListener("click", paste);

```

### Browser-specific considerations


Firefox supports the `"clipboardRead"` [permission](manifest.json/permissions) from version 54 but only supports pasting into elements in [content editable mode](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable), which for content scripts only works with a [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea). For background scripts, any element can be set to content editable mode.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setImageData` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Interact_with_the_clipboard` | 66 | 79 | 63 | No | 53 | 13.1 | 66 | 66 | 63 | 47 | 13.4 | 9.0 |
| `read` | 86From version 86, the `text/html` MIME type is supported.76From version 76, the `image/png` MIME type is supported.66Images are not supported. | 79 | 90Firefox only supports reading the clipboard in browser extensions, using the `"clipboardRead"` extension permission. | No | 63 | 13.1 | 84From version 84, the `image/png` MIME type is supported.66Images are not supported. | 86From version 86, the `text/html` MIME type is supported.84From version 84, the `image/png` MIME type is supported.66Images are not supported. | No | 54 | 13.4 | 12.0 |
| `readText` | 66 | 79 | NoFirefox only supports reading the clipboard in browser extensions, using the `"clipboardRead"` extension permission. | No | 53 | 13.1 | 66 | 66 | NoFirefox only supports reading the clipboard in browser extensions, using the `"clipboardRead"` extension permission. | 47 | 13.4 | 9.0 |
| `write` | 66From version 76, the `image/png` MIME type is supported. | 79 | 87Writing to the clipboard is available without permission in secure contexts and browser extensions, but only from user-initiated event callbacks. Browser extensions with the `"clipboardWrite"` permission can write to the clipboard at any time.63["This method accepts a `DataTransfer` object instead of an array of `ClipboardItem` objects.", "Writing to the clipboard is available without permission in secure contexts and browser extensions, but only from user-initiated event callbacks. Browser extensions with the `\"clipboardWrite\"` permission can write to the clipboard at any time."] | No | 63 | 13.1 | 66From version 84, the `image/png` MIME type is supported. | 66From version 84, the `image/png` MIME type is supported. | No | 54 | 13.4 | 12.0 |
| `writeText` | 66 | 79 | 63Writing to the clipboard is available without permission in secure contexts and browser extensions, but only from user-initiated event callbacks. Browser extensions with the `"clipboardWrite"` permission can write to the clipboard at any time. | No | 53 | 13.1Must be called within user gesture event handlers such as `pointerdown` or `pointerup`. | 66 | 66 | 63Writing to the clipboard is available without permission in secure contexts and browser extensions, but only from user-initiated event callbacks. Browser extensions with the `"clipboardWrite"` permission can write to the clipboard at any time. | 47 | 13.4Must be called within user gesture event handlers such as `pointerdown` or `pointerup`. | 9.0 |

### api.Clipboard


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.api.clipboard


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


See also
--------


* [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)
* [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
* [Make content editable](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#contenteditable)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard>

tabs.toggleReaderMode()
=======================



Toggles Reader Mode for the given tab.

 This function toggles Reader Mode for the given tab. It takes a tab ID as a parameter: if this is omitted, the currently active tab is toggled.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 Reader Mode, also known as Reader View, is a browser feature that makes it easier for the user to focus on an article by:

 * hiding non-essential page elements like sidebars, footers, and ads
* changing the page's text size, contrast and layout for better readability.

 Reader Mode is useful specifically for articles: meaning, pages that have a body of text content as their main feature. Pages that don't have an identifiable article are not eligible for display in Reader Mode. To find out whether a page is an article, check the `isArticle` property of [`tabs.Tab`](tab).

 To find out whether a tab is already in Reader Mode, check the `isInReaderMode` property of [`tabs.Tab`](tab). To track tabs changing into or out of Reader Mode, you'll need to keep track of the current state of all tabs, and check when `isInReaderMode` changes:

 
```
function handleUpdated(tabId, changeInfo, tabInfo) {
  if (changeInfo.status === "complete") {
    console.log(`Tab ${tabId} reader mode: ${tabInfo.isInReaderMode}`);
  }
}

browser.tabs.onUpdated.addListener(handleUpdated);

```


Syntax
------



```
let toggling = browser.tabs.toggleReaderMode(
  tabId            // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to display in Reader Mode. Defaults to the selected tab of the current window.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the tab has been updated. If any error occurs (for example, because the page was not an article), the promise will be rejected with an error message.

Examples
--------



This code switches every new page into Reader Mode, if that page is eligible for it:

 
```
function switchToReaderMode(tabId, changeInfo, tabInfo) {
  if (changeInfo.isArticle) {
    browser.tabs.toggleReaderMode(tabId);
  }
}

browser.tabs.onUpdated.addListener(switchToReaderMode);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `toggleReaderMode` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/toggleReaderMode>

runtime.onSuspend
=================



Sent to the event page just before it is unloaded. This gives the extension an opportunity to do some cleanup. Note that since the page is unloading, any asynchronous operations started while handling this event are not guaranteed to complete.

  **Note:** If something prevents the event page from being unloaded, the [`runtime.onSuspendCanceled`](onsuspendcanceled) event will be sent and the page won't be unloaded.

 

Syntax
------




```
browser.runtime.onSuspend.addListener(listener)
browser.runtime.onSuspend.removeListener(listener)
browser.runtime.onSuspend.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onSuspend` | 22 | 79 | 100This event does not fire until Firefox 106, when event pages are available. | ? | 15 | No | ? | ? | 100This event does not fire until Firefox 106, when event pages are available. | ? | No | ? |


Examples
--------



Listen for suspend events:

 
```
function handleSuspend() {
  console.log("Suspending event page");
  // handle cleanup
}

browser.runtime.onSuspend.addListener(handleSuspend);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onSuspend) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onSuspend>

runtime.onSuspendCanceled
=========================


Sent after [`runtime.onSuspend`](onsuspend) to indicate that the app won't be unloaded after all.


Syntax
------




```
browser.runtime.onSuspendCanceled.addListener(listener)
browser.runtime.onSuspendCanceled.removeListener(listener)
browser.runtime.onSuspendCanceled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onSuspendCanceled` | 22 | 79 | 100This event does not fire until Firefox 106, when event pages are available. | ? | 15 | No | ? | ? | 100This event does not fire until Firefox 106, when event pages are available. | ? | No | ? |


Examples
--------



Listen for `SuspendCanceled` events:

 
```
function handleSuspendCanceled() {
  console.log("Suspend canceled");
}

browser.runtime.onSuspendCanceled.addListener(handleSuspendCanceled);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onSuspendCanceled) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onSuspendCanceled>

permissions.onAdded
===================


Fired when the extension granted new permissions.


Syntax
------




```
browser.permissions.onAdded.addListener(listener)
browser.permissions.onAdded.removeListener(listener)
browser.permissions.onAdded.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `permissions`  [`permissions.Permissions`](permissions) object containing the permissions that were granted.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onAdded` | Yes | 79 | 77 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------




```
function handleAdded(permissions) {
  console.log(`New API permissions: ${permissions.permissions}`);
  console.log(`New host permissions: ${permissions.origins}`);
}

browser.permissions.onAdded.addListener(handleAdded);

```
  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/onAdded>

tabs.hide()
===========



Hides one or more tabs.

 Hidden tabs are no longer visible in the browser's tabstrip. Hidden tabs are not automatically [discarded](discard): the code running in them continues to run. You can explicitly discard tabs whenever you hide them: although this is not appropriate in all situations, it will help to reduce the resources used by the browser.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

 Not all tabs are eligible for being hidden:

 * Tabs that are pinned cannot be hidden.
* Tabs that are sharing the screen, microphone or camera cannot be hidden.
* The current active tab cannot be hidden.
* Tabs that are in the process of being closed cannot be hidden.

 The first time an extension hides a tab, the browser will tell the user that the tab is being hidden, show them how they can access the hidden tab, and give them the option of disabling the extension instead.

 To use this API you must have the "tabHide" [permission](../../manifest.json/permissions).



Syntax
------



```
let hiding = browser.tabs.hide(
  tabIds          // integer or integer array
)

```
### Parameters


 `tabIds`  `integer` or `array` of `integer`. The IDs of the tab or tabs to hide.

 If any of these tabs are not eligible for being hidden, they will not be hidden, but the call will still succeed and eligible tabs will still be hidden. For example, if you pass `[1, 3]`, and `1` identifies the active tab, then only `3` will be hidden.

 However, if any of the tab IDs are invalid, the call will fail and no tabs will be hidden.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array containing the IDs of the tabs that were hidden. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Hide a single tab:

 
```
function onHidden() {
  console.log(`Hidden`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.tabs.hide(2).then(onHidden, onError);

```
 Hide multiple tabs:

 
```
function onHidden() {
  console.log(`Hidden`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.tabs.hide([15, 14, 1]).then(onHidden, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `hide` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/hide>

extension.isAllowedIncognitoAccess()
====================================



Check whether the extension is allowed access to tabs opened in "private browsing" mode.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let isAllowed = browser.extension.isAllowedIncognitoAccess()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean: `true` if the extension is allowed access to private tabs, `false` otherwise.

Examples
--------



```
function logIsAllowed(answer) {
  console.log(`Is allowed: ${answer}`);
}

let isAllowed = browser.extension.isAllowedIncognitoAccess();
isAllowed.then(logIsAllowed);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isAllowedIncognitoAccess` | Yes | 17 | 48 | ? | Yes | 14Always returns true. | ? | ? | 48 | ? | 15Always returns true. | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-isAllowedIncognitoAccess) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/isAllowedIncognitoAccess>

permissions.onRemoved
=====================


Fired when some permissions are removed from the extension.


Syntax
------




```
browser.permissions.onRemoved.addListener(listener)
browser.permissions.onRemoved.removeListener(listener)
browser.permissions.onRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `permissions`  [`permissions.Permissions`](permissions) object containing the permissions that were removed.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRemoved` | Yes | 79 | 77 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------




```
function handleRemoved(permissions) {
  console.log(`Removed API permissions: ${permissions.permissions}`);
  console.log(`Removed host permissions: ${permissions.origins}`);
}

browser.permissions.onRemoved.addListener(handleRemoved);

```
  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/onRemoved>

extension.getViews()
====================



Returns an array of the [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) objects for each of the pages running inside the current extension. This includes, for example:

 * the background page, if one is defined
* any popup pages, if defined and loaded
* any options pages, if defined and loaded
* any browser tabs that host content packaged with the extension

 In Firefox, if this method is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then its return value will not include the extension's background page.



Syntax
------



```
let windows = browser.extension.getViews(
  fetchProperties // optional object
)

```
### Parameters


 
`fetchProperties` Optional
  An object with the following properties:

  
`type` Optional
  `string`. An [`extension.ViewType`](viewtype) indicating the type of view to get. If omitted, this function returns all views.

  
`windowId` Optional
  `integer`. The window to restrict the search to. If omitted, this function returns all views. In Firefox version 92 and earlier, sidebar views are not matched and, therefore, not returned.

    ### Return value


`array` of `object`. Array of [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) objects.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getViews` | Yes | 14 | 45If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then its return value will not include the extension's background page. | ? | Yes | 14 | ? | ? | 48If this is called from a page that is part of a private browsing window, such as a sidebar in a private window or a popup opened from a private window, then its return value will not include the extension's background page. | ? | 15 | ? |
| `windowId` | Yes | 14 | 45Since Firefox 93, sidebar views are now matched. | ? | Yes | 14Filtering by `windowId` won't work when a tab is moved from one window to another. | ? | ? | 48The property is recognized, but the filter has no effect. | ? | 15Filtering by `windowId` won't work when a tab is moved from one window to another. | ? |


Examples
--------



Get all windows belonging to this extension, and log their URLs:

 
```
const windows = browser.extension.getViews();

for (const extensionWindow of windows) {
  console.log(extensionWindow.location.href);
}

```
 Get only windows in browser tabs hosting content packaged with the extension:

 
```
const windows = browser.extension.getViews({ type: "tab" });

```
 Get only windows in popups:

 
```
const windows = browser.extension.getViews({ type: "popup" });

```
  **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-getViews) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/getViews>

userScripts.onBeforeScript
==========================


The `onBeforeScript` event of the [`browser.userScripts`](../userscripts) is fired before a user script is executed. It can only be included in the API script, the script registered in [`"user_scripts"`](../../manifest.json/user_scripts), where it is used to detect that the custom API methods should be exported to the user script.


Syntax
------




```
browser.userScripts.onBeforeScript.addListener(listener)
browser.userScripts.onBeforeScript.removeListener(listener)
browser.userScripts.onBeforeScript.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `listener`  A function that is called when this event occurs. The function is passed the following arguments:

  `script`  An `object` that represents the user script that matched a web page. Its properties and methods are as follows:

  `defineGlobals`  A method that exports an object containing properties and methods available globally to the user script sandbox. This method must be called synchronously to guarantee that the user script has not executed.

  `export`  A method that converts a value to one that the user script code can access. This method is used in API methods exported to the user script to result or resolve non-primitive values. The exported objects can also provide methods that the user script code can access and call.

  `global`  An `object` that provides access to the sandbox for the user script.

  `metadata`  The `scriptMetadata` property set when the user script was registered using `userScripts.register`.

      Examples
--------



An example of how the listener might be used:

 
```
browser.userScripts.onBeforeScript.addListener((script) => {

  script // This is an API object that represents the user script
         // that is going to be executed.

  script.metadata // Access the user script metadata (returns the
                  // value of the scriptMetadata property from
                  // the call to userScripts.register.

  // Export some global properties into the user script sandbox
  // (this method has to be called synchronously from the
  // listener, otherwise the user script may have executed).
  script.defineGlobals({
    aGlobalPropertyAccessibleFromUserScriptCode: "prop value",

    myCustomAPIMethod(param1, param2) {
      // Custom methods exported from the API script can use
      // the WebExtensions APIs available to content scripts.
      browser.runtime.sendMessage(/\* … \*/);
      // …

      return 123; // primitive values can be returned directly
      // …

      // Non primitive values have to be exported explicitly
      // using the export method provided by the script API
      // object
      return script.export({
        objKey1: {
          nestedProp: "nestedValue",
        },
        // Explicitly exported objects can also provide methods.
        objMethod() { /\* … \*/ }
      })
    },

    async myAsyncMethod(param1, param2, param3) {
    // exported methods can also be declared as async
    },
  });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBeforeScript` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |


See also
--------


* [`contentScripts`](../contentscripts)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/onBeforeScript>

permissions.contains()
======================



Check whether the extension has the permissions listed in the given [`permissions.Permissions`](permissions) object.

 The `Permissions` argument may contain either an origins property, which is an array of [host permissions](../../manifest.json/permissions#host_permissions), or a `permissions` property, which is an array of [API permissions](../../manifest.json/permissions#api_permissions), or both.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). The promise is fulfilled with true only if all the extension currently has all the given permissions. For host permissions, if the extension's permissions [pattern-match](../../match_patterns) the permissions listed in `origins`, then they are considered to match.



Syntax
------



```
let getContains = browser.permissions.contains(
  permissions                // Permissions object
)

```
### Parameters


 `permissions`  A [`permissions.Permissions`](permissions) object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the extension already has all the permissions listed in the `permissions` argument, or `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `contains` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------




```
// Extension permissions are:
// "webRequest", "tabs", "\*://\*.mozilla.org/\*"

let testPermissions1 = {
  origins: ["\*://mozilla.org/"],
  permissions: ["tabs"]
};

const testResult1 = await browser.permissions.contains(testPermissions1);
console.log(testResult1); // true

let testPermissions2 = {
  origins: ["\*://mozilla.org/"],
  permissions: ["tabs", "alarms"]
};

const testResult2 = await browser.permissions.contains(testPermissions2);
console.log(testResult2); // false, "alarms" doesn't match

let testPermissions3 = {
  origins: ["https://developer.mozilla.org/"],
  permissions: ["tabs", "webRequest"]
};

const testResult3 = await browser.permissions.contains(testPermissions3);
console.log(testResult3); // true: "https://developer.mozilla.org/"
                          // matches: "\*://\*.mozilla.org/\*"

let testPermissions4 = {
  origins: ["https://example.org/"]
};

const testResult4 = await browser.permissions.contains(testPermissions4);
console.log(testResult4); // false, "https://example.org/"
                          // does not match

```
  **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/contains>

downloads.FilenameConflictAction
================================



The `FilenameConflictAction` type of the [`downloads`](../downloads) API specifies what to do if the name of a downloaded file conflicts with an existing file.

 This type defines the values that can be used for the `conflictAction` property of the [`downloads.download`](download) function's `options` parameter.



Type
----



Values of this type are strings. Possible values are:

  `"uniquify"`  The browser will modify the filename to make it unique.

  `"overwrite"`  The browser will overwrite the old file with the newly-downloaded file.

  `"prompt"`  The browser will prompt the user, asking them to choose whether to uniquify or overwrite.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `FilenameConflictAction` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `prompt` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-FilenameConflictAction) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/FilenameConflictAction>

downloads.InterruptReason
=========================



The `InterruptReason` type of the [`downloads`](../downloads) API defines a set of possible reasons why a download was interrupted.

 A [`downloads.DownloadItem`](downloaditem)'s `error` property will contain a string taken from the values defined in this type.



Type
----



Values of this type are strings. Possible values are split into categories, with each set having the same substring at the beginning:

 File-related errors:

 * `"FILE_FAILED"`
* `"FILE_ACCESS_DENIED"`
* `"FILE_NO_SPACE"`
* `"FILE_NAME_TOO_LONG"`
* `"FILE_TOO_LARGE"`
* `"FILE_VIRUS_INFECTED"`
* `"FILE_TRANSIENT_ERROR"`
* `"FILE_BLOCKED"`
* `"FILE_SECURITY_CHECK_FAILED"`
* `"FILE_TOO_SHORT"`

 Network-related errors:

 * `"NETWORK_FAILED"`
* `"NETWORK_TIMEOUT"`
* `"NETWORK_DISCONNECTED"`
* `"NETWORK_SERVER_DOWN"`
* `"NETWORK_INVALID_REQUEST"`

 Server-related errors:

 * `"SERVER_FAILED"`
* `"SERVER_NO_RANGE"`
* `"SERVER_BAD_CONTENT"`
* `"SERVER_UNAUTHORIZED"`
* `"SERVER_CERT_PROBLEM"`
* `"SERVER_FORBIDDEN"`

 User-related errors:

 * `"USER_CANCELED"`
* `"USER_SHUTDOWN"`

 Miscellaneous:

 * `"CRASH"`


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `InterruptReason` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-InterruptReason) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/InterruptReason>

downloads.DangerType
====================



The `DangerType` type of the [`downloads`](../downloads) API defines a set of possible reasons that a downloadable file might be considered dangerous.

 A [`downloads.DownloadItem`](downloaditem)'s `danger` property will contain a string taken from the values defined in this type.

  **Note:** These string constants will never change, however the set of DangerTypes may change.

 

Type
----



Values of this type are strings. Possible values are:

  `file`  The download's filename is suspicious.

  `url`  The download's URL is known to be malicious.

  `content`  The downloaded file is known to be malicious.

  `uncommon`  The download's URL is not commonly downloaded.

  `host`  The download came from a host known to distribute malicious binaries.

  `unwanted`  The download is potentially unwanted or unsafe.

  `safe`  The download presents no known danger to the user's computer.

  `accepted`  The user has accepted the dangerous download.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DangerType` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-DangerType) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/DangerType>

downloads.State
===============



The `State` type of the [`downloads`](../downloads) API defines different states that a current download can be in.

 A [`downloads.DownloadItem`](downloaditem)'s `state` property will contain a string taken from the values defined in this type.



Type
----



Values of this type are strings. Possible values are:

  `in_progress`  The browser is currently receiving download data from the server.

  `interrupted`  An error broke the connection with the server.

  `complete`  The download completed successfully.

    **Note:** These string constants will never change, but new constants may be added.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `State` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-State) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/State>

downloads.DownloadItem
======================


The `DownloadItem` type of the [`downloads`](../downloads) API represents a downloaded file.


Type
----



Values of this type are objects. They contain the following properties:

  
`byExtensionId` Optional
  A `string` representing the ID of the extension that triggered the download (if it was triggered by an extension). This does not change once set. If the download was not triggered by an extension this is undefined.

  
`byExtensionName` Optional
  A `string` representing the name of the extension that triggered the download (if it was triggered by an extension). This may change if the extension changes its name or the user changes their locale. If the download was not triggered by an extension this is undefined.

  `bytesReceived`  A `number` representing the number of bytes received so far from the host during the download; this does not take file compression into consideration.

  `canResume`  A `boolean` indicating whether a currently-interrupted (e.g. paused) download can be resumed from the point where it was interrupted (`true`), or not (`false`).

  
`cookieStoreId` Optional
  The cookie store ID of the [contextual identity](../../work_with_contextual_identities) in which the download took place.

  `danger`  A string indicating whether this download is thought to be safe or known to be suspicious. Its possible values are defined in the [`downloads.DangerType`](dangertype) type.

  
`endTime` Optional
  A `string` (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format) representing the number of milliseconds between the UNIX epoch and when this download ended. This is undefined if the download has not yet finished.

  
`error` Optional
  A string indicating why a download was interrupted. Possible values are defined in the [`downloads.InterruptReason`](interruptreason) type. This is undefined if an error has not occurred.

  
`estimatedEndTime` Optional
  A `string` (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format) representing the estimated number of milliseconds between the UNIX epoch and when this download is estimated to be completed. This is undefined if it is not known (in particular, it is undefined in the `DownloadItem` that's passed into [`downloads.onCreated`](oncreated)).

  `exists`  A `boolean` indicating whether a downloaded file still exists (`true`) or not (`false`). This information might be out-of-date, as browsers do not automatically watch for file removal — to check whether a file exists, call the [`downloads.search()`](search) method, filtering for the file in question.

  `filename`  A `string` representing the file's absolute local path.

  `fileSize`  A `number` indicating the total number of bytes in the whole file, after decompression. A value of -1 here means that the total file size is unknown.

  `id`  An `integer` representing a unique identifier for the downloaded file that is persistent across browser sessions.

  `incognito`  A `boolean` that indicates whether the download is recorded in the browser's history (`false`), or not (`true`).

  `mime`  A `string` representing the downloaded file's MIME type.

  `paused`  A `boolean` indicating whether the download is paused, i.e. if the download has stopped reading data from the host but has kept the connection open. If so, the value is `true`, `false` if not.

  `referrer`  A `string` representing the downloaded file's referrer.

  `startTime`  A `string` (in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format) representing the number of milliseconds between the UNIX epoch and when this download began.

  `state`  A `string` Indicating whether the download is progressing, interrupted, or complete. Possible values are defined in the [`downloads.State`](state) type.

  `totalBytes`  A `number` indicating the total number of bytes in the file being downloaded. This does not take file compression into consideration. A value of -1 here means that the total number of bytes is unknown.

  `url`  A `string` representing the absolute URL from which the file was downloaded.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `byExtensionId` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `byExtensionName` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `bytesReceived` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `canResume` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `cookieStoreId` | No | No | 92 | ? | No | No | ? | ? | No | ? | No | ? |
| `danger` | Yes | 79 | NoAlways given as 'safe'. | ? | Yes | No | ? | ? | No | ? | No | ? |
| `endTime` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `error` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `estimatedEndTime` | Yes | 79 | 57 | ? | Yes | No | ? | ? | 57–79 | ? | No | ? |
| `exists` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `fileSize` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `filename` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `id` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `incognito` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `mime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `paused` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `referrer` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `startTime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `state` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `totalBytes` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `url` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-DownloadItem) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/DownloadItem>

Permissions
===========


A `Permissions` object represents a collection of permissions.


Type
----



An [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) with the following properties:

  
`origins` Optional
  An array of [match patterns](../../match_patterns), representing [host permissions](../../manifest.json/permissions#host_permissions).

  
`permissions` Optional
  An array of named permissions, including [API permissions](../../manifest.json/permissions#api_permissions) and [clipboard permissions](../../manifest.json/permissions#clipboard_access).

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Permissions` | Yes | 79 | 55 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.permissions`](https://developer.chrome.com/docs/extensions/reference/permissions/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/Permissions>

downloads.StringDelta
=====================


The `StringDelta` type of the [`downloads`](../downloads) API represents the difference between two strings.


Type
----



Values of this type are objects. They contain the following properties:

  
`current` Optional
  A `string` representing the current string value.

  
`previous` Optional
  A `string` representing the previous string value.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `StringDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-StringDelta) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/StringDelta>

downloads.DoubleDelta
=====================


The `DoubleDelta` type of the [`downloads`](../downloads) API represents the difference between two doubles.


Type
----



Values of this type are objects. They contain the following properties:

  
`current` Optional
  A `number` representing the current double value.

  
`previous` Optional
  A `number` representing the previous double value.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DoubleDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-DoubleDelta) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/DoubleDelta>

downloads.pause()
=================



The `pause()` function of the [`downloads`](../downloads) API pauses a download.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let pausing = browser.downloads.pause(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the `id` of the download to pause.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the call was successful, the download will be put in a paused state, and the promise will be fulfilled with no arguments. If the call fails, the promise will be rejected with an error message. The call will fail if the download is not active: for example, because it has finished downloading.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `pause` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------




```
function onPaused() {
  console.log(`Paused download`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let pausing = browser.downloads.pause(downloadId);
pausing.then(onPaused, onError);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-pause) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/pause>

downloads.cancel()
==================



The `cancel()` function of the [`downloads`](../downloads) API cancels a download. The call will fail if the download is not active: for example, because it has completed downloading.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let canceling = browser.downloads.cancel(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  `integer`. The id of the download to cancel.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request was successful, the promise will be fulfilled with no arguments. If the request failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `cancel` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------




```
let downloadId = 13;

function onCanceled() {
  console.log(`Canceled download`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let canceling = browser.downloads.cancel(downloadId);
canceling.then(onCanceled, onError);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-cancel) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/cancel>

downloads.BooleanDelta
======================


The `BooleanDelta` type of the [`downloads`](../downloads) API represents the difference between two booleans.


Type
----



Values of this type are objects. They contain the following properties:

  
`current` Optional
  A `boolean` representing the current boolean value.

  
`previous` Optional
  A `boolean` representing the previous boolean value.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BooleanDelta` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-BooleanDelta) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/BooleanDelta>

downloads.DownloadTime
======================


The `DownloadTime` type of the [`downloads`](../downloads) API represents the time a download took to complete.


Type
----



A `DownloadTime` can be one of three different types:

 * a JavaScript [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object.
* a string:
	+ if this contains only digits, it's interpreted as the number of milliseconds since the UNIX epoch.
	+ otherwise, it's interpreted as an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) string.
* a number: this is interpreted as the number of milliseconds since the UNIX epoch.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DownloadTime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-DownloadTime) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/DownloadTime>

downloads.DownloadQuery
=======================



The `DownloadQuery` type of the [`downloads`](../downloads) API defines a set of parameters that can be used to search the downloads manager for a specific set of downloads.

 This type is used for example in [`downloads.search()`](search) and [`downloads.erase()`](erase), as a query object to filter the set of [`DownloadItems`](downloaditem) to return or erase.



Type
----



Values of this type are objects. They contain the following properties:

  
`cookieStoreId` Optional
  The cookie store ID of the [contextual identity](../../work_with_contextual_identities) in which the download took place.

  
`query` Optional
  An `array` of `string`s. Include only [`DownloadItems`](downloaditem) whose `filename` or `url` contains all of the given strings. You can also include terms beginning with a dash (-) — these terms **must not** be contained in the item's `filename` or `url` for it to be included.

  
`startedBefore` Optional
  A [`DownloadTime`](downloadtime). Include only [`DownloadItems`](downloaditem) that started before the given time.

  
`startedAfter` Optional
  A [`DownloadTime`](downloadtime). Include only [`DownloadItems`](downloaditem) that started after the given time.

  
`endedBefore` Optional
  A [`DownloadTime`](downloadtime). Include only [`DownloadItems`](downloaditem) that ended before the given time.

  
`endedAfter` Optional
  A [`DownloadTime`](downloadtime). Include only [`DownloadItems`](downloaditem) that ended after the given time.

  
`totalBytesGreater` Optional
  A `number` representing a number of bytes. Include only [`DownloadItems`](downloaditem) whose `totalBytes` is greater than the given number.

  
`totalBytesLess` Optional
  A `number` representing a number of bytes. Include only [`DownloadItems`](downloaditem) whose `totalBytes` is less than the given number.

  
`filenameRegex` Optional
  A `string` representing a regular expression. Include only [`DownloadItems`](downloaditem) whose `filename` value matches the given regular expression.

  
`urlRegex` Optional
  A `string` representing a regular expression. Include only [`DownloadItems`](downloaditem) whose `url` value matches the given regular expression.

  
`limit` Optional
  An `integer` representing a number of results. Include only the specified number of [`DownloadItems`](downloaditem).

  
`orderBy` Optional
  An `array` of `string`s representing [`DownloadItem`](downloaditem) properties the search results should be sorted by. For example, including `startTime` then `totalBytes` in the array would sort the [`DownloadItems`](downloaditem) by their start time, then total bytes — in ascending order. To specify sorting by a property in descending order, prefix it with a hyphen, for example `-startTime`.

  
`id` Optional
  An `integer` representing the ID of the [`downloads.DownloadItem`](downloaditem) you want to query.

  
`url` Optional
  A `string` representing the absolute URL that the download was initiated from, before any redirects.

  
`filename` Optional
  A string representing the absolute local path of the download file you want to query.

  
`danger` Optional
  A string representing a [`downloads.DangerType`](dangertype) — include only [`DownloadItems`](downloaditem) with this `danger` value.

  
`mime` Optional
  A `string` representing a MIME type. Include only [`DownloadItems`](downloaditem) with this `mime` value.

  
`startTime` Optional
  A `string` representing an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format time. Include only [`DownloadItems`](downloaditem) with this `startTime` value.

  
`endTime` Optional
  A `string` representing an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format time. Include only will limited to [`DownloadItems`](downloaditem) with this `endTime` value.

  
`state` Optional
  A `string` representing a download [`downloads.State`](state) (`in_progress`, `interrupted`, or `complete`). Include only [`DownloadItems`](downloaditem) with this `state` value.

  
`paused` Optional
  A `boolean` that indicates whether a download is paused — i.e. has stopped reading data from the host, but kept the connection open (`true`), or not (`false`). Include only [`DownloadItems`](downloaditem) with this `paused` value.

  
`error` Optional
  A string representing an [`downloads.InterruptReason`](interruptreason) — a reason why a download was interrupted. Include only [`DownloadItems`](downloaditem) with this `error` value.

  
`bytesReceived` Optional
  A `number` representing the number of bytes received so far from the host, without considering file compression. Include only [`DownloadItems`](downloaditem) with this `bytesReceived` value.

  
`totalBytes` Optional
  A `number` representing the total number of bytes in the downloaded file, without considering file compression. Include only [`DownloadItems`](downloaditem) with this `totalBytes` value.

  
`fileSize` Optional
  `number`. Number of bytes in the whole file post-decompression, or -1 if unknown. A `number` representing the total number of bytes in the file after decompression. Include only [`DownloadItems`](downloaditem) with this `fileSize` value.

  
`exists` Optional
  A `boolean` indicating whether a downloaded file still exists (`true`) or not (`false`). Include only [`DownloadItems`](downloaditem) with this `exists` value.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DownloadQuery` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `bytesReceived` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `cookieStoreId` | No | No | 92 | ? | No | No | ? | ? | No | ? | No | ? |
| `danger` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `endTime` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `endedAfter` | Yes | 79 | 47The parameter is ignored. | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `endedBefore` | Yes | 79 | 47The parameter is ignored. | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `error` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `exists` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `fileSize` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `filename` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `filenameRegex` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `id` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `limit` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `mime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `orderBy` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `paused` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `query` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `startTime` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `startedAfter` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `startedBefore` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `state` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `totalBytes` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `totalBytesGreater` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `totalBytesLess` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `url` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |
| `urlRegex` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#type-DownloadQuery) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/DownloadQuery>

downloads.resume()
==================



The `resume()` function of the [`downloads`](../downloads) API resumes a paused download. If the request was successful, the download will be unpaused and progress will resume. The `resume()` call will fail if the download is not active: for example, because it has finished downloading.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let resuming = browser.downloads.resume(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the `id` of the download to resume.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request was successful, the promise will be fulfilled with no arguments. If the request failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `resume` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------




```
let downloadId = 2;

function onResumed() {
  console.log(`Resumed download`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let resuming = browser.downloads.resume(downloadId);
resuming.then(onResumed, onError);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-resume) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/resume>

downloads.show()
================



The `show()` function of the [`downloads`](../downloads) API shows the downloaded file in its containing folder in the underlying platform's file manager.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let showing = browser.downloads.show(
  downloadId             // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the ID of the [`DownloadItem`](downloaditem) to show.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If the request succeeds, the promise will be fulfilled with a boolean about whether the request was successful. If the request fails, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `show` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



This example shows the most recently downloaded item:

 
```
function onShowing(success) {
  console.log(`Showing download item: ${success}`);
}

function onError(error) {
  console.log(`Error opening item: ${error}`);
}

function openDownload(downloadItems) {
    if (downloadItems.length > 0) {
      latestDownloadId = downloadItems[0].id;
      let showing = browser.downloads.show(latestDownloadId);
      showing.then(onShowing, onError);
    }
  }

let searching = browser.downloads.search({
  limit: 1,
  orderBy: ["-startTime"]
});

searching.then(openDownload, onError);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-show) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/show>

downloads.showDefaultFolder()
=============================


The `showDefaultFolder()` function of the [`downloads`](../downloads) API opens the default downloads folder in the platform's file manager.


Syntax
------



```
browser.downloads.showDefaultFolder();

```
### Parameters


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `showDefaultFolder` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



The following snippet contains a show button, which when clicked invokes `showDefaultFolder()` to open the default downloads folder in the platform's file manager:

 
```
let showBtn = document.querySelector('.show');

showBtn.onclick = () => {
  browser.downloads.showDefaultFolder();
}

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-showDefaultFolder) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/showDefaultFolder>

downloads.acceptDanger()
========================



The `acceptDanger()` function of the [`downloads`](../downloads) API prompts the user to either accept or cancel a potentially dangerous download.

 This function can't be called from background scripts, only in scripts that are running in a visible window (such as a browser or page action's popup).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let prompting = browser.downloads.acceptDanger(
  downloadId      // integer
)

```
### Parameters


 `downloadId`  An `integer` representing the `id` of the [`DownloadItem`](downloaditem) in question.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). When the dialog closes, the promise will be fulfilled with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `acceptDanger` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-acceptDanger) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/acceptDanger>

downloads.setShelfEnabled()
===========================



The `setShelfEnabled()` function of the [`downloads`](../downloads) API enables or disables the gray shelf at the bottom of every window associated with the current browser profile. The shelf will be disabled as long as at least one extension has disabled it.

 If you try to enable the shelf when at least one other extension has already disabled it, the call will fail and [`runtime.lastError`](../runtime/lasterror) will be set with an appropriate error message.

  **Note:** To use this function in your extension you must ask for the `"downloads.shelf"` [manifest permission](../../manifest.json/permissions), as well as the `"downloads"` permission.

 

Syntax
------




```
chrome.downloads.setShelfEnabled(enabled);

```
 This API is also available as `browser.downloads.setShelfEnabled()`.


### Parameters


 `enabled`  A `boolean` representing the state that you want to set `setShelfEnabled()` to — `true` for enable, and `false` for disable.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setShelfEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-setShelfEnabled) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/setShelfEnabled>

downloads.onCreated
===================



The `onCreated()` event of the [`downloads`](../downloads) API fires when a download begins, i.e. when [`downloads.download()`](download) is successfully invoked.

 The listener is passed the [`downloads.DownloadItem`](downloaditem) object in question as a parameter.



Syntax
------




```
browser.downloads.onCreated.addListener(listener)
browser.downloads.onCreated.removeListener(listener)
browser.downloads.onCreated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether a given `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that will be called when this event occurs. This function will be passed the following arguments:

  `downloadItem`  The [`downloads.DownloadItem`](downloaditem) object in question.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreated` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



Log the URL of items as they are downloaded:

 
```
function handleCreated(item) {
  console.log(item.url);
}

browser.downloads.onCreated.addListener(handleCreated);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#event-onCreated) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/onCreated>

runtime.PlatformOs
==================


The operating system the browser is running on.


Type
----



Values of this type are strings. Possible values are:

  `"mac"`  The underlying operating system is macOS.

  `"win"`  The underlying operating system is Windows.

  `"android"`  The underlying operating system is Android.

  `"cros"`  The underlying operating system is Chrome OS.

  `"linux"`  The underlying operating system is Linux.

  `"openbsd"`  The underlying operating system is Open/FreeBSD.

  `"fuchsia"`  The underlying operating system is Fuchsia.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `PlatformOs` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformOs) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/PlatformOs>

downloads.drag()
================


The `drag()` function of the [`downloads`](../downloads) API initiates dragging the downloaded file to another application.


Syntax
------




```
chrome.downloads.drag(
  downloadId // integer
)

```
 This API is also available as `browser.downloads.drag()`.


### Parameters


 `downloadId`  An `integer` representing the `id` of the [`DownloadItem`](downloaditem) in question.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `drag` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#method-drag) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/drag>

downloads.onErased
==================



The `onErased()` event of the [`downloads`](../downloads) API fires when a download is erased from the browser history.

 The listener is passed the `downloadId` of the [`downloads.DownloadItem`](downloaditem) object in question as a parameter.



Syntax
------




```
browser.downloads.onErased.addListener(listener)
browser.downloads.onErased.removeListener(listener)
browser.downloads.onErased.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether a given `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A callback function that will be called when this event occurs. This function will be passed the following arguments:

  `downloadId`  An `integer` representing the `id` of the [`downloads.DownloadItem`](downloaditem) that was erased.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onErased` | Yes | 79 | 48 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



Add a listener for `onErased` events, then erase the most recent download:

 
```
function handleErased(item) {
  console.log(`Erased: ${item}`);
}

browser.downloads.onErased.addListener(handleErased);

let erasing = browser.downloads.erase({
  limit: 1,
  orderBy: ["-startTime"]
});

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#event-onErased) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/onErased>

downloads.onChanged
===================



The `onChanged()` event of the [`downloads`](../downloads) API is fired when any of a [`downloads.DownloadItem`](downloaditem)'s properties changes (except for `bytesReceived`).

 The listener is passed a `downloadDelta` as a parameter — an object containing the `downloadId` of the [`downloads.DownloadItem`](downloaditem) object in question, plus the status of all the properties that changed.



Syntax
------




```
browser.downloads.onChanged.addListener(listener)
browser.downloads.onChanged.removeListener(listener)
browser.downloads.onChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether a given `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A callback function that will be called when this event occurs. This function will be passed the following arguments:

  `downloadDelta`  An `object` representing the [`downloads.DownloadItem`](downloaditem) object that changed, and the status of all the properties that changed in it. See the [downloadDelta](#downloaddelta_2) section for more details.

    Additional objects
------------------


### downloadDelta



The `downloadDelta` object has the following properties available:

  `id`  An `integer` representing the `id` of the [`downloads.DownloadItem`](downloaditem) that changed.

  
`url` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `url`.

  
`filename` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `filename`.

  
`danger` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `danger`.

  
`mime` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `mime`.

  
`startTime` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `startTime`.

  
`endTime` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `endTime`.

  
`state` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `state`.

  
`canResume` Optional
  A [`downloads.BooleanDelta`](booleandelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `canResume` status.

  
`paused` Optional
  A [`downloads.BooleanDelta`](booleandelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `paused` status.

  
`error` Optional
  A [`downloads.StringDelta`](stringdelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `error` status.

  
`totalBytes` Optional
  A [`downloads.DoubleDelta`](doubledelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `totalBytes`.

  
`fileSize` Optional
  A [`downloads.DoubleDelta`](doubledelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `fileSize`.

  
`exists` Optional
  A [`downloads.BooleanDelta`](booleandelta) object describing a change in a [`downloads.DownloadItem`](downloaditem)'s `exists` status.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48–79 | ? | No | ? |


Examples
--------



Log a message when downloads complete:

 
```
function handleChanged(delta) {
  if (delta.state && delta.state.current === "complete") {
    console.log(`Download ${delta.id} has completed.`);
  }
}

browser.downloads.onChanged.addListener(handleChanged);

```
  **Note:** This API is based on Chromium's [`chrome.downloads`](https://developer.chrome.com/docs/extensions/reference/downloads/#event-onChanged) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads/onChanged>

runtime.PlatformArch
====================


The machine's processor architecture.


Type
----



Values of this type are strings. Possible values are:

  `"arm"`  The platform is based on arm architecture.

  `"x86-32"`  The platform is based on x86 32-bit architecture.

  `"x86-64"`  The platform is based on x86 64-bit architecture.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `PlatformArch` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformArch) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/PlatformArch>

runtime.requestUpdateCheck()
============================



Checks to see if an update for the extension is available.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let requestingCheck = browser.runtime.requestUpdateCheck()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with two arguments:

  `status`  A [`runtime.RequestUpdateCheckStatus`](requestupdatecheckstatus) value — the result of the update check.

  
`details` Optional
  `object`. If `status` is `update_available`, this contains more information about the update. It is an object containing a single property:

  `version`  `string`. The update's version.

    
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `requestUpdateCheck` | 25 | 79 | No | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------



Request an update, and log the new version if one is available:

 
```
function onRequested(status, details) {
  console.log(status);
  if (status === "update\_available") {
    console.log(details.version);
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let requestingCheck = browser.runtime.requestUpdateCheck(onRequested);
requestingCheck.then(onRequested, onError);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-requestUpdateCheck) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/requestUpdateCheck>

runtime.OnInstalledReason
=========================


The reason that the [`runtime.onInstalled`](oninstalled) event is being dispatched.


Type
----



Values of this type are strings. Possible values are:

  `"install"`  The extension was installed.

  `"update"`  The extension was updated to a new version.

  
`"browser_update"` or, for Chrome, `"chrome_update"`
  The browser was updated to a new version.

  `"shared_module_update"`  Another extension, which contains a module used by this extension, was updated.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnInstalledReason` | YesUses 'chrome\_update' instead of 'browser\_update'. | 14Only supports 'install' and 'update'. | 45 | ? | YesUses 'chrome\_update' instead of 'browser\_update'. | 14Only supports 'install' and 'update'. | ? | ? | 48 | ? | 15Only supports 'install' and 'update'. | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-OnInstalledReason) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/OnInstalledReason>

runtime.OnRestartRequiredReason
===============================


The reason that the [`onRestartRequired`](onrestartrequired) event is being dispatched.


Type
----



Values of this type are strings. Possible values are:

 * `"app_update"`: The application is being updated to a newer version.
* `"os_update"`: The browser/OS is updated to a newer version.
* `"periodic"`: The system has run for more than the permitted uptime set in the enterprise policy.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnRestartRequiredReason` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-OnRestartRequiredReason) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/OnRestartRequiredReason>

runtime.onRestartRequired
=========================


Fired when an app or the device that it runs on needs to be restarted. The app should close all its windows at its earliest convenience to let the restart happen. If the app does nothing, a restart will be enforced after a 24-hour grace period has passed. Currently, this event is only fired for Chrome OS kiosk apps.


Syntax
------




```
browser.runtime.onRestartRequired.addListener(listener)
browser.runtime.onRestartRequired.removeListener(listener)
browser.runtime.onRestartRequired.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `reason`  A [`runtime.OnRestartRequiredReason`](onrestartrequiredreason) value — the reason that the event is being dispatched.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRestartRequired` | 29 | 79 | No | ? | 16 | No | ? | ? | No | ? | No | ? |


Examples
--------


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onRestartRequired) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onRestartRequired>

runtime.RequestUpdateCheckStatus
================================


Result of a call to [`runtime.requestUpdateCheck()`](requestupdatecheck).


Type
----



Values of this type are strings. Possible values are:

  `"throttled"`  Update is throttled.

  `"no_update"`  No update is available.

  `"update_available"`  An update of the extension is available.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RequestUpdateCheckStatus` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-RequestUpdateCheckStatus) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/RequestUpdateCheckStatus>

runtime.getFrameId()
====================


Returns the frame ID of any window global or frame element when called from a content script or extension page, including background pages.


Syntax
------



```
let gettingInfo = browser.runtime.getFrameId(
  target               // object
)

```
### Parameters


 `target`  A [WindowProxy](https://developer.mozilla.org/en-US/docs/Glossary/WindowProxy) or a [browsing context](https://developer.mozilla.org/en-US/docs/Glossary/Browsing_context) container [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) (iframe, frame, embed, or object) for the target frame.

  ### Return value


Returns the frame ID of the target frame, or -1 if the frame doesn't exist.

Examples
--------



This code recursively walks descendant frames and gets parent frame IDs.

 
```
const parents = {};

function visit(win) {
  const frameId = browser.runtime.getFrameId(win);
  const parentId = browser.runtime.getFrameId(win.parent);
  parents[frameId] = win.parent !== win ? parentId : -1;

  try {
    const frameEl = browser.runtime.getFrameId(win.frameElement);
    browser.test.assertEq(frameId, frameEl, "frameElement id correct");
  } catch (e) {
    // Can't access a cross-origin .frameElement.
  }

  for (const frame of win.frames) {
    visit(frame);
  }
}
visit(window);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getFrameId` | No | No | 96 | ? | No | 16 | ? | ? | 96 | ? | 16 | ? |


 **Note:** Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getFrameId>

runtime.setUninstallURL()
=========================



Sets the URL to be visited when the extension is uninstalled. This may be used to clean up server-side data, do analytics, or implement surveys. The URL can be a maximum 255 characters.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let settingUrl = browser.runtime.setUninstallURL(
  url             // string
)

```
### Parameters


 `url`  `string`. URL to be opened after the extension is uninstalled. This URL must have an `http` or `https` scheme. Set it to an empty string to not open a new tab upon uninstallation.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the URL has been set, or rejected with an error message if the operation failed.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setUninstallURL` | 41 | 15 | 47 | ? | 28 | 14API exists, but has no effect. | ? | ? | 48 | ? | 15API exists, but has no effect. | ? |


Examples
--------




```
function onSetURL() {
  console.log("set uninstall URL");
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let settingUrl = browser.runtime.setUninstallURL("https://example.org");
settingUrl.then(onSetURL, onError);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-setUninstallURL) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/setUninstallURL>

runtime.getPlatformInfo()
=========================



Returns information about the current platform. This can only be called in the background script context.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.runtime.getPlatformInfo()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`runtime.PlatformInfo`](platforminfo) value representing the current platform.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPlatformInfo` | 29 | 79 | 45 | ? | 16 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



Get and log the platform OS:

 
```
function gotPlatformInfo(info) {
  console.log(info.os);
}

let gettingInfo = browser.runtime.getPlatformInfo();
gettingInfo.then(gotPlatformInfo);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-getPlatformInfo) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getPlatformInfo>

runtime.onStartup
=================



Fired when a profile that has this extension installed first starts up. This event is not fired when a private browsing (incognito) profile is started, even if this extension is operating in 'split' incognito mode.

   **Note:** When using an event page or background service worker, the extension must add a listener to `runtime.onStartup` on the event page for the event page to be executed at least once per browser session. 

 

Syntax
------



```
browser.runtime.onStartup.addListener(listener)
browser.runtime.onStartup.removeListener(listener)
browser.runtime.onStartup.hasListener(listener)

```
### Event Functions



All events have three functions:

  `addListener(listener)`  Adds a `listener` to the calling event.

  `removeListener(listener)`  Stop listening to the calling event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for the calling event. Returns `true` if it is listening, `false` otherwise.

  
### Parameters



The only parameter is `listener`, used for any of the above functions.

  `listener`  A function that is called when this event occurs.

  
Examples
--------



Open <https://giphy.com/explore/cat> when the browser starts up:

 
```
function handleStartup() {
  browser.tabs.create({
    url: "https://giphy.com/explore/cat"
  });
}

browser.runtime.onStartup.addListener(handleStartup);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onStartup` | 23 | 79 | 52 | ? | 15 | 14 | ? | ? | 52 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onStartup) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onStartup>

runtime.onUpdateAvailable
=========================



Fired when an update to the extension is available. This event enables an extension to delay an update: for example, because it is in the middle of some operation which should not be interrupted.

 If the extension is not listening for this event when an update becomes available, the extension is reloaded immediately and the update is applied. If the extension is listening, then the update will be applied the next time the extension is reloaded. This happens if:

 * the browser is restarted
* the extension is disabled and re-enabled
* the extension explicitly reloads itself by calling [`runtime.reload()`](reload).



Syntax
------




```
browser.runtime.onUpdateAvailable.addListener()
browser.runtime.onUpdateAvailable.removeListener(listener)
browser.runtime.onUpdateAvailable.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Contains a single property, a string named `version`, which represents the version number of the update.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onUpdateAvailable` | 25 | 79 | 51 | ? | 15 | No | ? | ? | 51 | ? | No | ? |


Examples
--------



Listen for `UpdateAvailable` events:

 
```
function handleUpdateAvailable(details) {
  console.log(details.version);
  // Proceed to upgrade the add-on
  browser.runtime.reload();
}

browser.runtime.onUpdateAvailable.addListener(handleUpdateAvailable);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onUpdateAvailable) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onUpdateAvailable>

runtime.onMessageExternal
=========================



Use this event to listen for messages from other extensions or web pages.

 By default, an extension can receive messages from any other extension. However, the [`externally_connectable`](../../manifest.json/externally_connectable) manifest key can be used to limit communication to specific extensions and enable communication with websites.

 To send a message that is received by the `onMessageExternal` listener, use [`runtime.sendMessage()`](sendmessage), passing the ID of the recipient in the `extensionId` parameter.

 Along with the message itself, the listener is passed:

 * a `sender` object giving details about the message sender
* a `sendResponse` function that the listener can use to send a response back to the sender.

 This API can't be used in a content script.



Syntax
------




```
browser.runtime.onMessageExternal.addListener()
browser.runtime.onMessageExternal.removeListener(listener)
browser.runtime.onMessageExternal.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that is called when this event occurs. The function is passed these arguments:

  `message`  `object`. The message itself. This is a JSON-ifiable object.

  `sender`  A [`runtime.MessageSender`](messagesender) object representing the sender of the message.

  `sendResponse`  A function to call, at most once, to send a response to the message. The function takes a single argument, which may be any JSON-ifiable object. This argument is passed back to the message sender.

 If you have more than one `onMessageExternal` listener in the same document, then only one may send a response.

 To send a response synchronously, call `sendResponse` before the listener function returns. To send a response asynchronously, do one of these:

 * keep a reference to the `sendResponse` argument and return `true` from the listener function. You can then call `sendResponse` after the listener function has returned.
* return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) from the listener function and resolve the promise when the response is ready.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onMessageExternal` | 26 | 79 | 54 | ? | 15 | 15.4Since Safari 15.4, this event is also fired in response to a message from webpages allowed in [`externally_connectable`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable).14This event is only fired in response to a message from an extension's containing app, not webpages nor other extensions. | ? | ? | 54 | ? | 15.4Since Safari 15.4, this event is also fired in response to a message from webpages allowed in [`externally_connectable`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable).15This event is only fired in response to a message from an extension's containing app, not webpages nor other extensions. | ? |
| `return_promise` | No | No | Yes | ? | No | 15.4 | ? | ? | Yes | ? | 15.4 | ? |


Examples
--------



In this example the extension "[blue@mozilla.org](mailto:blue@mozilla.org)" sends a message to the extension "[red@mozilla.org](mailto:red@mozilla.org)":

 
```
// sender: browser.runtime.id === "blue@mozilla.org"

// Send a message to the extension whose ID is "red@mozilla.org"
browser.runtime.sendMessage(
    "red@mozilla.org",
    "my message"
  );

```
 
```
// recipient: browser.runtime.id === "red@mozilla.org"

function handleMessage(message, sender) {
  // check that the message is from "blue@mozilla.org"
  if (sender.id === "blue@mozilla.org") {
    // process message
  }
}

browser.runtime.onMessageExternal.addListener(handleMessage);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessageExternal) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessageExternal>

runtime.getBrowserInfo()
========================



Returns information about the browser in which the extension is installed.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingInfo = browser.runtime.getBrowserInfo()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object which has the following properties:

  `name`  string value representing the browser name, for example "Firefox".

  `vendor`  string value representing the browser's vendor, for example "Mozilla".

  `version`  string representing the browser's version, for example "51.0" or "51.0a2".

  `buildID`  string representing the specific build of the browser, for example "20161018004015".

  
Examples
--------



Get and log the browser's name:

 
```
function gotBrowserInfo(info) {
  console.log(info.name);
}

let gettingInfo = browser.runtime.getBrowserInfo();
gettingInfo.then(gotBrowserInfo);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBrowserInfo` | No | No | 51 | ? | No | No | ? | ? | 51 | ? | No | ? |


 **Note:** Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBrowserInfo>

runtime.getPackageDirectoryEntry()
==================================



Returns a `DirectoryEntry` object representing the package directory.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingEntry = browser.runtime.getPackageDirectoryEntry()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a `DirectoryEntry` object representing the package directory.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPackageDirectoryEntry` | 29 | 79 | No | ? | 16 | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function gotDirectoryEntry(directoryEntry) {
  console.log(directoryEntry);
}

let gettingEntry = browser.runtime.getPackageDirectoryEntry();
gettingEntry.then(gotDirectoryEntry);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#method-getPackageDirectoryEntry) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getPackageDirectoryEntry>

runtime.onBrowserUpdateAvailable
================================



**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

 Fired when an update for the browser is available, but it isn't installed immediately because a browser restart is required.



Syntax
------




```
browser.runtime.onBrowserUpdateAvailable.addListener(listener)
browser.runtime.onBrowserUpdateAvailable.removeListener(listener)
browser.runtime.onBrowserUpdateAvailable.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that will be called when this event occurs.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBrowserUpdateAvailable` | 27 | 79 | No | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------



Listen for this event:

 
```
function handleBrowserUpdateAvailable() {
  // handle event
}

browser.runtime.onBrowserUpdateAvailable.addListener(handleBrowserUpdateAvailable);

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onBrowserUpdateAvailable) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onBrowserUpdateAvailable>

runtime.onConnectExternal
=========================



Fired when an extension receives a connection request from a different extension.

 To send a message which will be received by the `onConnectExternal` listener, use [`runtime.connect()`](connect), passing the ID of the recipient in the `extensionId` parameter.

 The listener is passed a [`runtime.Port`](port) object which it can then use to send and receive messages. The `Port` object also contains a `sender` property, which is a [`runtime.MessageSender`](messagesender) object, and which the recipient can use to check the sender's ID.



Syntax
------




```
browser.runtime.onConnectExternal.addListener(listener)
browser.runtime.onConnectExternal.removeListener(listener)
browser.runtime.onConnectExternal.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `port`  A [`runtime.Port`](port) object connecting the current script to the other extension it is connecting to.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onConnectExternal` | 26 | 79 | 54 | ? | 15 | No | ? | ? | 54 | ? | No | ? |


Examples
--------



In this example the extension Hansel connects to the extension Gretel:

 
```
console.log("connecting to Gretel");
let myPort = browser.runtime.connect(
  "gretel@mozilla.org"
);

myPort.onMessage.addListener((message) => {
  console.log(`From Gretel: ${message.content}`);
});

browser.browserAction.onClicked.addListener(() => {
  myPort.postMessage({content: "Hello from Hansel"});
});

```
 Gretel listens for the connection and checks that the sender is really Hansel:

 
```
let portFromHansel;

browser.runtime.onConnectExternal.addListener((port) => {
  console.log(port);
  if (port.sender.id === "hansel@mozilla.org") {
    console.log("connection attempt from Hansel");
    portFromHansel = port;
    portFromHansel.onMessage.addListener((message) => {
      console.log(`From Hansel: ${message.content}`);
    });
  }
});

browser.browserAction.onClicked.addListener(() => {
   portFromHansel.postMessage({content: "Message from Gretel"});
});

```
  **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#event-onConnectExternal) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnectExternal>

tabs.TabStatus
==============


Indicates whether the tab has finished loading.


Type
----


Values of this type are strings. Possible values are: `"loading"` and `"complete"`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TabStatus` | 5 | 14 | 45 | ? | 15 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-TabStatus) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/TabStatus>

browserAction.ImageDataType
===========================


Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).


Type
----


An [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#type-ImageDataType) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/ImageDataType>

browserAction.getTitle()
========================



Gets the browser action's title.

 Just as you can set the title on a per-tab basis using [`browserAction.setTitle()`](settitle), so you can retrieve a tab-specific title by passing the tab's ID into this function.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingTitle = browser.browserAction.getTitle(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specify the tab to get the title from.

  
`windowId` Optional
  `integer`. Specify the window to get the title from.

     * If `windowId` and `tabId` are both supplied, the function fails and the promise it returns is rejected.
* If `windowId` and `tabId` are both omitted, the global title is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the browser action's title.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTitle` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 55 | ? | 15The API exists, but the title not visible in the UI. | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code switches the title between "this" and "that" each time the user clicks the browser action:

 
```
function toggleTitle(title) {
  if (title === "this") {
    browser.browserAction.setTitle({ title: "that" });
  } else {
    browser.browserAction.setTitle({ title: "this" });
  }
}

browser.browserAction.onClicked.addListener(() => {
  let gettingTitle = browser.browserAction.getTitle({});
  gettingTitle.then(toggleTitle);
});

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-getTitle) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getTitle>

browserAction.setPopup()
========================


Sets the HTML document that will be opened as a popup when the user clicks on the browser action's icon. Tabs without a specific popup will inherit the global popup, which defaults to the [`default_popup`](../../manifest.json/browser_action) specified in the manifest.


Syntax
------



```
browser.browserAction.setPopup(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Sets the popup only for a specific tab. The popup is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the popup only for the specified window.

  `popup`  `string` or `null`. The HTML file to show in a popup, specified as a URL.

 This can point to a file packaged within the extension (for example, created using [`extension.getURL`](../extension/geturl)), or a remote document (e.g. `https://example.org/`).

 If an empty string (`""`) is passed here, the popup is disabled, and the extension will receive [`browserAction.onClicked`](onclicked) events.

 If `popup` is `null`:

 * If `tabId` is specified, removes the tab-specific popup so that the tab inherits the global popup.
* If `windowId` is specified, removes the window-specific popup so that the window inherits the global popup.
* If `tabId` and `windowId` are both omitted, reverts the global popup to the default value.

     * If `windowId` and `tabId` are both supplied, the function fails and the popup is not set.
* If `windowId` and `tabId` are both omitted, the global popup is set.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setPopup` | Yes | 14 | 4545–58Tab-specific popups are not cleared when a new page is loaded. | ? | Yes | 14 | ? | ? | 5757–58Tab-specific popups are not cleared when a new page is loaded. | ? | 15 | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



This code adds a pair of context menu items that you can use to switch between two popups. Note that you'll need the "contextMenus" [permission](../../manifest.json/permissions) set in the extension's manifest to create context menu items.

 
```
function onCreated() {
  if (browser.runtime.lastError) {
    console.log("error creating item:", browser.runtime.lastError);
  } else {
    console.log("item created successfully");
  }
}

browser.contextMenus.create(
  {
    id: "popup-1",
    type: "radio",
    title: "Popup 1",
    contexts: ["all"],
    checked: true,
  },
  onCreated
);

browser.contextMenus.create(
  {
    id: "popup-2",
    type: "radio",
    title: "Popup 2",
    contexts: ["all"],
    checked: false,
  },
  onCreated
);

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "popup-1") {
    browser.browserAction.setPopup({ popup: "/popup/popup1.html" });
  } else if (info.menuItemId === "popup-2") {
    browser.browserAction.setPopup({ popup: "/popup/popup2.html" });
  }
});

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setPopup) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setPopup>

browserAction.getPopup()
========================



Gets the HTML document set as the popup for this browser action.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingPopup = browser.browserAction.getPopup(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. The tab whose popup to get.

  
`windowId` Optional
  `integer`. The windows whose popup to get.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global popup is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the URL for the popup's document. This will be a fully qualified URL, such as `moz-extension://d1d8a2eb-fe60-f646-af30-a866c5b39942/popups/popup2.html`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPopup` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 57 | ? | 15 | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Get the popup's URL:

 
```
function gotPopup(popupURL) {
  console.log(popupURL);
}

let gettingPopup = browser.browserAction.getPopup({});
gettingPopup.then(gotPopup);

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-getPopup) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getPopup>

windows.WINDOW\_ID\_CURRENT
===========================


`browser.windows.WINDOW_ID_CURRENT` is a value that can be used as a `windowId` parameter in some APIs to represent the current window.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `WINDOW_ID_CURRENT` | 18 | 14 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#property-WINDOW_ID_CURRENT) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/WINDOW_ID_CURRENT>

tabs.WindowType
===============


The type of window that hosts this tab.


Type
----



Values of this type are strings. Possible values are:

 * **"normal"**
* **"popup"**
* **"panel"**
* **"devtools"**


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `WindowType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-WindowType) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/WindowType>

browserAction.ColorArray
========================


Type
----



An `array` of four integers in the range 0-255, defining an RGBA color. The four values specify the following channels:

 1. Red
2. Green
3. Blue
4. Alpha (opacity).

 For example, opaque red is `[255, 0, 0, 255]`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ColorArray` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#type-ColorArray) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/ColorArray>

browserAction.openPopup()
=========================



Open the browser action's popup.

 You can only call this function from inside the handler for a [user action](../../user_actions).



Syntax
------



```
browser.browserAction.openPopup()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openPopup` | 67 | 79 | 57["Since Firefox 108, user interaction is no longer required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)).", "Support for the `windowId` parameter was added in Firefox 108."] | ? | 54 | 16 | ? | ? | 79 | ? | 16 | ? |


Examples
--------



Open the popup when the user selects a context menu item:

 
```
browser.menus.create({
  id: "open-popup",
  title: "open popup",
  contexts: ["all"],
});

browser.menus.onClicked.addListener(() => {
  browser.browserAction.openPopup();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/openPopup>

browserAction.getBadgeText()
============================



Gets the browser action's badge text.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingText = browser.browserAction.getBadgeText(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specifies the tab from which to get the badge text.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge text.

     * If windowId and tabId are both supplied, the function fails.
* If windowId and tabId are both omitted, the global badge text is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the badge text.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeText` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the badge text:

 
```
function gotBadgeText(text) {
  console.log(text);
}

let gettingBadgeText = browser.browserAction.getBadgeText({});
gettingBadgeText.then(gotBadgeText);

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-getBadgeText) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getBadgeText>

browserAction.getBadgeBackgroundColor()
=======================================



Gets the background color of the browser action's badge.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.browserAction.getBadgeBackgroundColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specifies the tab to get the badge background color from.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge background color.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge background color is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the retrieved color as a [`browserAction.ColorArray`](colorarray).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeBackgroundColor` | Yes | 14 | 45 | ? | Yes | 14Always returns a red `ColorArray`. | ? | ? | 79 | ? | 15Always returns a red `ColorArray`. | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the badge's background color:

 
```
function onGot(color) {
  console.log(color);
}

function onFailure(error) {
  console.log(error);
}

browser.browserAction.getBadgeBackgroundColor({}).then(onGot, onFailure);

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-getBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getBadgeBackgroundColor>

browserAction.enable()
======================


Enables the browser action for a tab. By default, browser actions are enabled for all tabs.


Syntax
------



```
browser.browserAction.enable(
  tabId // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The id of the tab for which you want to enable the browser action.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `enable` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



Disable the browser action when clicked, and re-enable it every time a new tab is opened:

 
```
browser.tabs.onCreated.addListener(() => {
  browser.browserAction.enable();
});

browser.browserAction.onClicked.addListener(() => {
  browser.browserAction.disable();
});

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-enable) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/enable>

browserAction.disable()
=======================


Disables the browser action for a tab, meaning that it cannot be clicked when that tab is active.


Syntax
------



```
browser.browserAction.disable(
  tabId // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The id of the tab for which you want to disable the browser action.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `disable` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



Disable the browser action when clicked, and re-enable it every time a new tab is opened:

 
```
browser.tabs.onCreated.addListener(() => {
  browser.browserAction.enable();
});

browser.browserAction.onClicked.addListener(() => {
  browser.browserAction.disable();
});

```
 Disable the browser action only for the active tab:

 
```
browser.browserAction.onClicked.addListener((tab) => {
  browser.browserAction.disable(tab.id);
});

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-disable) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/disable>

browserAction.setBadgeTextColor()
=================================


Sets the text color for the browser action's badge. Tabs without a specific badge text color will inherit the global badge text color.


Syntax
------



```
browser.browserAction.setBadgeTextColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  `color`  The color, specified as one of:

 * a string: any CSS [<color>](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) value, for example `"red"`, `"#FF0000"`, or `"rgb(255,0,0)"`. If the string is not a valid color, the returned promise will be rejected and the text color won't be altered.
* a `[`browserAction.ColorArray`](colorarray)` object.
* `null`. If a `tabId` is specified, it removes the tab-specific badge text color so that the tab inherits the global badge text color. Otherwise it reverts the global badge text color to the default value.

  
`tabId` Optional
  `integer`. Sets the badge text color only for the given tab. The color is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the badge text color only for the given tab.

     * If `windowId` and `tabId` are both supplied, the function fails and the color is not set.
* If `windowId` and `tabId` are both omitted, the global badge text color is set instead.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeTextColor` | No | No | 63 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



A badge text color that starts off as red, and turns green when the browser action is clicked:

 
```
browser.browserAction.setBadgeText({ text: "1234" });
browser.browserAction.setBadgeTextColor({ color: "red" });

browser.browserAction.onClicked.addListener(() => {
  browser.browserAction.setBadgeTextColor({ color: "green" });
});

```
 Set the badge text color only for the active tab:

 
```
browser.browserAction.setBadgeText({ text: "1234" });
browser.browserAction.setBadgeTextColor({ color: "red" });

browser.browserAction.onClicked.addListener((tab) => {
  browser.browserAction.setBadgeTextColor({
    color: "green",
    tabId: tab.id,
  });
});

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-setBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setBadgeTextColor>

browserAction.getBadgeTextColor()
=================================



Gets the text color for the browser action's badge.

 From Firefox 63, unless the badge text color is explicitly set using [`browserAction.setBadgeTextColor()`](setbadgetextcolor), then the badge text color will be automatically set to black or white so as to maximize contrast with the specified badge background color. For example, if you set the badge background color to white, the default badge text color will be set to black, and vice versa.

 Other browsers always use a white text color.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.browserAction.getBadgeTextColor(
  details // object
)

```
### Parameters



 `details`  `object`.

  
`tabId` Optional
  `integer`. Specifies the tab to get the badge text color from.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge text color.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge text color is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the retrieved color as a [`browserAction.ColorArray`](colorarray).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeTextColor` | No | No | 63 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Log the badge's text color:

 
```
function onGot(color) {
  console.log(color);
}

function onFailure(error) {
  console.log(error);
}

browser.browserAction.getBadgeTextColor({}).then(onGot, onFailure);

```
  **Note:** This API is based on Chromium's [`chrome.browserAction`](https://developer.chrome.com/docs/extensions/reference/browserAction/#method-getBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/getBadgeTextColor>

storage.StorageArea
===================


StorageArea is an object representing a storage area.


Type
----


Values of this type are objects.

Methods
-------


 [`storage.StorageArea.get()`](storagearea/get)  Retrieves one or more items from the storage area.

  [`storage.StorageArea.getBytesInUse()`](storagearea/getbytesinuse)  Gets the amount of storage space (in bytes) used one or more items being stored in the storage area.

  [`storage.StorageArea.set()`](storagearea/set)  Stores one or more items in the storage area. If an item already exists, its value will be updated.

  [`storage.StorageArea.setAccessLevel()`](storagearea/setaccesslevel)  Sets the access level for the storage area.

  [`storage.StorageArea.remove()`](storagearea/remove)  Removes one or more items from the storage area.

  [`storage.StorageArea.clear()`](storagearea/clear)  Removes all items from the storage area.

  Events
------


 [`storage.StorageArea.onChanged`](storagearea/onchanged)  Fires when one or more items in the storage area change.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `StorageArea` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `clear` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `get` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `getBytesInUse` | Yes | 14 | 78Only supported by the `sync` storage area. | ? | 33 | 14 | ? | ? | No | ? | 15 | ? |
| `onChanged` | 73 | Yes | 101 | ? | Yes | 14 | ? | ? | 101 | ? | 15 | ? |
| `remove` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `set` | Yes | 14storage is limited to 1MB per value. | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `setAccessLevel` | 96Only supported for the session storage area. | 96Only supported for the session storage area. | No | ? | 82Only supported for the session storage area. | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#type-StorageArea) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea>

storage.StorageChange
=====================


`StorageChange` is an object representing a change to a storage area.


Type
----



`StorageChange` objects contain the following properties:

  
`oldValue` Optional
  The old value of the item, if there was an old value. This can be any data type.

  
`newValue` Optional
  The new value of the item, if there is a new value. This can be any data type.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `StorageChange` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#type-StorageChange) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageChange>

storage.session
===============



 Represents the `session` storage area. Items in `session` storage are stored in memory for the duration of the browser session and are not persisted to disk. By default, it's not exposed to content scripts, but this behavior can be changed through [`storage.session.setAccessLevel()`](storagearea/setaccesslevel). 

 The amount of data that an extension can store in the session storage area is limited to 10 MB, unless stated otherwise in the [browser compatibility table](#browser_compatibility).

 When the browser stops, all session storage is cleared. When the extension is uninstalled, its associated session storage is cleared.



Methods
-------



The `session` object implements the methods defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.session.get()`](storagearea/get)  Retrieves one or more items from the storage area.

  [`storage.session.getBytesInUse()`](storagearea/getbytesinuse)  Gets the amount of storage space (in bytes) used for one or more items in the storage area.

  [`storage.session.set()`](storagearea/set)  Stores one or more items in the storage area. If the item exists, its value is updated.

  [`storage.session.setAccessLevel()`](storagearea/setaccesslevel)  Sets the access level for the storage area.

  [`storage.session.remove()`](storagearea/remove)  Removes one or more items from the storage area.

  [`storage.session.clear()`](storagearea/clear)  Removes all items from the storage area.

  
Events
------



The `session` object implements the events defined on the [`storage.StorageArea`](storagearea) type:

  [`storage.session.onChanged`](storagearea/onchanged)  Fires when one or more items in the storage area change.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `session` | 102Before version 112, storage quota limits were 1MB. | 102Before version 112, storage quota limits were 1MB. | No | ? | 88Before version 98, storage quota limits were 1MB. | 16.4 | ? | ? | No | ? | 16.4 | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#property-session) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/session>

extensionTypes.RunAt
====================


The soonest that the JavaScript or CSS will be injected into the tab.


Type
----



Values of this type are strings. Possible values are: `"document_start"`, `"document_end"`, `"document_idle"`.

 * `"document_start"`: corresponds to `loading`. The DOM is still loading.
* `"document_end"`: corresponds to `interactive`. The DOM has finished loading, but resources such as scripts and images may still be loading.
* `"document_idle"`: corresponds to `complete`. The document and all its resources have finished loading.

 The default value is `"document_idle"`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RunAt` | 20This feature is supported but not exposed through the 'extensionTypes' object. | 79This feature is supported but not exposed through the 'extensionTypes' object. | 45 | ? | 15This feature is supported but not exposed through the 'extensionTypes' object. | 14["This feature is supported but not exposed through the 'extensionTypes' object.", "'document\_idle' and 'document\_end' are treated the same."] | ? | ? | 48 | ? | 15["This feature is supported but not exposed through the 'extensionTypes' object.", "'document\_idle' and 'document\_end' are treated the same."] | ? |


 **Note:** This API is based on Chromium's [`chrome.extensionTypes`](https://developer.chrome.com/docs/extensions/reference/extensionTypes/#type-RunAt) API. This documentation is derived from [`extension_types.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/extension_types.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes/RunAt>

scripting.insertCSS()
=====================



Injects CSS into a page.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Safari and Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the target's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 You can only inject CSS into pages whose URL can be expressed using a [match pattern](../../match_patterns): meaning, its scheme must be one of "http", "https", or "file". This means that you can't inject CSS into any of the browser's built-in pages, such as about:debugging, about:addons, or the page that opens when you open a new empty tab.

  **Note:** Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.

  The inserted CSS can be removed by calling [`scripting.removeCSS()`](removecss).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
await browser.scripting.insertCSS(
  details     // object
)

```
### Parameters


 `details`  An object describing the CSS to insert and where to insert it. It contains the following properties:

  
`css` Optional
  `string`. A string containing the CSS to inject. Either `css` or `files` must be specified.

  
`files` Optional
  `array` of `string`. The path of a CSS files to inject, relative to the extension's root directory. Either `files` or `css` must be specified.

  
`origin` Optional
  `string`. The style origin for the injection, either `USER` or `AUTHOR`. Defaults to `AUTHOR`.

  `target`  [`scripting.InjectionTarget`](injectiontarget). Details specifying the target to inject the CSS into.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with no arguments when all the CSS is inserted. If any error occurs, the promise is rejected.

Examples
--------



This example inserts CSS taken from a string into the active tab.

 
```
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.insertCSS({
      target: {
        tabId: tab.id,
      },
      css: `body { border: 20px dotted pink; }`,
    });
  } catch (err) {
    console.error(`failed to insert CSS: ${err}`);
  }
});

```
 This example inserts CSS loaded from a file (packaged with the extension) called `"content-style.css"`:

 
```
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.insertCSS({
      target: {
        tabId: tab.id,
      },
      files: ["content-style.css"],
    });
  } catch (err) {
    console.error(`failed to insert CSS: ${err}`);
  }
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `insertCSS` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `origin` | 88 | 88 | 102 | ? | 74 | No | ? | ? | 102 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-insertCSS) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/insertCSS>

scripting.removeCSS()
=====================



Removes a CSS stylesheet injected by a call to [`scripting.insertCSS()`](insertcss).

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Safari and Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
await browser.scripting.removeCSS(
  details       // object
)

```
### Parameters


 `details`  An object describing the CSS to remove and where to remove it from. It contains the following properties:

  
`css` Optional
  `string`. A string containing the CSS to inject. Either `css` or `files` must be specified and must match the stylesheet inserted through [`scripting.insertCSS()`](insertcss).

  
`files` Optional
  `array` of `string`. The path of a CSS files to inject, relative to the extension's root directory. Either `files` or `css` must be specified and must match the stylesheet inserted through [`scripting.insertCSS()`](insertcss).

  
`origin` Optional
  `string`. The style origin for the injection, either `USER` or `AUTHOR`. Defaults to `AUTHOR`. Must match the origin of the stylesheet inserted through [`scripting.insertCSS()`](insertcss).

  `target`  [`scripting.InjectionTarget`](injectiontarget). Details specifying the target to remove the CSS from.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with no arguments when all the CSS is removed. If any error occurs, the promise is rejected. Attempts to remove non-existent stylesheets are ignored.

Examples
--------



This example adds some CSS using [`scripting.insertCSS`](insertcss), then removes it again when the user clicks a browser action:

 
```
// Assuming some style has been injected previously with the following code:
//
// await browser.scripting.insertCSS({
// target: {
// tabId: tab.id,
// },
// css: "\* { background: #c0ffee }",
// });
//
// We can remove it when a user clicked an extension button like this:
browser.action.onClicked.addListener(async (tab) => {
  try {
    await browser.scripting.removeCSS({
      target: {
        tabId: tab.id,
      },
      css: "\* { background: #c0ffee }",
    });
  } catch (err) {
    console.error(`failed to remove CSS: ${err}`);
  }
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeCSS` | 88 | 88 | 102 | ? | 74 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `origin` | 88 | 88 | 102 | ? | 74 | No | ? | ? | 102 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-removeCSS) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/removeCSS>

tabs.TAB\_ID\_NONE
==================


A special ID value given to tabs that are not browser tabs (for example, tabs in devtools windows).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TAB_ID_NONE` | 46 | 14 | 45 | ? | 33 | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#property-TAB_ID_NONE) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/TAB_ID_NONE>

runtime.PlatformInfo
====================


An object containing information about the current platform.


Type
----



Values of this type are objects, which contain the following properties:

  `os`  [`runtime.PlatformOs`](platformos). The platform's operating system.

  `arch`  [`runtime.PlatformArch`](platformarch). The platform's processor architecture.

  `nacl_arch`  [`runtime.PlatformNaclArch`](platformnaclarch). The native client architecture. This may be different from `arch` on some platforms.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `PlatformInfo` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `nacl_arch` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformInfo) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/PlatformInfo>

browserAction.isEnabled()
=========================



Returns `true` if the browser action is enabled.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingIsEnabled = browser.browserAction.isEnabled(
  details // object
)

```
### Parameters



 `details`  `object`. An object optionally containing the `tabId` or `windowId` to check.

  
`tabId` Optional
  `integer`. ID of a tab to check.

  
`windowId` Optional
  `integer`. ID of a window to check.

     * If windowId and tabId are both supplied, the function fails.
* If windowId and tabId are both omitted, the global enabled/disabled status is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the extension's browser action is enabled, and `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isEnabled` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |
| `details_windowId_parameter` | No | No | 62 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Check the global state:

 
```
browser.browserAction.isEnabled({}).then((result) => {
  console.log(result);
});

```
 Check the state of the currently active tab:

 
```
async function enabledInActiveTab() {
  let tabs = await browser.tabs.query({
    currentWindow: true,
    active: true,
  });
  let enabled = await browser.browserAction.isEnabled({
    tabId: tabs[0].id,
  });
  console.log(enabled);
}

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/isEnabled>

tabs.MutedInfo
==============


This object contains a boolean indicating whether the tab is muted, and the reason for the last state change.


Type
----



Values of this type are objects. They contain the following properties:

  
`extensionId` Optional
  `string`. The ID of the extension that last changed the muted state. Not set if an extension was not the reason the muted state last changed.

  `muted`  `boolean`. Whether the tab is currently muted. Equivalent to whether the muted audio indicator is showing.

  
`reason` Optional
  [`tabs.MutedInfoReason`](mutedinforeason). The reason the tab was muted or unmuted. Not set if the tab's muted state has never been changed.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MutedInfo` | 46 | 79 | 47 | ? | 33 | 14`reason` and `extensionId` will not be populated. | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-MutedInfo) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/MutedInfo>

windows.WindowType
==================


The type of browser window this is.


Type
----



Values of this type are `strings`. Possible values are:

 * `"normal"`
* `"popup"`
* `"panel"`
* `"devtools"`


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `WindowType` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `app` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `devtools` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `panel` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#type-WindowType) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/WindowType>

tabs.ZoomSettings
=================


Defines zoom settings for a tab: [`mode`](zoomsettingsmode), [`scope`](zoomsettingsscope), and default zoom factor.


Type
----



Values of this type are objects. They contain the following properties:

  
`defaultZoomFactor` Optional
  `number`. The default zoom level for the current tab. Note that this is only used in [`tabs.getZoomSettings`](getzoomsettings).

  
`mode` Optional
  [`tabs.ZoomSettingsMode`](zoomsettingsmode). Defines whether zoom changes are handled by the browser, by the extension, or are disabled.

  
`scope` Optional
  [`tabs.ZoomSettingsScope`](zoomsettingsscope). Defines whether zoom changes will persist for the page's origin, or only take effect in this tab.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ZoomSettings` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |
| `defaultZoomFactor` | 43 | 79 | 11045Returns 1, regardless of the default zoom factor setting. | ? | 30 | No | ? | ? | No | ? | No | ? |
| `mode` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |
| `scope` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-ZoomSettings) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/ZoomSettings>

extensionTypes.ImageDetails
===========================


Details about the format, quality, area and scale of a captured image.


Type
----



Values of this type are objects. They contain the following properties:

  
`format` Optional
  [`extensionTypes.ImageFormat`](imageformat). The format of the resulting image. Default is `"png"`.

  
`quality` Optional
  `integer`. When format is `"jpeg"`, this controls the quality of the resulting image. It is a number between 0 and 100, which is converted to a value between 0 and 1 and then used as the `encoderOptions` argument to [`HTMLCanvasElement.toDataURL()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL). If it is omitted, 92 is used. As quality is decreased, the resulting image will have more visual artifacts, and the number of bytes needed to store it will decrease. This value is ignored for PNG images.

  
`rect` Optional
  An `object` specifying the area of the document to capture, in CSS pixels, relative to the page. All properties default to `0`. The properties are:

 * `x`: The coordinate of the left side of the rectangle.
* `y`: The coordinate of the top side of the rectangle.
* `width`: The width of the rectangle.
* `height`: The height of the rectangle.

 This option was introduced in Firefox 82. If omitted, the currently visible viewport is captured.

  
`scale` Optional
  `number`. The scale to render at, defaults to [`devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio). This option was introduced in Firefox 82.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDetails` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `rect` | No | No | 82 | ? | No | No | ? | ? | 82 | ? | No | ? |
| `scale` | No | No | 82 | ? | No | No | ? | ? | 82 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extensionTypes`](https://developer.chrome.com/docs/extensions/reference/extensionTypes/#type-ImageDetails) API. This documentation is derived from [`extension_types.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/extension_types.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes/ImageDetails>

tabs.saveAsPDF()
================



Saves the current page as a PDF file. This will open a dialog, supplied by the underlying operating system, asking the user where they want to save the PDF file.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let saving = browser.tabs.saveAsPDF(
  pageSettings   // object
)

```
### Parameters


 `pageSettings`  `object`. Settings for the saved page, as a [`tabs.PageSettings`](pagesettings) object. This object must be given, but all its properties are optional. Any properties not specified here will get the default values listed in the [`PageSettings`](pagesettings) documentation.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a status string when the dialog has closed. The string may be any of:

 * "saved"
* "replaced"
* "canceled"
* "not\_saved"
* "not\_replaced"


Examples
--------



In this example a background script listens for a click on a [browser action](../../anatomy_of_a_webextension#browser_actions_2), then tries to save the currently active tab as a PDF file, then logs the result:

 
```
browser.browserAction.onClicked.addListener(() => {
  browser.tabs.saveAsPDF({})
    .then((status) => {
      console.log(status);
    });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `saveAsPDF` | No | No | 8156–81This function does not work on macOS. | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/saveAsPDF>

tabs.ZoomSettingsMode
=====================


Defines how zoom changes are handled. Extensions can pass this value into [`tabs.setZoomSettings()`](setzoomsettings) to control how the browser handles attempts to change zoom settings for a tab. Defaults to "automatic".


Type
----



Values of this type are strings. Possible values are:

  "automatic"  Zoom changes are handled normally by the browser.

  "disabled"  Disables all zooming in the tab. The tab will revert to the default zoom level, and all attempted zoom changes will be ignored.

  "manual"  The extension will handle zoom changes itself, by listening for the [`tabs.onZoomChange`](onzoomchange) event and scaling the page accordingly. This mode does not support `per-origin` zooming: it will ignore the `scope` [`zoom setting`](zoomsettings) and always use `per-tab`.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ZoomSettingsMode` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-ZoomSettingsMode) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/ZoomSettingsMode>

tabs.MutedInfoReason
====================


Specifies the reason a tab was muted or unmuted.


Type
----



Values of this type are strings. Possible values are:

  "capture"  Tab capture started, forcing a muted state change.

  "extension"  An extension set the muted state. If this is the reason, `extensionId` in [`tabs.mutedInfo`](mutedinfo) will contain the ID of the extension responsible.

  "user"  The user set the muted state.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MutedInfoReason` | 46 | 79 | 47 | ? | 33 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-MutedInfoReason) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/MutedInfoReason>

tabs.PageSettings
=================



The type `tabs.PageSettings` is used to control how a tab is rendered as a PDF by the [`tabs.saveAsPDF()`](saveaspdf) method.

 All its properties are optional.

 For setting headers and footers, you can include certain special characters in the strings you supply. These will be replaced in the rendered output as follows:

 * "&P": the page number, like "2"
* "&PT": the page number and the total number of pages, like "2 of 3"
* "&D": the current date/time
* "&T": the page title
* "&U": the page URL



Type
----



Values of this type are objects. They contain the following properties:

  
`edgeBottom` Optional
  `number`. The spacing between the bottom of the footers and the bottom edge of the paper (inches). Default: 0.

  
`edgeLeft` Optional
  `number`. The spacing between the left header/footer and the left edge of the paper (inches). Default: 0.

  
`edgeRight` Optional
  `number`. The spacing between the right header/footer and the left edge of the paper (inches). Default: 0.

  
`edgeTop` Optional
  `number`. The spacing between the top of the headers and the top edge of the paper (inches). Default: 0

  
`footerCenter` Optional
  `string`. The text for the page's center footer. Default: ''.

  
`footerLeft` Optional
  `string`. The text for the page's left footer. Default: '&PT'.

  
`footerRight` Optional
  `string`. The text for the page's right footer. Default: '&D'.

  
`headerCenter` Optional
  `string`. The text for the page's center header. Default: ''.

  
`headerLeft` Optional
  `string`. The text for the page's left header. Default: '&T'.

  
`headerRight` Optional
  `string`. The text for the page's right header. Default: '&U'.

  
`marginBottom` Optional
  `number`. The margin between the page content and the bottom edge of the paper (inches). Default: 0.5.

  
`marginLeft` Optional
  `number`. The margin between the page content and the left edge of the paper (inches). Default: 0.5.

  
`marginRight` Optional
  `number`. The margin between the page content and the right edge of the paper (inches). Default: 0.5.

  
`marginTop` Optional
  `number`. The margin between the page content and the top edge of the paper (inches). Default: 0.5.

  
`orientation` Optional
  `integer`. Page orientation: 0 means "portrait", 1 means "landscape". Default: 0.

  
`paperHeight` Optional
  `number`. The paper height in paper size units. Default: 11.0.

  
`paperSizeUnit` Optional
  `integer`. The paper size unit: 0 = inches, 1 = millimeters. Default: 0.

  
`paperWidth` Optional
  `number`. The paper width in paper size units. Default: 8.5.

  
`scaling` Optional
  `number`. Page content scaling factor. 1 means 100% or normal size. Default: 1.

  
`showBackgroundColors` Optional
  `boolean`. Whether the page background colors should be shown. Default: false.

  
`showBackgroundImages` Optional
  `boolean`. Whether the page background images should be shown. Default: false.

  
`shrinkToFit` Optional
  `boolean`. Whether the page content should shrink to fit the page width (overrides scaling). Default: true.

  
`toFileName` Optional
  `string`. The name of the file the PDF is saved in, with or without the `.pdf` extension.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `PageSettings` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `edgeBottom` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `edgeLeft` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `edgeRight` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `edgeTop` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `fileName` | No | No | 75 | ? | No | No | ? | ? | No | ? | No | ? |
| `footerCenter` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `footerLeft` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `footerRight` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `headerCenter` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `headerLeft` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `headerRight` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `marginBottom` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `marginLeft` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `marginRight` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `marginTop` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `orientation` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `paperHeight` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `paperSizeUnit` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `paperWidth` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `scaling` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `showBackgroundColors` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `showBackgroundImages` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `shrinkToFit` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/PageSettings>

tabs.ZoomSettingsScope
======================


Defines whether zoom changes will persist for the page's origin, or only take effect in this tab. This defaults to `per-origin` when [`tabs.zoomSettingsMode`](zoomsettingsmode) is "automatic", and is always `per-tab` otherwise.


Type
----



Values of this type are strings. Possible values are:

  "per-origin"  All other tabs with the same origin as this tab will have the zoom changes applied to them. This scope is only available if [`tabs.zoomSettingsMode`](zoomsettingsmode) is "automatic".

  "per-tab"  Zoom changes only take effect in this tab, and zoom changes in other tabs will not affect the zooming of this tab. Also:

 * in Firefox the zoom level persists across page loads and navigation within the tab.
* in Chrome-based browsers zoom changes are reset on navigation; navigating a tab will always load pages with their per-origin zoom factors.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ZoomSettingsScope` | 38 | 79 | 45 | ? | 25 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#type-ZoomSettingsScope) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/ZoomSettingsScope>

tabs.captureTab()
=================



Creates a data URL encoding the image of an area of the given tab. You must have the `<all_urls>` [permission](../../manifest.json/permissions) to use this method.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let capturing = browser.tabs.captureTab(
  tabId,               // optional integer
  options              // optional extensionTypes.ImageDetails
)

```
### Parameters


 
`tabId` Optional
  `integer`. ID of the tab to capture. Defaults to the active tab in the current window.

  
`options` Optional
  [`extensionTypes.ImageDetails`](../extensiontypes/imagedetails).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a data URL which encodes the captured image. May be assigned to the 'src' property of an HTML Image element for display. If any error occurs the promise will be rejected with an error message.

Examples
--------



Capture an image of the active tab in the current window, with default settings:

 
```
function onCaptured(imageUri) {
  console.log(imageUri);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener(() => {
  let capturing = browser.tabs.captureTab();
  capturing.then(onCaptured, onError);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `captureTab` | No | No | 59 | ? | No | No | ? | ? | 82 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-captureVisibleTab) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/captureTab>

tabs.goForward()
================



Navigate to the next page in tab's history, if available.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let goingForward = browser.tabs.goForward(
  tabId,                       // optional integer
  callback                       // optional function
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to navigate. Defaults to the active tab of the current window.

  
`callback` Optional
  `function`. When the page navigation finishes, this function is called without parameters.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled when the page navigation finishes.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `goForward` | 72 | 79 | 77 | ? | 60 | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



Go forward to the next page in the current tab:

 
```
function onGoForward() {
  console.log("Gone forward");
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let goingForward = browser.tabs.goForward();
goingForward.then(onGoForward, onError);

```
  **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoomSettings) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/goForward>

tabs.goBack()
=============



Navigate to the previous page in tab's history, if available.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let withGoingBack = browser.tabs.goBack(
  tabId,                  // optional integer
  callback                  // optional function
)

```
### Parameters


 
`tabId` Optional
  `integer`. The ID of the tab to navigate. Defaults to the active tab of the current window.

  
`callback` Optional
  `function`. When the page navigation finishes, this function is called without parameters.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled when the page navigation finishes.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `goBack` | 72 | 79 | 77 | ? | 60 | 14 | ? | ? | 79 | ? | 15 | ? |


Examples
--------



Go back to the previous page in the current tab:

 
```
function onGoBack() {
  console.log("Gone back");
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let goingBack = browser.tabs.goBack();
goingBack.then(onGoBack, onError);

```
  **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoomSettings) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/goBack>

tabs.moveInSuccession()
=======================



Modifies the succession relationship for a group of tabs.

 Using the [`tabs`](../tabs) API, a tab can be assigned a *successor* tab in the same window. If tab B is the successor of tab A, and tab A is closed while it is the active tab, tab B will be activated next. If tab A doesn't have a successor, then the browser is free to determine which tab to activate next. If tab B is the successor of tab A, then tab A is called a *predecessor* of tab B. A tab can have at most one successor, but it can have any number of predecessors. A tab cannot take itself or a tab in a different window as a successor.

 All tabs start out with no successor; tabs only get a successor if assigned one by a WebExtension. However, the browser must not orphan a tab in a succession relationship with other tabs, if possible: if tab B is the successor of tab A, and tab C is the successor of tab B, and B is closed (or moved to another window), then tab A will take tab C as its successor. Preventing C from being orphaned in this way is called *moving a tab* (B) *from its line of succession*.

 `tabs.moveInSuccession()` takes an array of tab IDs, and moves all of those tabs from their lines of succession. It then makes each tab the successor of the previous tab in the array, forming a chain. It can optionally set the successor of the last tab in the chain to an anchor tab, which is *not* moved from its line of succession. Additional options can control whether the tab chain is "prepended" or "appended" to the anchor tab, and whether the operation acts like a linked-list insert.

 While the successor tab can be assigned with [`tabs.update()`](update), it is often desirable to use `tabs.moveInSuccession()` to change successors, even if only a single tab is having its successor assigned. The difference is that `browser.tabs.moveInSuccession([a], b)` moves tab `a` from its line of succession, so any predecessors of `a` will adopt `a`'s previous successor; whereas if `browser.tabs.update(a, {successorTabId: b})` is used instead, tab `a` may continue to be the successor of other tabs, which could be unexpected. Another advantage of `tabs.moveInSuccession()` is that all of the succession changes happen atomically, without having to worry about races between calls to [`tabs.update()`](update) and [`tabs.get()`](get) and other operations like the user closing a tab.



Syntax
------



```
browser.tabs.moveInSuccession([1, 3, 5, 7, 2, 9], 4, {insert:true})

```
### Parameters


 `tabIds`  `array` of `integer`. An array of tab `ID`s. The order of the elements in the array defines the relationship of the tabs. Any invalid tab `ID`s, or tab `ID`s corresponding to tabs not in the same window as `tabId` (or the first tab in the array, if `tabId` is omitted), will be ignored—they will keep their current successors and predecessors.

  
`tabId` Optional
  `integer`. The `ID` of the tab that will be the successor of the last tab in the `tabIds` array. If this `ID` is invalid or [`tabs.TAB_ID_NONE`](tab_id_none), the last tab will not have a successor. Defaults to [`tabs.TAB_ID_NONE`](tab_id_none).

  
`options` Optional
  `object`.

  
`append` Optional
  `boolean`. Determines whether to move the tabs in `tabIds` before or after `tabId` in the succession. If `false`, the tabs are moved before `tabId`, if `true`, the tabs are moved after `tabId`. Defaults to `false`.

  
`insert` Optional
  `boolean`. Determines whether to link up the current predecessors or successor (depending on `options.append`) of `tabId` to the other side of the chain after it is prepended or appended. If true, one of the following happens: if `options.append` is `false`, the first tab in the array is set as the successor of any current predecessors of `tabId`; if `options.append` is `true`, the current successor of tabId is set as the successor of the last tab in the array. Defaults to `false`.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `moveInSuccession` | No | No | 65 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/moveInSuccession>

tabs.print()
============


Call this function to print the contents of the active tab. If this function is called, the user will be presented with the print dialog from the underlying platform, and will have the chance to change the print settings and then print the currently active tab.


Syntax
------



```
browser.tabs.print()

```
### Parameters


None.

### Return value


None.

Examples
--------



In this example a background script listens for a click on a [browser action](../../anatomy_of_a_webextension#browser_actions_2), then tries to print the currently active tab:

 
```
browser.browserAction.onClicked.addListener(() => {
  browser.tabs.print();
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `print` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/print>

tabs.discard()
==============



Discards one or more tabs.

 Some browsers automatically "discard" tabs that they don't think are likely to be needed by the user soon. The tab stays visible in the tabstrip and the browser remembers its state, so if the user selects a tab that has been discarded, it is immediately restored.

 The details of exactly what is discarded are browser-specific, but in general, discarding a tab enables the browser to free some of the memory occupied by that tab.

 The [`tabs.discard()`](discard) API enables an extension to discard one or more tabs. It's not possible to discard the currently active tab, or a tab whose document contains a [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) listener that would display a prompt.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let discarding = browser.tabs.discard(
  tabIds          // integer or integer array
)

```
### Parameters


 `tabIds`  `integer` or `array` of `integer`. The IDs of the tab or tabs to discard.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when all the specified tabs have been discarded. If any error occurs (for example, invalid tab IDs), the promise will be rejected with an error message.

 If the ID of the active tab is passed in, it will not be discarded, but the promise will be fulfilled and any other tabs passed in will be discarded.


Examples
--------



Discard a single tab:

 
```
function onDiscarded() {
  console.log(`Discarded`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let discarding = browser.tabs.discard(2);
discarding.then(onDiscarded, onError);

```
 Discard multiple tabs:

 
```
function onDiscarded() {
  console.log(`Discarded`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let discarding = browser.tabs.discard([15, 14, 1]);
discarding.then(onDiscarded, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `discard` | 54["Only accepts a single tab ID as a parameter, not an array.", "The tab ID argument is optional: if it is omitted, the browser discards the least important tab.", "The callback is passed a `Tab` object representing the tab that was discarded.", "Tabs whose document contains a [`beforeunload`](https://developer.mozilla.org/docs/Web/API/BeforeUnloadEvent) listener that displays a prompt will be discarded."] | 14 | 58 | ? | 41["Only accepts a single tab ID as a parameter, not an array.", "The tab ID argument is optional: if it is omitted, the browser discards the least important tab.", "The callback is passed a `Tab` object representing the tab that was discarded.", "Tabs whose document contains a [`beforeunload`](https://developer.mozilla.org/docs/Web/API/BeforeUnloadEvent) listener that displays a prompt will be discarded."] | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-discard) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/discard>

tabs.getAllInWindow()
=====================



 **Warning:** This method has been deprecated. Use [`tabs.query({currentWindow: true})`](query) instead.

  Gets details about all tabs in the specified window.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.tabs.getAllInWindow(
  windowId            // optional integer
)

```
### Parameters


 
`windowId` Optional
  `integer`. Defaults to the current window.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `array` of `[`tabs.Tab`](tab)` objects, containing information about all the tabs in the window. If the window could not be found or some other error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAllInWindow` | 5 | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getAllInWindow) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getAllInWindow>

tabs.getSelected()
==================



 **Warning:** This method has been deprecated. Use [`tabs.query({active: true})`](query) instead.

  Gets the tab that is selected in the specified window.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingSelected = browser.tabs.getSelected(
  windowId           // optional integer
)

```
### Parameters


 
`windowId` Optional
  `integer`. Defaults to the current window.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`tabs.Tab`](tab) object containing information about the selected tab. If the tab could not be found or some other error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getSelected` | Yes | 79 | No | ? | No | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-getSelected) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getSelected>

tabs.highlight()
================



Highlights (selects) one or more tabs. Tabs are specified using a window ID and a range of tab indices.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let highlighting = browser.tabs.highlight(
  highlightInfo         // object
)

```
### Parameters


 `highlightInfo`  `object`.

  
`windowId` Optional
  `integer`. ID of the window that contains the tabs.

  
`populate` Optional
  `boolean`. Defaults to `true`. If set to `false`, the [`windows.Window`](../windows/window) object won't have a `tabs` property containing a list of [`tabs.Tab`](tab) objects representing the tabs open in the window.

  **Note:** Populating the window (the default behavior) can be an expensive operation if there are lots of tabs. For better performance it's recommended to manually set `populate` to `false` if you don't need tab details.

   `tabs`  `array` of integer values specifying one or more tab indices to highlight. Previously highlighted tabs not included in `tabs` will stop being highlighted. The first tab in `tabs` will become active.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](../windows/window) object containing details about the window whose tabs were highlighted. If the window could not be found or some other error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `highlight` | Yes | 79 | 63 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-highlight) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/highlight>

tabs.printPreview()
===================



Opens print preview for the active tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). An extension can detect when print preview has been closed by listening to the [afterprint](https://developer.mozilla.org/en-US/docs/Web/API/Window/afterprint_event) event:

 
```
window.addEventListener("afterprint", resumeFunction, false);

```


Syntax
------



```
let openingPreview = browser.tabs.printPreview()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the preview page has opened.

Examples
--------



In this example a background script listens for a click on a [browser action](../../anatomy_of_a_webextension#browser_actions_2), then opens print preview for the currently active tab:

 
```
browser.browserAction.onClicked.addListener(() => {
  browser.tabs.printPreview()
    .then(() => {
      console.log("Entered print preview");
    });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `printPreview` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/printPreview>

tabs.sendRequest()
==================



 **Warning:** This method has been deprecated. Use [`tabs.sendMessage()`](sendmessage) instead.

  Sends a single request to the content script(s) in the specified tab, with an optional callback to run when a response is sent back. The [`extension.onRequest`](../extension/onrequest) event is fired in each content script running in the specified tab for the current extension.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let sending = browser.tabs.sendRequest(
  tabId,                   // integer
  request                  // any
)

```
### Parameters


 `tabId`  `integer`.

  `request`  `any`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the JSON response object sent by the handler of the message in the content script, or with no arguments if the content script did not send a response. If an error occurs while connecting to the specified tab or any other error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sendRequest` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-sendRequest) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendRequest>

tabs.show()
===========



Shows one or more tabs that were previously hidden by a call to [`tabs.hide`](hide).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let showing = browser.tabs.show(
  tabIds          // integer or integer array
)

```
### Parameters


 `tabIds`  `integer` or `array` of `integer`. The IDs of the tab or tabs to show.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Show a single tab:

 
```
function onShown() {
  console.log(`Shown`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.tabs.show(2).then(onShown, onError);

```
 Show multiple tabs:

 
```
function onShown() {
  console.log(`Shown`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

browser.tabs.show([15, 14, 1]).then(onShown, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `show` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/show>

tabs.onAttached
===============


Fired when a tab is attached to a window, for example because it was moved between windows.


Syntax
------




```
browser.tabs.onAttached.addListener(listener)
browser.tabs.onAttached.removeListener(listener)
browser.tabs.onAttached.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. ID of the tab that was attached to a new window.

  `attachInfo`  `object`. ID of the new window, and index of the tab within it. See the [attachInfo](#attachinfo_2) section for more details.

    Additional objects
------------------


### attachInfo


 `newWindowId`  `integer`. ID of the new window.

  `newPosition`  `integer`. Index position that the tab has in the new window.

  Examples
--------



Listen for attach events, and log the info:

 
```
function handleAttached(tabId, attachInfo) {
  console.log(`Tab: ${tabId} attached`);
  console.log(`New window: ${attachInfo.newWindowId}`);
  console.log(`New index: ${attachInfo.newPosition}`);
}

browser.tabs.onAttached.addListener(handleAttached);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onAttached` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onAttached) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onAttached>

tabs.onDetached
===============


Fired when a tab is detached from a window, for example because it is being moved between windows.


Syntax
------




```
browser.tabs.onDetached.addListener(listener)
browser.tabs.onDetached.removeListener(listener)
browser.tabs.onDetached.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. ID of the tab that was detached.

  `detachInfo`  `object`. ID of the previous window, and index of the tab within it. See the [detachInfo](#detachinfo_2) section for more details.

    Additional objects
------------------


### detachInfo


 `oldWindowId`  `integer`. ID of the previous window.

  `oldPosition`  `integer`. Index position that the tab had in the old window.

  Examples
--------



Listen for detach events, and log the info:

 
```
function handleDetached(tabId, detachInfo) {
  console.log(`Tab: ${tabId} moved`);
  console.log(`Old window: ${detachInfo.oldWindowId}`);
  console.log(`Old index: ${detachInfo.oldPosition}`);
}

browser.tabs.onDetached.addListener(handleDetached);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onDetached` | Yes | 15 | 45 | ? | Yes | 14 | ? | ? | 54 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onDetached) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onDetached>

tabs.warmup()
=============



To optimize system resource usage, browsers may drop GPU resources associated with tabs that the user has not accessed for a certain amount of time. If a browser has done this for a tab, then reactivating the tab (for example, when the user switches to it) may take longer than it normally would.

 The `tabs.warmup()` API enables an extension to start the process of rendering the resources for an inactive tab, if the extension expects that the user might switch to the tab soon. This then makes the actual tab switch faster than it would be otherwise.

 Note this API does not work on discarded tabs and does not need to be called immediately prior to switching tabs. It is merely a performance improvement when the tab switch can be anticipated, such as when hovering over a button that when clicked would switch to the tab.

 It is expected that this API would mostly be useful to tab management extensions.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let warming = browser.tabs.warmup(
  tabId               // integer
)

```
### Parameters


 `tabId`  `integer`. ID of the tab to warm up. If the argument passed here is not an integer (in particular, if it is `null` or `undefined`) then `warmup()` will throw an exception synchronously.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if the tab identified by `tabId` is successfully warmed up. If `tabId` does not identify an open tab, or if warming up fails for some other reason, then the promise will be rejected with an error message.

Examples
--------



This code adds a listener to the `browserAction.onClicked` event. The listener retrieves all tabs in the current window that contain pages under "<https://developer.mozilla.org/>" and warms up the first one that it finds.

 
```
function onSuccess() {
  console.log("success!");
}

function onFailure(error) {
  // e.g. ID of a nonexistent tab
  console.error(error);
}

async function warmupMDN() {

  const mdnTabs = await browser.tabs.query({
    currentWindow: true,
    url: "https://developer.mozilla.org/\*"
  });

  if (mdnTabs.length > 0) {
    const warming = browser.tabs.warmup(mdnTabs[0].id);
    warming.then(onSuccess, onFailure);
  }

}

browser.browserAction.onClicked.addListener(warmupMDN);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `warmup` | No | No | 79 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/warmup>

tabs.onActiveChanged
====================



 **Warning:** This event is deprecated. Use [`tabs.onActivated`](onactivated) instead.

  Fires when the selected tab in a window changes. Note that the tab's URL may not be set at the time this event fired, but you can listen to [`tabs.onUpdated`](onupdated) events to be notified when a URL is set.



Syntax
------




```
browser.tabs.onActiveChanged.addListener(listener)
browser.tabs.onActiveChanged.removeListener(listener)
browser.tabs.onActiveChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. The ID of the tab that has become active.

  `selectInfo`  `object`. See the [selectInfo](#selectinfo_2) section for more details.

    Additional objects
------------------


### selectInfo


 `windowId`  `integer`. The ID of the window containing the selected tab.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onActiveChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onActiveChanged) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onActiveChanged>

tabs.onHighlightChanged
=======================



 **Warning:** This event is deprecated. Use [`tabs.onHighlighted`](onhighlighted) instead.

  Fired when the highlighted or selected tabs in a window changes.



Syntax
------




```
browser.tabs.onHighlightChanged.addListener(listener)
browser.tabs.onHighlightChanged.removeListener(listener)
browser.tabs.onHighlightChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `selectInfo`  `object`. See the [selectInfo](#selectinfo_2) section for more details.

    Additional objects
------------------


### selectInfo


 `windowId`  `integer`. The window whose tabs changed.

  `tabIds`  `array` of `integer`. All highlighted tabs in the window.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHighlightChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onHighlightChanged) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onHighlightChanged>

tabs.onReplaced
===============



Fired when a tab is replaced with another tab due to prerendering or instant.

 This event may not be relevant for or supported by browsers other than Chrome.



Syntax
------




```
browser.tabs.onReplaced.addListener(listener)
browser.tabs.onReplaced.removeListener(listener)
browser.tabs.onReplaced.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `addedTabId`  `integer`. ID of the replacement tab.

  `removedTabId`  `integer`. ID of the tab that was replaced.

    Examples
--------



Listen for replacement events, and log the associated info:

 
```
function handleReplaced(addedTabId, removedTabId) {
  console.log(`New tab: ${addedTabId}`);
  console.log(`Old tab: ${removedTabId}`);
}

browser.tabs.onReplaced.addListener(handleReplaced);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onReplaced` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onReplaced) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onReplaced>

tabs.onSelectionChanged
=======================



 **Warning:** This event is deprecated. Use [`tabs.onActivated`](onactivated) instead.

  Fires when the selected tab in a window changes.



Syntax
------




```
browser.tabs.onSelectionChanged.addListener(listener)
browser.tabs.onSelectionChanged.removeListener(listener)
browser.tabs.onSelectionChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tabId`  `integer`. The ID of the tab that has become active.

  `selectInfo`  `object`. See the [selectInfo](#selectinfo_2) section for more details.

    Additional objects
------------------


### selectInfo


 `windowId`  `integer`. The ID of the window the selected tab changed in.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onSelectionChanged` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onSelectionChanged) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onSelectionChanged>

tabs.onZoomChange
=================


Fired when a tab is zoomed.


Syntax
------




```
browser.tabs.onZoomChange.addListener(listener)
browser.tabs.onZoomChange.removeListener(listener)
browser.tabs.onZoomChange.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `ZoomChangeInfo`  `object`. Information about the zoom event. See the [ZoomChangeInfo](#zoomchangeinfo_2) section for more details.

    Additional objects
------------------


### ZoomChangeInfo


 `tabId`  `integer`. ID of the tab that was zoomed.

  `oldZoomFactor`  `number`. The previous zoom factor.

  `newZoomFactor`  `number`. The new zoom factor.

  `zoomSettings`  [`tabs.ZoomSettings`](zoomsettings). Zoom settings for the tab.

  Examples
--------



Listen for zoom events and log the info:

 
```
function handleZoomed(zoomChangeInfo) {
  console.log(`Tab: ${zoomChangeInfo.tabId} zoomed`);
  console.log(`Old zoom: ${zoomChangeInfo.oldZoomFactor}`);
  console.log(`New zoom: ${zoomChangeInfo.newZoomFactor}`);
}

browser.tabs.onZoomChange.addListener(handleZoomed);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onZoomChange` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onZoomChange) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onZoomChange>

pageAction.ImageDataType
========================


Pixel data for an image.


Type
----


An [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object, e.g. from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 79 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#type-ImageDataType) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/ImageDataType>

pageAction.isShown()
====================



Returns `true` if the page action is being shown for the given tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingIsShown = browser.pageAction.isShown(
  details // object
)

```
### Parameters


 `details`  `object`. An object containing the `tabId` to check.

  `tabId`  `integer`. ID of the tab to check.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the extension's page action is being shown for the given tab, and `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isShown` | No | No | 59 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Check the state of the currently active tab:

 
```
async function shownInActiveTab() {
  let tabs = await browser.tabs.query({
    currentWindow:true,
    active: true
  });
  let shown = await browser.pageAction.isShown({
    tabId: tabs[0].id
  });
  console.log(shown);
}

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/isShown>

pageAction.setPopup()
=====================


Sets the HTML document to be opened as a popup when the user clicks on the page action's icon.


Syntax
------



```
browser.pageAction.setPopup(
  details // object
)

```
### Parameters


 `details`  `object`.

  `tabId`  `integer`. The ID of the tab for which you want to set the popup.

  `popup`  `string` or `null`. URL to the HTML file to show in a popup.

 If an empty string (`""`) is passed here, the popup is disabled, and the extension will receive [`pageAction.onClicked`](onclicked) events.

 If `null` is passed here, the popup is reset to the popup that was specified in the [`page_action`](../../manifest.json/page_action) manifest key.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setPopup` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50The 'tabId' parameter is ignored, and the popup is set for all tabs. | ? | 15 | ? |
| `null` | No | No | 59 | ? | No | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Listen for [`tabs.onUpdated`](../tabs/onupdated) events, and switch the popup if the loading status changes:

 
```
browser.tabs.onUpdated.addListener((tabId, changeInfo, tabInfo) => {
  if (changeInfo.status) {
    browser.pageAction.show(tabId);
    if (changeInfo.status === "loading") {
      browser.pageAction.setPopup({
        tabId,
        popup: "/popup/loading.html"
      });
    } else {
      browser.pageAction.setPopup({
        tabId,
        popup: "/popup/complete.html"
      });
    }
  }
});

```
  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-setPopup) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/setPopup>

pageAction.getPopup()
=====================



Gets the URL for the HTML document set as the popup for this page action.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingPopup = browser.pageAction.getPopup(
  details               // object
)

```
### Parameters


 `details`  `object`.

  `tabId`  `integer`. ID of the tab whose popup you want to get.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the popup's URL.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPopup` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 50The 'tabId' parameter is ignored: the page action popup is the same for all tabs. | ? | 15 | ? |


Examples
--------



Add a context menu item that logs the popup URL for the current tab. Note that you'll need the `contextMenus` [permission](../../manifest.json/permissions) in your [manifest](../../manifest.json) to create context menu items.

 
```
function gotPopup(popupURL) {
  console.log(popupURL);
}

browser.contextMenus.create({
  id: "get-popup",
  title: "Get popup URL"
});

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "get-popup") {
    let gettingPopup = browser.pageAction.getPopup({tabId: tab.id});
    gettingPopup.then(gotPopup);
  }
});

```
  **Note:** This API is based on Chromium's [`chrome.pageAction`](https://developer.chrome.com/docs/extensions/reference/pageAction/#method-getPopup) API. This documentation is derived from [`page_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/page_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction/getPopup>

tabs.onHighlighted
==================



Fired when the set of highlighted tabs in a window changes.

 Note that before version 63, Firefox didn't have the concept of highlighting multiple tabs, so this event was just an alias for [`tabs.onActivated`](onactivated).



Syntax
------




```
browser.tabs.onHighlighted.addListener(listener)
browser.tabs.onHighlighted.removeListener(listener)
browser.tabs.onHighlighted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `highlightInfo`  `object`. ID(s) of the highlighted tabs, and ID of their window. See the [highlightInfo](#highlightinfo_2) section for more details.

    Additional objects
------------------


### highlightInfo


 `windowId`  `integer`. ID of the window whose tabs changed.

  `tabIds`  `array` of `integer`. IDs of the highlighted tabs in the window.

  Examples
--------



Listen for highlighting events, and log the IDs of highlighted tabs:

 
```
function handleHighlighted(highlightInfo) {
  console.log(`Highlighted tabs: ${highlightInfo.tabIds}`);
}

browser.tabs.onHighlighted.addListener(handleHighlighted);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHighlighted` | Yes | 79 | 6345–62Implemented as an alias for `onActivated`. | ? | No | 14 | ? | ? | 54Implemented as an alias for `onActivated`. | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#event-onHighlighted) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onHighlighted>

contextualIdentities.ContextualIdentity
=======================================


The `contextualIdentities.ContextualIdentity` type describes a single contextual identity.


Type
----



Values of this type are objects. They contain the following properties:

  `cookieStoreId`  `string`. The cookie store ID for the identity. Since contextual identities don't share cookie stores, this serves as a unique identifier.

  `color`  `string`. The color for the identity. This will be shown in tabs belonging to this identity. The following values are valid:

 * "blue"
* "turquoise"
* "green"
* "yellow"
* "orange"
* "red"
* "pink"
* "purple"
* "toolbar"

 The value "toolbar" represents a theme-dependent color. Identities with color "toolbar" will be displayed in the same color as text in the toolbar (corresponding to the [theme key](../../manifest.json/theme#colors) `"toolbar_field_text"`).

  `colorCode`  `string`. A hex code representing the exact color used for the identity. For example: `"#37adff"`. In the special case of the "toolbar" color, `colorCode` is always `"#7c7c7d"`, regardless of the displayed color.

  `icon`  `string`. The name of an icon for the identity. This will be shown in the URL bar for tabs belonging to this identity. The following values are valid:

 * "fingerprint"
* "briefcase"
* "dollar"
* "cart"
* "circle"
* "gift"
* "vacation"
* "food"
* "fruit"
* "pet"
* "tree"
* "chill"
* "fence"

  `iconUrl`  `string`. A full resource:// URL pointing to the identity's icon. For example: "resource://usercontext-content/fingerprint.svg".

  `name`  `string`. Name of the identity. This will be shown in the URL bar for tabs belonging to this identity. Note that names don't have to be unique.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `color` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |
| `colorCode` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `cookieStoreId` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |
| `icon` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |
| `iconUrl` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `name` | No | No | 53 | ? | No | No | ? | ? | 53 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/ContextualIdentity>

contextualIdentities.create()
=============================



Creates a new contextual identity. Once created, the user will be able to create new tabs belonging to this contextual identity, just as they can with the built-in identities.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let createContext = browser.contextualIdentities.create(
  details                  // object
)

```
### Parameters


 `details`  `object`. An object containing properties for the new contextual identity. This contains the following properties:

  `name`  `string`. The name of the new identity. This will be displayed in the browser's UI, enabling them to open a new tab belonging to the identity. It will also be displayed in the URL bar for tabs belonging to this identity.

  `color`  `string`. The color associated with the new identity. This will be used to highlight tabs belonging to this identity. You can supply any of the following values here:

 * "blue"
* "turquoise"
* "green"
* "yellow"
* "orange"
* "red"
* "pink"
* "purple"
* "toolbar"

  `icon`  `string`. The name of an icon to display in the URL bar for tabs belonging to this identity. You can supply any of the following values here:

 * "fingerprint"
* "briefcase"
* "dollar"
* "cart"
* "circle"
* "gift"
* "vacation"
* "food"
* "fruit"
* "pet"
* "tree"
* "chill"
* "fence"

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`ContextualIdentity`](contextualidentity) that describes the new identity. If the contextual identities feature is not enabled, the promise is rejected.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | No | No | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | No | ? | ? | 53Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled. | ? | No | ? |


Examples
--------



This example creates a new contextual identity and logs its cookie store ID:

 
```
function onCreated(context) {
  console.log(`New identity's ID: ${context.cookieStoreId}.`);
}

function onError(e) {
  console.error(e);
}

browser.contextualIdentities.create({
  name: "my-thing",
  color: "purple",
  icon: "briefcase"
}).then(onCreated, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/create>

contextualIdentities.get()
==========================



Gets information about a contextual identity, given its cookie store ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getContext = browser.contextualIdentities.get(
  cookieStoreId                  // string
)

```
### Parameters


 `cookieStoreId`  `string`. The ID of this contextual identity's cookie store. Because contextual identities each have their own cookie store, this serves as an identifier for the contextual identity itself.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`ContextualIdentity`](contextualidentity) that describes the identity. If the identity could not be found or the contextual identities feature is not enabled, the promise is rejected.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |


Examples
--------



This example tries to retrieve the contextual identity whose ID is "firefox-container-1":

 
```
function onGot(context) {
  if (!context) {
    console.error("Context not found");
  } else {
    console.log(`Name: ${context.name}`);
  }
}

function onError(e) {
  console.error(e);
}

browser.contextualIdentities.get("firefox-container-1").then(onGot, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/get>

contextualIdentities.onCreated
==============================


Fired when a new contextual identity is created. Contextual identities may be created by extensions using the `contextualIdentities` API, or directly by the user, using the browser's user interface.


Syntax
------




```
browser.contextualIdentities.onCreated.addListener(listener)
browser.contextualIdentities.onCreated.removeListener(listener)
browser.contextualIdentities.onCreated.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `changeInfo`  `object`. An object that contains a single property, `contextualIdentity`, which is a [`contextualIdentities.ContextualIdentity`](contextualidentity) object, representing the identity that was created.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreated` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



```
function handleCreated(changeInfo) {
  console.log(`Created: ${changeInfo.contextualIdentity.name}`);
}

browser.contextualIdentities.onCreated.addListener(handleCreated);

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/onCreated>

contextualIdentities.onRemoved
==============================


Fired when a new contextual identity is removed. Contextual identities may be removed by extensions using the `contextualIdentities` API, or directly by the user, using the browser's user interface.


Syntax
------




```
browser.contextualIdentities.onRemoved.addListener(listener)
browser.contextualIdentities.onRemoved.removeListener(listener)
browser.contextualIdentities.onRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `changeInfo`  `object`. An object that contains a single property, `contextualIdentity`, which is a [`contextualIdentities.ContextualIdentity`](contextualidentity) object representing the identity that was removed.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRemoved` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



```
function handleRemoved(changeInfo) {
  console.log(`Removed: ${changeInfo.contextualIdentity.name}`);
}

browser.contextualIdentities.onRemoved.addListener(handleRemoved);

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/onRemoved>

action.onClicked
================



Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.

  **Note:** This API is available in Manifest V3 or higher.

  To define a right-click action, use the [`contextMenus`](../menus) API with the "browser\_action" [context type](../menus/contexttype).



Syntax
------




```
browser.action.onClicked.addListener(listener)
browser.action.onClicked.removeListener(listener)
browser.action.onClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `tab`  [`tabs.Tab`](../tabs/tab). The tab that was active when the icon was clicked.

  `OnClickData`  An object containing information about the click.

  `modifiers`  An `array`. The keyboard modifiers active at the time of the click, being one or more of `Shift`, `Alt`, `Command`, `Ctrl`, or `MacCtrl`.

  `button`  An `integer`. Indicates the button used to click the page action icon: `0` for a left-click or a click not associated with a mouse, such as one from the keyboard and `1` for a middle button or wheel click. Note that the right-click is not supported because Firefox consumes that click to display the context menu before this event is triggered.

      Examples
--------



When the user clicks the icon, disable it for the active tab, and log the tab's URL:

 
```
browser.action.onClicked.addListener((tab) => {
  // disable the active tab
  browser.action.disable(tab.id);
  // requires the "tabs" or "activeTab" permission, or host permissions for the URL
  console.log(tab.url);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onClicked` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#event-onClicked) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/onClicked>

contextualIdentities.update()
=============================



Updates properties of a contextual identity, given its cookie store ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let createContext = browser.contextualIdentities.update(
  cookieStoreId,           // string
  details                  // object
)

```
### Parameters


 `cookieStoreId`  `string`. The ID of this contextual identity's cookie store. Because contextual identities each have their own cookie store, this serves as an identifier for the contextual identity itself.

  `details`  `object`. An object containing new values for the properties that you wish to change. This may contain any of the following properties:

  
`name` Optional
  `string`. A new name for the identity. This will be displayed in the browser's UI, enabling them to open a new tab in the identity. It will also be displayed in the URL bar for tabs belonging to this identity.

  
`color` Optional
  `string`. A new color for the identity. This will be used to highlight tabs belonging to this identity. You can supply any of the following values here:

 * "blue"
* "turquoise"
* "green"
* "yellow"
* "orange"
* "red"
* "pink"
* "purple"
* "toolbar"

  
`icon` Optional
  `string`. A new icon for the identity. You can supply any of the following values here:

 * "fingerprint"
* "briefcase"
* "dollar"
* "cart"
* "circle"
* "gift"
* "vacation"
* "food"
* "fruit"
* "pet"
* "tree"
* "chill"
* "fence"

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`ContextualIdentity`](contextualidentity) that describes the updated identity. If the identity could not be found or the contextual identities feature is not enabled, the promise is rejected.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |


Examples
--------



This example updates the contextual identity whose ID is "firefox-container-1" to have a new name, color, and icon:

 
```
function onUpdated(context) {
  console.log(`New identity's name: ${context.name}.`);
}

function onError(e) {
  console.error(e);
}

browser.contextualIdentities.update(
  "firefox-container-1", {
    name: "my-thing",
    color: "purple",
    icon: "briefcase"
  }).then(onUpdated, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/update>

contextualIdentities.remove()
=============================



Removes a contextual identity, given its cookie store ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removeContext = browser.contextualIdentities.remove(
  cookieStoreId                  // string
)

```
### Parameters


 `cookieStoreId`  `string`. The ID of the contextual identity's cookie store. Because contextual identities each have their own cookie store, this serves as an identifier for the contextual identity itself.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`ContextualIdentity`](contextualidentity) that describes the identity that was removed. If the identity could not be found or the contextual identities feature is not enabled, the promise is rejected.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | No | No | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | No | ? | ? | 53["Before version 57, this method resolves its promise with `false` if the contextual identities feature is disabled.", "Before version 57, this method resolves its promise with `null` if the given identity was not found."] | ? | No | ? |


Examples
--------



This example tries to remove the contextual identity whose ID is "firefox-container-1":

 
```
function onRemoved(context) {
  if (!context) {
    console.error("Context not found");
  } else {
    console.log(`Removed identity: ${context.cookieStoreId}.`);
  }
}

function onError(e) {
  console.error(e);
}

browser.contextualIdentities.remove("firefox-container-1").
  then(onRemoved, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/remove>

contextualIdentities.onUpdated
==============================


Fired when the properties of a contextual identity, such as its name, icon, or color, are changed. Contextual identities may be updated by extensions using the `contextualIdentities` API, or directly by the user, using the browser's user interface.


Syntax
------




```
browser.contextualIdentities.onUpdated.addListener(listener)
browser.contextualIdentities.onUpdated.removeListener(listener)
browser.contextualIdentities.onUpdated.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `changeInfo`  `object`. An object that contains a single property, `contextualIdentity`, which is a [`contextualIdentities.ContextualIdentity`](contextualidentity) object representing the identity whose properties were updated.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onUpdated` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



```
function handleUpdated(changeInfo) {
  console.log(`Updated: ${changeInfo.contextualIdentity.name}`);
}

browser.contextualIdentities.onUpdated.addListener(handleUpdated);

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/onUpdated>

action.ColorArray
=================


Type
----



An `array` of four integers in the range 0-255, defining an RGBA color. The four values specify the following channels:

 1. Red
2. Green
3. Blue
4. Alpha (opacity).

 For example, opaque red is `[255, 0, 0, 255]`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ColorArray` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#type-ColorArray) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/ColorArray>

action.setIcon()
================



Sets the icon for the browser action.

  **Note:** This API is available in Manifest V3 or higher.

  You can specify a single icon as either the path to an image file or a [`action.ImageDataType`](imagedatatype) object.

 You can specify multiple icons in different sizes by supplying a dictionary containing multiple paths or `ImageData` objects. This means the icon doesn't have to be scaled for a device with a different pixel density.

 Tabs without a specific icon will inherit the global icon, which defaults to the [`default_icon`](../../manifest.json/browser_action) specified in the manifest.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let settingIcon = browser.action.setIcon(
  details         // object
)

```
### Parameters



 `details`  `object`. An object containing either `imageData` or `path` properties, and optionally a `tabId` property.

  
`imageData` Optional
  `[`action.ImageDataType`](imagedatatype)` or `object`. This is either a single `ImageData` object or a dictionary object.

 Use a dictionary object to specify multiple `ImageData` objects in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `imageData` is a dictionary, the value of each property is an `ImageData` object, and its name is its size, like this:

 
```
{
  16: image16,
  32: image32
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`path` Optional
  `string` or `object`. This is either a relative path to an icon file or it is a dictionary object.

 Use a dictionary object to specify multiple icon files in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `path` is a dictionary, the value of each property is a relative path, and its name is its size, like this:

 
```
{
  16: "path/to/image16.jpg",
  32: "path/to/image32.jpg"
}

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`tabId` Optional
  `integer`. Sets the icon only for the given tab. The icon is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the icon for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the icon is not set.
* If `windowId` and `tabId` are both omitted, the global icon is set.

 If each one of `imageData` and `path` is one of `undefined`, `null` or empty object:

 * If `tabId` is specified, and the tab has a tab-specific icon set, then the tab will inherit the icon from the window to which it belongs.
* If `windowId` is specified, and the window has a window-specific icon set, then the window will inherit the global icon.
* Otherwise, the global icon will be reset to the manifest icon.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the icon has been set.

Examples
--------



The code below uses a browser action to toggle a listener for [`webRequest.onHeadersReceived`](../webrequest/onheadersreceived), and uses `setIcon()` to indicate whether listening is on or off:

 
```
function logResponseHeaders(requestDetails) {
  console.log(requestDetails);
}

function startListening() {
  browser.webRequest.onHeadersReceived.addListener(
    logResponseHeaders,
    {urls: ["<all\_urls>"]},
    ["responseHeaders"]
  );
  browser.action.setIcon({path: "icons/listening-on.svg"});
}

function stopListening() {
  browser.webRequest.onHeadersReceived.removeListener(logResponseHeaders);
  browser.action.setIcon({path: "icons/listening-off.svg"});
}

function toggleListener() {
  if (browser.webRequest.onHeadersReceived.hasListener(logResponseHeaders)) {
    stopListening();
  } else {
    startListening();
  }
}

browser.action.onClicked.addListener(toggleListener);

```
 The code below sets the icon using an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object:

 
```
function getImageData() {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");

  ctx.fillStyle = "green";
  ctx.fillRect(10, 10, 100, 100);

  return ctx.getImageData(50, 50, 100, 100);
}

browser.action.onClicked.addListener(() => {
  browser.action.setIcon({imageData: getImageData()});
});

```
 The following snippet updates the icon when the user clicks it, but only for the active tab:

 
```
browser.action.onClicked.addListener((tab) => {
  browser.action.setIcon({
    tabId: tab.id, path: "icons/updated-48.png"
  });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setIcon` | 88 | 88["This call is not persisted.", "The `imageData` parameter is not accepted.", "The `path` parameter is required."] | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setIcon) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setIcon>

action.setPopup()
=================



Sets the HTML document that is opened as a popup when the user clicks on the browser action's icon. Tabs without a specific popup will inherit the global popup, which defaults to the [`default_popup`](../../manifest.json/browser_action) specified in the manifest.

  **Note:** This API is available in Manifest V3 or higher.

 

Syntax
------



```
browser.action.setPopup(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Sets the popup only for a specific tab. The popup is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the popup only for the specified window.

  `popup`  `string` or `null`. The HTML file to show in a popup, specified as a URL.

 This can point to a file packaged within the extension (for example, created using [`extension.getURL`](../extension/geturl)), or a remote document (e.g. `https://example.org/`).

 If an empty string (`""`) is passed here, the popup is disabled, and the extension will receive [`action.onClicked`](onclicked) events.

 If `popup` is `null`:

 * If `tabId` is specified, removes the tab-specific popup so that the tab inherits the global popup.
* If `windowId` is specified, removes the window-specific popup so that the window inherits the global popup.
* If `tabId` and `windowId` are both omitted, reverts the global popup to the default value.

     * If `windowId` and `tabId` are both supplied, the function fails and the popup is not set.
* If `windowId` and `tabId` are both omitted, the global popup is set.


Examples
--------



This code adds a pair of context menu items that you can use to switch between two popups. Note that you'll need the "contextMenus" [permission](../../manifest.json/permissions) set in the extension's manifest to create context menu items.

 
```
function onCreated() {
  if (browser.runtime.lastError) {
    console.log("error creating item:", browser.runtime.lastError);
  } else {
    console.log("item created successfully");
  }
}

browser.contextMenus.create(
  {
    id: "popup-1",
    type: "radio",
    title: "Popup 1",
    contexts: ["all"],
    checked: true,
  },
  onCreated
);

browser.contextMenus.create(
  {
    id: "popup-2",
    type: "radio",
    title: "Popup 2",
    contexts: ["all"],
    checked: false,
  },
  onCreated
);

browser.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "popup-1") {
    browser.action.setPopup({ popup: "/popup/popup1.html" });
  } else if (info.menuItemId === "popup-2") {
    browser.action.setPopup({ popup: "/popup/popup2.html" });
  }
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setPopup` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setPopup) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setPopup>

action.setBadgeText()
=====================



Sets the badge text for the browser action. The badge is displayed on top of the icon.

  **Note:** This API is available in Manifest V3 or higher.

  Tabs without an specific badge text will inherit the global badge text, which is `""` by default.



Syntax
------




```
browser.action.setBadgeText(
  details // object
)

```
 This API is also available as `chrome.action.setBadgeText()`.


### Parameters



 `details`  An object with the following properties:

  `text`  `string` or `null`. Any number of characters can be passed, but only about four can fit in the space.

 Use an empty string - `""` - if you don't want any badge.

 If a `tabId` is specified, `null` removes the tab-specific badge text so that the tab inherits the global badge text. Otherwise it reverts the global badge text to `""`.

 If a `windowId` is specified, `null` removes the window-specific badge text so that the tab inherits the global badge text. Otherwise it reverts the global badge text to `""`.

  
`tabId` Optional
  `integer`. Set the badge text only for the given tab. The text is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Set the badge text for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge is set.


Examples
--------



Add a badge indicating how many times the user clicked the button:

 
```
let clicks = 0;

function increment() {
  browser.action.setBadgeText({ text: (++clicks).toString() });
}

browser.action.onClicked.addListener(increment);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeText` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setBadgeText) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setBadgeText>

action.getBadgeText()
=====================



Gets the browser action's badge text.

  **Note:** This API is available in Manifest V3 or higher.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingText = browser.action.getBadgeText(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specifies the tab from which to get the badge text.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge text.

     * If windowId and tabId are both supplied, the function fails.
* If windowId and tabId are both omitted, the global badge text is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the badge text.

Examples
--------



Log the badge text:

 
```
function gotBadgeText(text) {
  console.log(text);
}

let gettingBadgeText = browser.action.getBadgeText({});
gettingBadgeText.then(gotBadgeText);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeText` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-getBadgeText) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/getBadgeText>

action.ImageDataType
====================


Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).


Type
----


An [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#type-ImageDataType) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/ImageDataType>

action.setTitle()
=================



Sets the browser action's title. The title is displayed in a tooltip over the browser action's icon. You can pass a `tabId` in or a `windowId` as an optional parameter — if you do this then the title is changed only for the specified tab or window. Tabs or windows without a specific title inherit the global title text, which defaults to the [`default_title`](../../manifest.json/browser_action) or [`name`](../../manifest.json/name) specified in the manifest.

  **Note:** This API is available in Manifest V3 or higher.

 

Syntax
------



```
browser.action.setTitle(
  details // object
)

```
### Parameters



 `details`  `object`. The new title and optionally the ID of the tab or window to target.

  `title`  `string` or `null`. The string the browser action should display when moused over.

 If `title` is an empty string, the used title will be the extension name, but [`action.getTitle`](gettitle) will still provide the empty string.

 If `title` is `null`:

 * If `tabId` is specified, and the tab has a tab-specific title set, then the tab will inherit the title from the window to which it belongs.
* if `windowId` is specified, and the window has a window-specific title set, then the window will inherit the global title.
* Otherwise, the global title will be reset to the manifest title.

  
`tabId` Optional
  `integer`. Sets the title only for the given tab.

  
`windowId` Optional
  `integer`. Sets the title for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the title is not set.
* If `windowId` and `tabId` are both omitted, the global title is set.


Examples
--------



This code switches the title between "this" and "that" each time the user clicks the browser action:

 
```
function toggleTitle(title) {
  if (title === "this") {
    browser.action.setTitle({ title: "that" });
  } else {
    browser.action.setTitle({ title: "this" });
  }
}

browser.action.onClicked.addListener(() => {
  let gettingTitle = browser.action.getTitle({});
  gettingTitle.then(toggleTitle);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setTitle` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setTitle) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setTitle>

action.getTitle()
=================



Gets the browser action's title.

  **Note:** This API is available in Manifest V3 or higher.

  Just as you can set the title on a per-tab basis using [`action.setTitle()`](settitle), so you can retrieve a tab-specific title by passing the tab's ID into this function.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingTitle = browser.action.getTitle(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specify the tab to get the title from.

  
`windowId` Optional
  `integer`. Specify the window to get the title from.

     * If `windowId` and `tabId` are both supplied, the function fails and the promise it returns is rejected.
* If `windowId` and `tabId` are both omitted, the global title is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the browser action's title.

Examples
--------



This code switches the title between "this" and "that" each time the user clicks the browser action:

 
```
function toggleTitle(title) {
  if (title === "this") {
    browser.action.setTitle({ title: "that" });
  } else {
    browser.action.setTitle({ title: "this" });
  }
}

browser.action.onClicked.addListener(() => {
  let gettingTitle = browser.action.getTitle({});
  gettingTitle.then(toggleTitle);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTitle` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-getTitle) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/getTitle>

action.getPopup()
=================



Gets the HTML document set as the popup for this browser action.

  **Note:** This API is available in Manifest V3 or higher.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingPopup = browser.action.getPopup(
  details               // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. The tab whose popup to get.

  
`windowId` Optional
  `integer`. The windows whose popup to get.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global popup is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the URL for the popup's document. This will be a fully qualified URL, such as `moz-extension://d1d8a2eb-fe60-f646-af30-a866c5b39942/popups/popup2.html`.

Examples
--------



Get the popup's URL:

 
```
function gotPopup(popupURL) {
  console.log(popupURL);
}

let gettingPopup = browser.action.getPopup({});
gettingPopup.then(gotPopup);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPopup` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-getPopup) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/getPopup>

action.openPopup()
==================



Open the browser action's popup.

  **Note:** This API is available in Manifest V3 or higher.

  You can only call this function from inside the handler for a [user action](../../user_actions).



Syntax
------



```
browser.action.openPopup()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Examples
--------



Open the popup when the user selects a context menu item:

 
```
browser.menus.create({
  id: "open-popup",
  title: "open popup",
  contexts: ["all"],
});

browser.menus.onClicked.addListener(() => {
  browser.action.openPopup();
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openPopup` | 88 | 88 | 109User interaction is not required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)). | ? | 74 | 16 | ? | ? | 109User interaction is not required to call this API when the `extensions.openPopupWithoutUserGesture.enabled` preference is set ([bug 1799344](https://bugzil.la/1799344)). | ? | 16 | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/openPopup>

action.setBadgeBackgroundColor()
================================



Sets the background color for the badge. Tabs without a specific badge background color will inherit the global badge background color, which defaults to `[217, 0, 0, 255]` in Firefox.

  **Note:** This API is available in Manifest V3 or higher.

  In Firefox, unless the badge text color is explicitly set using [`action.setBadgeTextColor()`](setbadgetextcolor), then the badge text color iw automatically set to black or white to maximize contrast with the specified badge background color. For example, if you set the badge background color to white, the default badge text color is set to black, and vice versa.

 Other browsers always use a white text color, so setting a dark background may be preferable to ensure the text is readable.



Syntax
------



```
browser.action.setBadgeBackgroundColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  `color`  The color, specified as one of:

 * a string: any CSS [<color>](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) value, for example `"red"`, `"#FF0000"`, or `"rgb(255,0,0)"`. If the string is not a valid color, the returned promise will be rejected and the background color won't be altered.
* a `[`action.ColorArray`](colorarray)` object.
* `null`. If a `tabId` is specified, it removes the tab-specific badge background color so that the tab inherits the global badge background color. Otherwise it reverts the global badge background color to the default value.

  
`tabId` Optional
  `integer`. Sets the badge background color only for the given tab. The color is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the badge background color only for the given tab.

     * If `windowId` and `tabId` are both supplied, the function fails and the color is not set.
* If `windowId` and `tabId` are both omitted, the global badge background color is set instead.


Examples
--------



A background color that starts off as red, and turns green when the browser action is clicked:

 
```
browser.action.setBadgeText({ text: "1234" });
browser.action.setBadgeBackgroundColor({ color: "red" });

browser.action.onClicked.addListener(() => {
  browser.action.setBadgeBackgroundColor({ color: "green" });
});

```
 Set the badge background color only for the active tab:

 
```
browser.action.setBadgeText({ text: "1234" });
browser.action.setBadgeBackgroundColor({ color: "red" });

browser.action.onClicked.addListener((tab) => {
  browser.action.setBadgeBackgroundColor({
    color: "green",
    tabId: tab.id,
  });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeBackgroundColor` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |



The default color in Firefox is: `[217, 0, 0, 255]`.

  **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setBadgeBackgroundColor>

action.getBadgeBackgroundColor()
================================



Gets the background color of the browser action's badge.

  **Note:** This API is available in Manifest V3 or higher.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.action.getBadgeBackgroundColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  
`tabId` Optional
  `integer`. Specifies the tab to get the badge background color from.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge background color.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge background color is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the retrieved color as a [`action.ColorArray`](colorarray).

Examples
--------



Log the badge's background color:

 
```
function onGot(color) {
  console.log(color);
}

function onFailure(error) {
  console.log(error);
}

browser.action.getBadgeBackgroundColor({}).then(onGot, onFailure);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeBackgroundColor` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-getBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/getBadgeBackgroundColor>

action.setBadgeTextColor()
==========================



Sets the text color for the browser action's badge. Tabs without a specific badge text color will inherit the global badge text color.

  **Note:** This API is available in Manifest V3 or higher.

 

Syntax
------



```
browser.action.setBadgeTextColor(
  details // object
)

```
### Parameters



 `details`  An object with the following properties:

  `color`  The color, specified as one of:

 * a string: any CSS [<color>](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) value, for example `"red"`, `"#FF0000"`, or `"rgb(255,0,0)"`. If the string is not a valid color, the returned promise will be rejected and the text color won't be altered.
* a `[`action.ColorArray`](colorarray)` object.
* `null`. If a `tabId` is specified, it removes the tab-specific badge text color so that the tab inherits the global badge text color. Otherwise it reverts the global badge text color to the default value.

  
`tabId` Optional
  `integer`. Sets the badge text color only for the given tab. The color is reset when the user navigates this tab to a new page.

  
`windowId` Optional
  `integer`. Sets the badge text color only for the given tab.

     * If `windowId` and `tabId` are both supplied, the function fails and the color is not set.
* If `windowId` and `tabId` are both omitted, the global badge text color is set instead.


Examples
--------



A badge text color that starts off as red, and turns green when the browser action is clicked:

 
```
browser.action.setBadgeText({ text: "1234" });
browser.action.setBadgeTextColor({ color: "red" });

browser.action.onClicked.addListener(() => {
  browser.action.setBadgeTextColor({ color: "green" });
});

```
 Set the badge text color only for the active tab:

 
```
browser.action.setBadgeText({ text: "1234" });
browser.action.setBadgeTextColor({ color: "red" });

browser.action.onClicked.addListener((tab) => {
  browser.action.setBadgeTextColor({
    color: "green",
    tabId: tab.id,
  });
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setBadgeTextColor` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-setBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setBadgeTextColor>

action.disable()
================



Disables the browser action for a tab, meaning that it cannot be clicked when that tab is active.

  **Note:** This API is available in Manifest V3 or higher.

 

Syntax
------



```
browser.action.disable(
  tabId // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The id of the tab for which you want to disable the browser action.

  Examples
--------



Disable the browser action when clicked, and re-enable it every time a new tab is opened:

 
```
browser.tabs.onCreated.addListener(() => {
  browser.action.enable();
});

browser.action.onClicked.addListener(() => {
  browser.action.disable();
});

```
 Disable the browser action only for the active tab:

 
```
browser.action.onClicked.addListener((tab) => {
  browser.action.disable(tab.id);
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `disable` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-disable) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/disable>

action.isEnabled()
==================



Returns `true` if the browser action is enabled.

  **Note:** This API is available in Manifest V3 or higher.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingIsEnabled = browser.action.isEnabled(
  details // object
)

```
### Parameters



 `details`  `object`. An object optionally containing the `tabId` or `windowId` to check.

  
`tabId` Optional
  `integer`. ID of a tab to check.

  
`windowId` Optional
  `integer`. ID of a window to check.

     * If windowId and tabId are both supplied, the function fails.
* If windowId and tabId are both omitted, the global enabled/disabled status is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the extension's browser action is enabled, and `false` otherwise.

Examples
--------



Check the global state:

 
```
browser.action.isEnabled({}).then((result) => {
  console.log(result);
});

```
 Check the state of the currently active tab:

 
```
async function enabledInActiveTab() {
  let tabs = await browser.tabs.query({
    currentWindow: true,
    active: true,
  });
  let enabled = await browser.action.isEnabled({
    tabId: tabs[0].id,
  });
  console.log(enabled);
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isEnabled` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/isEnabled>

action.getBadgeTextColor()
==========================



Gets the text color for the browser action's badge.

  **Note:** This API is available in Manifest V3 or higher.

  In Firefox, unless the badge text color is explicitly set using [`action.setBadgeTextColor()`](setbadgetextcolor), the badge text color is automatically set to black or white so as to maximize contrast with the specified badge background color. For example, if you set the badge background color to white, the default badge text color is set to black, and vice versa.

 Other browsers always use a white text color.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.action.getBadgeTextColor(
  details // object
)

```
### Parameters



 `details`  `object`.

  
`tabId` Optional
  `integer`. Specifies the tab to get the badge text color from.

  
`windowId` Optional
  `integer`. Specifies the window from which to get the badge text color.

     * If `windowId` and `tabId` are both supplied, the function fails.
* If `windowId` and `tabId` are both omitted, the global badge text color is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with the retrieved color as a [`action.ColorArray`](colorarray).

Examples
--------



Log the badge's text color:

 
```
function onGot(color) {
  console.log(color);
}

function onFailure(error) {
  console.log(error);
}

browser.action.getBadgeTextColor({}).then(onGot, onFailure);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBadgeTextColor` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-getBadgeBackgroundColor) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/getBadgeTextColor>

action.enable()
===============



Enables the browser action for a tab. By default, browser actions are enabled for all tabs.

  **Note:** This API is available in Manifest V3 or higher.

 

Syntax
------



```
browser.action.enable(
  tabId // optional integer
)

```
### Parameters


 
`tabId` Optional
  `integer`. The id of the tab for which you want to enable the browser action.

  Examples
--------



Disable the browser action when clicked, and re-enable it every time a new tab is opened:

 
```
browser.tabs.onCreated.addListener(() => {
  browser.action.enable();
});

browser.action.onClicked.addListener(() => {
  browser.action.disable();
});

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `enable` | 88 | 88 | 109 | ? | 74 | No | ? | ? | 109 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.action`](https://developer.chrome.com/docs/extensions/reference/action/#method-enable) API. This documentation is derived from [`browser_action.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/browser_action.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/enable>

alarms.clear()
==============



Cancels an alarm, given its name.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let clearAlarm = browser.alarms.clear(
  name                       // string
)

```
### Parameters


 
`name` Optional
  `string`. The name of the alarm to clear. If you don't supply this, the empty string "" will be used.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean. This will be `true` if the alarm was cleared, `false` otherwise.

Examples
--------



```
function onCleared(wasCleared) {
  console.log(wasCleared); // true/false
}

let clearAlarm = browser.alarms.clear("my-periodic-alarm");
clearAlarm.then(onCleared);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `clear` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/clear>

alarms.get()
============



Gets an alarm, given its name.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getAlarm = browser.alarms.get(
  name                   // optional string
)

```
### Parameters


 
`name` Optional
  `string`. The name of the alarm to get. If you don't supply this, the empty string "" will be used.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `[`Alarm`](alarm)` object. This represents the alarm whose name matches `name`. If no alarms match, this will be `undefined`.

Examples
--------



```
function gotAlarm(alarm) {
  if (alarm) {
    console.log(alarm.name);
  }
}

let getAlarm = browser.alarms.get("my-periodic-alarm");
getAlarm.then(gotAlarm);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/get>

alarms.getAll()
===============



Gets all active alarms for the extension.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getAlarms = browser.alarms.getAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`Alarm`](alarm) objects. Each of these represents an active alarm that belongs to the extension. If no alarms are active, the array will be empty.

Examples
--------



```
function gotAll(alarms) {
  for (const alarm of alarms) {
    console.log(alarm.name);
  }
}

browser.alarms.getAll().then(gotAll);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/getAll>

BrowserSetting
==============



A `BrowserSetting` is an object representing a browser setting.

 It provides methods to set and get the setting's underlying value, to clear any change you've made to it, and to listen for changes to its value.

 Note that while this object is based on the [ChromeSetting](https://developer.chrome.com/docs/extensions/reference/types/#type-ChromeSetting) type, this object does not distinguish between setting the value in normal browsing windows and in private browsing windows. This means that all parts of the API relating to private browsing (such as the `scope` option to `ChromeSetting.set()`) are not implemented.



Methods
-------


 [`types.BrowserSetting.get()`](browsersetting/get)  Get the current value of the setting, and an enumeration representing how the setting is currently controlled.

  [`types.BrowserSetting.set()`](browsersetting/set)  Set the setting to a new value.

  [`types.BrowserSetting.clear()`](browsersetting/clear)  Clear any change made to the setting by this extension.

  Events
------


 [`types.BrowserSetting.onChange`](browsersetting/onchange)  Fired when the setting's value changes.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BrowserSetting` | Yes | 79 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `onChange` | Yes | 79 | 72 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.types`](https://developer.chrome.com/docs/extensions/reference/types/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting>

set()
=====



Use `BrowserSetting.set()` to change the browser setting to a new value.

 There are some rules that can restrict when extensions are able to change settings:

 * some settings are locked, so they can't be changed by extensions at all
* if multiple extensions try to modify the same setting, then extensions are given a precedence ordering based on when they were installed. More-recently installed extensions have precedence over less-recently installed extension.

 This means that if extension X tries to change a setting:

 1. If the setting is locked, then the setting is not changed. However, X's change is remembered, and it is stored in a queue, ordered by X's precedence relative to any other extensions that tried to change the setting. If the setting becomes unlocked later on, the first extension in the queue gets to change the setting.
2. Otherwise, if no other extension has already changed the setting, then X succeeds in changing the setting, and is then said to "control" the setting.
3. Otherwise, if a lower-precedence extension Y has already changed the setting, then X succeeds in changing the setting, and now controls the setting. However, Y's change is remembered, and is stored in a queue in precedence order. If X subsequently clears its value, or if X is disabled or uninstalled, the first extension in the queue gets to make its change to the setting.
4. Otherwise, if a higher-precedence extension Z has already changed the setting, then X does not succeed in changing the setting, but its change is queued. If Z subsequently clears its value, or if Z is disabled or uninstalled, the first extension in the queue gets to make its change to the setting.

 An extension can find out which of these scenarios applies by examining the "`levelOfControl`" property returned from a call to [`BrowserSetting.get()`](get).

 The `BrowserSetting.set()` method returns a Promise that resolves to a boolean: if an attempt to change a setting actually results in the setting being changed (scenarios 2 and 3 above) the boolean is `true`: otherwise it is `false`.



Syntax
------



```
let setting = setting.set(
  details     // object
)

```
### Parameters


 `details`  An object that must contain the following property:

  `value`  `any`. The value you want to change the setting to. Its type depends on the particular setting.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a `boolean`: `true` if the setting was modified, `false` otherwise (for example, because the extension did not control the setting).

Browser compatibility
---------------------

Example
-------



Modify the `hyperlinkAuditingEnabled` setting (this requires the "privacy" permission):

 
```
function onSet(result) {
  if (result) {
    console.log("Value was updated");
  } else {
    console.log("Value was not updated");
  }
}

browser.browserAction.onClicked.addListener(() => {

    let setting = browser.privacy.websites.hyperlinkAuditingEnabled.set({
      value: false
    });
    setting.then(onSet);

});

```
  **Note:**

 This API is based on Chromium's [`chrome.types`](https://developer.chrome.com/docs/extensions/reference/types/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting/set>

browserSettings.allowPopupsForUserEvents
========================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to enable or disable the ability of web pages to open popups in response to user actions.

 The underlying value is a boolean.

 By default, browsers allow web pages to open popups in response to a particular set of events: for example, [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event), [mouseup](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseup_event), [submit](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event). If `allowPopupsForUserEvents` is set to `false`, no user events will be able to open popups. If it is set to `true`, the default set of events will be allowed to open popups.

 For example, suppose a web page has code like this:

 
```
window.addEventListener("click", (e) => {
  window.open("https://example.com", "myPopup", "height=400,width=400");
});

```
 By default, this will open a popup window. If your extension sets `allowPopupsForUserEvents` to `false`, then it will not open a popup, and the user will be informed that the popup was blocked.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `allowPopupsForUserEvents` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Toggle the setting:

 
```
function toggleAllowPopup() {
  function toggle(current) {
    console.log(`Current value: ${current.value}`);
    browser.browserSettings.allowPopupsForUserEvents.set({
      value: !current.value,
    });
  }

  browser.browserSettings.allowPopupsForUserEvents.get({}).then(toggle);
}

browser.browserAction.onClicked.addListener(() => {
  toggleAllowPopup();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/allowPopupsForUserEvents>

browserSettings.cacheEnabled
============================



A [`BrowserSetting`](../types/browsersetting) object that can be used to globally enable or disable the browser cache.

 The underlying value is a boolean.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `cacheEnabled` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |


Examples
--------



Getting the current value of this setting:

 
```
function logResult(result) {
  console.log(`Current value: ${result.value}`);
  console.log(`Current level of control: ${result.levelOfControl}`);
}

browser.browserSettings.cacheEnabled.get({}).then(logResult);

```
 Disabling the browser cache:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.cacheEnabled.set({ value: false }).then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/cacheEnabled>

alarms.Alarm
============


Information about a single alarm. This object is returned from [`alarms.get()`](get) and [`alarms.getAll()`](getall), and is passed into the [`alarms.onAlarm`](onalarm) listener.


Type
----



Values of this type are objects. They contain the following properties:

  `name`  `string`. Name of this alarm. This is the name that was passed into the [`alarms.create()`](create) call that created this alarm.

  `scheduledTime`  `double`. Time at which the alarm is scheduled to fire next, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  
`periodInMinutes` Optional
  `double`. If this is not `null`, then the alarm is periodic, and this represents its period in minutes.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Alarm` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/alarms/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/Alarm>

browserSettings.closeTabsByDoubleClick
======================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to enable or disable the user's ability to close a tab using double-click.

 The underlying value is a boolean.

 By default, closeTabsByDoubleClick is false. The setting can be changed by the user in about:config.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `closeTabsByDoubleClick` | No | No | 61 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/closeTabsByDoubleClick>

browserSettings.colorManagement
===============================



A [`BrowserSetting`](../types/browsersetting) object used to query and set the browser's color management features.

 By default, Firefox applies color management to tagged media and defaults to sRGB for untagged media. This behavior means that some untagged media, such as that used in animation and movie production, may have undesired color corrections made to it. Use these settings to prevent that.

 The object has these properties:

  `mode`  A string that represents the mode used for color management. Valid values are `off`, `full`, and `tagged_only`.

  `useNativeSRGB`  A boolean representing whether or not built-in sRGB color management is used.

  `useWebRenderCompositor`  A boolean representing whether or not the WebRender compositor is used.

  

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `colorManagement` | No | No | 91 | ? | No | No | ? | ? | 91 | ? | No | ? |


Examples
--------



Set color mode to "full":

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.colorManagement.mode
  .set({ value: "full" })
  .then(logResult);

```
 Get the native sRGB color management color mode:

 
```
function logResult(result) {
  console.log(`Current useNativeSRGB value: ${result.value}`);
}

browser.browserSettings.colorManagement.useNativeSRGB.get({}).then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/colorManagement>

browserSettings.contextMenuShowEvent
====================================



A [`BrowserSetting`](../types/browsersetting) object which determines whether the browser's context menu is shown on the mouseup event or on the mousedown event.

 Its underlying value is a string that may be either "mouseup" or "mousedown".

 The default value is "mouseup" on Windows, and "mousedown" on macOS and Linux. Assigning to it on Windows has no effect - the setting is only designed to allow the context menu to be opened on mouseup instead of mousedown, not the inverse.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `contextMenuShowEvent` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Examples
--------



Set the setting to "mouseup":

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.contextMenuShowEvent
  .set({ value: "mouseup" })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/contextMenuShowEvent>

browserSettings.imageAnimationBehavior
======================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to change the way the browser handles animated images, such as GIFs.

 The underlying value is a string that can take one of three values:

 * "normal": the default. Play animated images as normal.
* "none": don't animate images at all.
* "once": play the animation once.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `imageAnimationBehavior` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Disable animated images:

 
```
browser.browserSettings.imageAnimationBehavior.set({ value: "none" });

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/imageAnimationBehavior>

browserSettings.newTabPageOverride
==================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to get a string representing the URL for the "new tab" page: that is, the page that's loaded when the user opens a new empty tab.

 Note that this is a read-only setting.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `newTabPageOverride` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Get the current value of the new tab URL:

 
```
browser.browserSettings.newTabPageOverride.get({}).then((result) => {
  console.log(result.value);
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/newTabPageOverride>

browserSettings.openBookmarksInNewTabs
======================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 If set to `true`, then when the user selects a bookmark, it will be opened in a new tab. If set to `false` (the default) bookmarks are opened in the current tab.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openBookmarksInNewTabs` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Examples
--------



Set the setting to `true`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.openBookmarksInNewTabs
  .set({ value: true })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/openBookmarksInNewTabs>

browserSettings.openSearchResultsInNewTabs
==========================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 If set to `true`, then when the user selects a term in the browser's search box, the search results are displayed in a new tab. If set to `false` (the default) the search results are shown in the current tab.

 Note that this does not affect the behavior when selecting items from the omnibox/awesomebar,only the dedicated search box.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openSearchResultsInNewTabs` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Examples
--------



Set the setting to `true`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.openSearchResultsInNewTabs
  .set({ value: true })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/openSearchResultsInNewTabs>

browserSettings.ftpProtocolEnabled
==================================



A [`BrowserSetting`](../types/browsersetting) object that determines whether the FTP protocol is enabled in the browser.

 The underlying value is a boolean.

  **Note:** From Firefox version 88 this setting is read-only.

 

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ftpProtocolEnabled` | No | No | 72From version 88, this setting is read-only (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | No | ? | ? | 79From version 88, this setting is read-only (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | ? |


Examples
--------



Toggle the setting:

 
```
function toggleAllowFtp() {
  function toggle(current) {
    console.log(`Current value: ${current.value}`);
    browser.browserSettings.ftpProtocolEnabled.set({ value: !current.value });
  }

  browser.browserSettings.ftpProtocolEnabled.get({}).then(toggle);
}

browser.browserAction.onClicked.addListener(() => {
  toggleAllowFtp();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/ftpProtocolEnabled>

browserSettings.homepageOverride
================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to get a string representing the URL currently set as the browser's homepage.

 Note that this is a read-only setting. To change the homepage, see [chrome\_settings\_overrides](../../manifest.json/chrome_settings_overrides).



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `homepageOverride` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Get the current value of the homepage URL:

 
```
browser.browserSettings.homepageOverride.get({}).then((result) => {
  console.log(result.value);
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/homepageOverride>

browserSettings.newTabPosition
==============================



A [`BrowserSetting`](../types/browsersetting) object that can be used to control the position of newly opened tabs relative to already open tabs.

 The underlying value is a string that can take one of three values:

 * "afterCurrent": Open all new tabs next to the current tab.
* "relatedAfterCurrent": The default. Open new tabs next to the current tab if they are related to the current tab (for example, if they were opened via a link in the current tab). Otherwise, open new tabs at the end of the tabstrip.
* "atEnd": Open all tabs at the end of the tabstrip.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `newTabPosition` | No | No | 61 | ? | No | No | ? | ? | 61This setting can be changed but has no effect. | ? | No | ? |


Examples
--------



This code sets the value to "afterCurrent" and then logs the new value:

 
```
async function setAfterCurrent() {
  let result = await browser.browserSettings.newTabPosition.set({
    value: "afterCurrent",
  });
  console.log(`Result: ${result}`);
  let newValue = await browser.browserSettings.newTabPosition.get({});
  console.log(`New value: ${newValue.value}`);
}

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/newTabPosition>

browserSettings.openUrlbarResultsInNewTabs
==========================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 When the user focuses the address bar and starts typing, the browser offers autocomplete suggestions: a dropdown list of web pages based on the user's incomplete input and their browsing history.

 If set to `true`, then when the user selects one of these items, the item is opened in a new tab. If set to `false` (the default) the item is opened in the current tab.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openUrlbarResultsInNewTabs` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |


Examples
--------



Set the setting to `true`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.openUrlbarResultsInNewTabs
  .set({ value: true })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/openUrlbarResultsInNewTabs>

browserSettings.useDocumentFonts
================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 By default, of course, web pages can specify the fonts they want using CSS properties like [`font-family`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family). This setting enables an extension to instruct Firefox to ignore the fonts specified by the page, and only use system fonts.

 Its underlying value is a boolean:

 * `true`: use the fonts specified by the web page. This is the default.
* `false`: use the system fonts.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `useDocumentFonts` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |


Examples
--------



Set the setting to `false`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.useDocumentFonts.set({ value: false }).then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/useDocumentFonts>

browserSettings.webNotificationsDisabled
========================================



A [`BrowserSetting`](../types/browsersetting) object that can be used to prevent websites from showing notifications using the [`Notifications`](https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API) Web API.

 The `Notifications` API is used to display desktop notifications to the user. There are three levels of permission for notifications: *allow*, *deny*, and *prompt*. Users can set this permission for every site. If the user has not set a permission for a particular site, then the browser will fall back to a global permission, which defaults to *prompt*.

 Setting `browserSettings.webNotificationsDisabled` to `true` switches the global permission to *deny*.

 Note that this won't affect sites for which the user has set a per-site preference. For example, if the user sets <https://example.org> to *allow*, and an extension then sets `browserSettings.webNotificationsDisabled` to `true`, then pages under <https://example.org> will still be allowed to show notifications.

 Setting `browserSettings.webNotificationsDisabled` to `false` switches the global default back to its default value.

 Note that this setting has no effect on notifications created by extensions using the [`notifications`](../notifications) API.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `webNotificationsDisabled` | No | No | 58 | ? | No | No | ? | ? | 58 | ? | No | ? |


Examples
--------



Toggle the setting:

 
```
async function toggleWebNotifications() {
  let current = await browser.browserSettings.webNotificationsDisabled.get({});
  console.log(`Current value: ${current.value}`);
  browser.browserSettings.webNotificationsDisabled.set({
    value: !current.value,
  });
}

browser.browserAction.onClicked.addListener(() => {
  toggleWebNotifications();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/webNotificationsDisabled>

browserSettings.zoomSiteSpecific
================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 This property sets the [configuration setting](https://support.mozilla.org/en-US/kb/about-config-editor-firefox) `browser.zoom.siteSpecific`, which controls how zoom settings are applied to sites and tabs.

 If `browser.zoom.siteSpecific` is true, zoom operations apply to all pages from the same site so that:

 * when a page loads, if there is a zoom level for that site it is applied to the page otherwise the global default zoom level is applied.
* when the zoom level for a page changes, the zoom levels of other pages from the site in other tabs are also changed.

 If `browser.zoom.siteSpecific` is set false, zoom operations apply to the active tab only so that:

 * when a new tab opens, the global default zoom level is applied.
* when the zoom level in a tab changes, it persists across page loads and does not affect the zoom level in any other tab.

 When Firefox is installed, `browser.zoom.siteSpecific` is true.

 If [`privacy.websites`](../privacy/websites)`.resistFingerprinting` is true, this setting has no effect and zoom is set on a per-tab basis.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `zoomSiteSpecific` | No | No | 75 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Set the setting to `false`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.zoomSiteSpecific.set({ value: false }).then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/zoomSiteSpecific>

browserSettings.overrideContentColorScheme
==========================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a string.

 Firefox enables users to choose a theme for the browser UI. These themes apply either a light or dark theme to webpages. Using the `layout.css.prefers-color-scheme.content-override` preference, users can override the theme and choose to render webpages in a light or dark theme or follow the device's theme. This browser setting exposes that preference.

 This object takes these values:

 * "light": Applies a light theme to webpages.
* "dark": Applies a dark theme to webpages.
* "system": Applies a light or dark theme to webpages based on the device's theme.
* "browser": Applies a light or dark theme to webpages based on the browser's theme.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `overrideContentColorScheme` | No | No | 95 | ? | No | No | ? | ? | 95 | ? | No | ? |


Examples
--------



This example overrides the setting to use the dark theme for webpages:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.overrideContentColorScheme
  .set({ value: "dark" })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/overrideContentColorScheme>

browserSettings.overrideDocumentColors
======================================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a string.

 Firefox enables the user to set their own colors for document backgrounds and text. By default these values are only applied when a high-contrast theme is selected (a high-contrast theme is a feature of some operating system UIs that increases the contrast for improved accessibility). However, users can also choose to apply these colors always or never. This browser setting exposes that preference.

 Its underlying value is a string that may take any one of the following values:

 * "high-contrast-only": Apply the user's choices only when a high-contrast theme is selected. This is the default.
* "never": Never apply the user's choices.
* "always": Always apply the user's choices.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `overrideDocumentColors` | No | No | 61 | ? | No | No | ? | ? | 61 | ? | No | ? |


Examples
--------



Set the setting to "always":

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.overrideDocumentColors
  .set({ value: "always" })
  .then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/overrideDocumentColors>

browserSettings.tlsVersionRestrictionConfig
===========================================



A [`BrowserSetting`](../types/browsersetting) object used to read the highest and lowest versions of TLS supported by the browser.

 The object has these properties:

  `minimum`  The lowest TLS version supported by the browser. Valid values are `TLSv1`, `TLSv1.1`, `TLSv1.2`, `TLSv1.3`, and `unknown`.

  `maximum`  The highest TLS version supported by the browser. Valid values are `TLSv1`, `TLSv1.1`, `TLSv1.2`, `TLSv1.3`, and `unknown`.

   This is a read-only setting.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `tlsVersionRestrictionConfig` | No | No | 72 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Get the highest TLS version supported by the browser:

 
```
browser.browserSettings.tlsVersionRestrictionConfig.maximum
  .get({})
  .then((result) => {
    console.log(`Highest TLS version supported: ${result}`);
  });

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/tlsVersionRestrictionConfig>

browserSettings.zoomFullPage
============================



A [`BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 By default zoom applies to all the content of a web page. Using the [Zoom Text Only setting](https://support.mozilla.org/en-US/kb/font-size-and-zoom-increase-size-of-web-pages#w_how-to-only-change-the-size-of-the-text/en-US/docs/) users can choose to zoom only the text on a page. This settings enables web extensions to control this setting and determine whether zoom is applied to the entire page or to text only.

 The settings are:

 * `true`: zoom applies to all the content of a web page (default).
* `false`: zoom applies to web page text only.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `zoomFullPage` | No | No | 75 | ? | No | No | ? | ? | 79 | ? | No | ? |


Examples
--------



Set the setting to `false`:

 
```
function logResult(result) {
  console.log(`Setting was modified: ${result}`);
}

browser.browserSettings.zoomFullPage.set({ value: false }).then(logResult);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings/zoomFullPage>

privacy.websites
================



The [`privacy.websites`](websites) property contains privacy-related settings controlling the way to browser interacts with websites. Each property is a [`types.BrowserSetting`](../types/browsersetting) object.

 Default values for these properties tend to vary across browsers.



Properties
----------


 `cookieConfig`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is an object.

 The object has two properties:

 * `behavior`: a string which may take any of the following values:
	+ "allow\_all": accept all cookies
	+ "reject\_all": reject all cookies
	+ "reject\_third\_party": reject all third-party cookies
	+ "allow\_visited": accept a third-party cookie only if the cookie's top-level domain already has at least one cookie.
	+ "reject\_trackers": reject tracking cookies
	+ "reject\_trackers\_and\_partition\_foreign": reject trackers and partition third-party cookies.
* `nonPersistentCookies`  Deprecated : a boolean. If true, all cookies will be treated as session cookies.

  `firstPartyIsolate`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 If `true`, the `firstPartyIsolate` preference makes the browser associate all data (including cookies, HSTS data, cached images, and more) for any third party domains with the domain in the address bar. This prevents third party trackers from using directly stored information to identify the user across different websites, but may break websites where the user logs in with a third party account (such as a Facebook or Google account).

 Defaults to `false`.

  `hyperlinkAuditingEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If `true`, the browser sends auditing pings when a website uses the `ping` attribute to request them.

  `protectedContentEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. Available on Windows only. If `true`, the browser provides a unique ID to plugins in order to run protected content.

  `referrersEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If enabled, the browser sends [referer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) headers with your requests.

  `resistFingerprinting`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean.

 Browser fingerprinting is the practice by which websites use Web APIs to collect status or configuration data associated with the browser or the device it's running on. By doing this, they can build up a digital fingerprint that they can use to identify and track a particular user.

 If `true`, the `resistFingerprinting` preference makes the browser report generic spoofed information for data that's commonly used for fingerprinting. Such data includes the number of CPU cores, precision of JavaScript timers, and the local timezone. It will also disable features that are used in fingerprinting, such as GamePad support, and the WebSpeech and Navigator APIs.

 Defaults to `false`.

  `thirdPartyCookiesAllowed`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If `false`, the browser blocks [third-party cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#third-party_cookies).

  `trackingProtectionMode`  "Tracking protection" is a browser feature that blocks requests made to domains that are known to engage in cross-site tracking of users. Sites that track users are most commonly third-party advertising and analytics sites. This setting is a [`types.BrowserSetting`](../types/browsersetting) object that determines whether the browser should enable tracking protection. Its underlying value is a string that may take one of three values:

 * `"always"`: tracking protection is on.
* `"never"`: tracking protection is off.
* `"private_browsing"`: tracking protection is on in private browsing windows only.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `cookieConfig` | No | No | 59["The `behavior` property value \"reject\_trackers\_and\_partition\_foreign\" was introduced in version 78.", "The `behavior` property value \"reject\_trackers\" was introduced in version 64."] | ? | No | No | ? | ? | 59The `behavior` property value "reject\_trackers" was introduced in version 64. | ? | No | ? |
| `firstPartyIsolate` | No | No | 58 | ? | No | No | ? | ? | 58 | ? | No | ? |
| `hyperlinkAuditingEnabled` | Yes | 79 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `protectedContentEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `referrersEnabled` | Yes | 79 | 56 | ? | Yes | No | ? | ? | 56 | ? | No | ? |
| `resistFingerprinting` | No | No | 58 | ? | No | No | ? | ? | 58 | ? | No | ? |
| `thirdPartyCookiesAllowed` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `trackingProtectionMode` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Set the `hyperlinkAuditingEnabled` property.

 
```
function onSet(result) {
  if (result) {
    console.log("success");
  } else {
    console.log("failure");
  }
}

browser.browserAction.onClicked.addListener(() => {

  let getting = browser.privacy.websites.hyperlinkAuditingEnabled.get({});
  getting.then((got) => {
    console.log(got.value);
    if ((got.levelOfControl === "controlled\_by\_this\_extension") ||
        (got.levelOfControl === "controllable\_by\_this\_extension")) {
      let setting = browser.privacy.websites.hyperlinkAuditingEnabled.set({
        value: true
      });
      setting.then(onSet);
    } else {
      console.log("Not able to set hyperlinkAuditingEnabled");
    }
  });

});

```
  **Note:** This API is based on Chromium's [`chrome.privacy`](https://developer.chrome.com/docs/extensions/reference/privacy/) API. This documentation is derived from [`privacy.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/privacy.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/websites>

captivePortal.canonicalURL
==========================


Return the canonical URL of the captive-portal detection page. Read-only.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `canonicalURL` | No | No | 72 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.tabs`](https://developer.chrome.com/docs/extensions/reference/tabs/#property-TAB_ID_NONE) API. This documentation is derived from [`tabs.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal/canonicalURL>

getLastChecked
==============


Returns the time since the last request was completed.


Syntax
------



```
let state = browser.captivePortal.getLastChecked()

```
### Return value


A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with an integer representing time in milliseconds.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getLastChecked` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal/getLastChecked>

getState
========


Returns the portal state as one of `unknown`, `not_captive`, `unlocked_portal`, or `locked_portal`.


Syntax
------



```
let state = browser.captivePortal.getState()

```
### Return value


A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with a string containing one of `unknown`, `not_captive`, `unlocked_portal`, or `locked_portal`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getState` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal/getState>

clipboard.setImageData()
========================



Copies an image to the clipboard. The image is re-encoded before it is written to the clipboard. If the image is invalid, the clipboard is not modified.

 The image is provided as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) containing the encoded image. JPEG and PNG formats are supported.

 Although this API is based on Chrome's [`clipboard.setImageData()`](https://developer.chrome.com/docs/extensions/reference/clipboard/) API, there are some differences:

 * The Chrome API is only for apps, not extensions.
* This API requires only the `"clipboardWrite"` permission, while the Chrome version also requires the `"clipboard"` permission.
* Chrome's API uses callbacks, and this API only supports promises.
* This API does not support the `additionalItems` parameter.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.clipboard.setImageData(imageData, imageType)

```
### Parameters


 `imageData`  An [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) containing the encoded image data to copy to the clipboard.

  `imageType`  A string indicating the type of image contained in `imageData`: `"png"` or `"jpeg"`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved with no arguments if the operation succeeded, or rejected if there was an error (for example, because the data did not represent a valid image).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setImageData` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



Copy a remote image:

 
```
// requires:
// \* the host permission for "https://cdn.mdn.mozilla.net/\*"
// \* the API permission "clipboardWrite"

fetch("https://cdn.mdn.mozilla.net/static/img/favicon144.png")
  .then((response) => response.arrayBuffer())
  .then((buffer) => browser.clipboard.setImageData(buffer, "png"));

```
 Copy an image that was bundled with the extension:

 
```
// requires the API permission "clipboardWrite"

fetch(browser.runtime.getURL("image.png"))
  .then((response) => response.arrayBuffer())
  .then((buffer) => browser.clipboard.setImageData(buffer, "png"));

```
  **Note:** This API is based on Chromium's [`chrome.clipboard`](https://developer.chrome.com/docs/extensions/reference/clipboard/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData>

onConnectivityAvailable
=======================


Fires when the captive portal service determines that the user can connect to the internet.


Syntax
------




```
browser.captivePortal.onConnectivityAvailable.addListener(callback)
browser.captivePortal.onConnectivityAvailable.removeListener(listener)
browser.captivePortal.onConnectivityAvailable.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that is called when this event occurs. The function is passed the following arguments:

  `status`  `string` The status of the service, being one of `captive` if there is an unlocked captive portal present or `clear` if no captive portal is detected.

    Examples
--------



Handle a change user's ability to connect to the internet:

 
```
function handleConnectivity(connectivityInfo) {
  console.log(`The captive portal status: ${connectivityInfo.status}`);
}

browser.captivePortal.onConnectivityAvailable.addListener(handleConnectivity);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onConnectivityAvailable` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal/onConnectivityAvailable>

onStateChanged
==============


Fires when the captive portal state changes.


Syntax
------




```
browser.captivePortal.onStateChanged.addListener(callback)
browser.captivePortal.onStateChanged.removeListener(listener)
browser.captivePortal.onStateChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that is called when this event occurs. The function is passed the following arguments:

  `details`  `string` The captive portal state, being one of `unknown`, `not_captive`, `unlocked_portal`, or `locked_portal`.

    Examples
--------



Handle a change in captive portal status:

 
```
function handlePortalStatus(portalstatusInfo) {
  console.log(`The portal status is now: ${portalstatusInfo.details}`);
}

browser.captivePortal.onStateChanged.addListener(handlePortalStatus);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onStateChanged` | No | No | 68 | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal/onStateChanged>

Command
=======



Information about a command. This contains the information specified for the command in the [`commands` manifest.json key](../../manifest.json/commands).

 An array of these objects is returned from [`commands.getAll()`](getall).



Type
----



Values of this type are objects. They contain the following properties:

  
`name` Optional
  `string`. Name of this command. This will be passed into the [`commands.onCommand`](oncommand) event listener.

  
`description` Optional
  `string`. Description of this command. This is primarily used to explain to the user what this command does.

  
`shortcut` Optional
  `string`. Key(s) used to execute this command, specified as a string like "Ctrl+Shift+Y".

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Command` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `name` | Yes | 79 | 48 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `tab` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.commands`](https://developer.chrome.com/docs/extensions/reference/commands/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands/Command>

bookmarks.BookmarkTreeNode
==========================


An object of type `bookmarks.BookmarkTreeNode` represents a node in the bookmark tree, where each node is a bookmark, a bookmark folder, or a separator. Child nodes are ordered by an `index` within their respective parent folders.


Type
----



An [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) with the following properties:

  
`children` Optional
  An [`array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of [`bookmarks.BookmarkTreeNode`](bookmarktreenode) objects which represent the node's children. The list is ordered in the list in which the children appear in the user interface. This field is omitted if the node isn't a folder.

  
`dateAdded` Optional
  A number representing the creation date of the node in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  
`dateGroupModified` Optional
  A number representing the date and time the contents of this folder last changed, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which uniquely identifies the node. Each ID is unique within the user's profile and remains unchanged across browser restarts.

  
`index` Optional
  A number which represents the zero-based position of this node within its parent folder, where zero represents the first entry.

  **Note:** If you create or move multiple bookmarks, because the [`bookmarks.create()`](create) and [`bookmarks.move()`](move) methods are asynchronous, the requests may get processed in any order. Consequently, the value of each bookmark's index may change or be unknown until all the requests are completed. If the index associated with a bookmark matters to your extension, then – when creating or moving multiple bookmarks – the extension should wait for each `bookmarks.create` or `bookmarks.move` call to complete before creating or moving the next bookmark. Waiting ensures that the index associated with each bookmark is not affected by a create or move call executing concurrently while the original call is in progress.

   
`parentId` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which specifies the ID of the parent folder. This property is not present in the root node.

  `title`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which contains the text displayed for the node in menus and lists of bookmarks.

  
`type` Optional
  A [`bookmarks.BookmarkTreeNodeType`](bookmarktreenodetype) object indicating whether this is a bookmark, a folder, or a separator. Defaults to `"bookmark"` unless `url` is omitted, in which case it defaults to `"folder"`.

  
`unmodifiable` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) as described by the type [`bookmarks.BookmarkTreeNodeUnmodifiable`](bookmarktreenodeunmodifiable). Represents the reason that the node can't be changed. If the node can be changed, this is omitted.

  
`url` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which represents the URL for the bookmark. If the node represents a folder, this property is omitted.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BookmarkTreeNode` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `type` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#type-BookmarkTreeNode) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/BookmarkTreeNode>

bookmarks.BookmarkTreeNodeUnmodifiable
======================================


The `bookmarks.BookmarkTreeNodeUnmodifiable` type is used to indicate the reason that a node in the bookmark tree (where each node is either a bookmark or a bookmark folder) cannot be changed. This is used as the value of the [`bookmarks.BookmarkTreeNode.unmodifiable.unmodifiable`](bookmarktreenode#unmodifiable) field on bookmark nodes.


Type
----


`bookmarks.BookmarkTreeNodeUnmodifiable` is a [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which can currently have only one value: `"managed"`. This indicates that the bookmark node was configured by an administrator or by the custodian of a supervised user (such as a parent, in the case of parental controls).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BookmarkTreeNodeUnmodifiable` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#type-BookmarkTreeNodeUnmodifiable) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/BookmarkTreeNodeUnmodifiable>

bookmarks.CreateDetails
=======================


The `CreateDetails` type is used to describe the properties of a new, bookmark, bookmark folder, or separator when calling the [`bookmarks.create()`](create) method.


Type
----



An [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) containing some combination of the following fields:

  
`index` Optional
  An integer [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) which specifies the position at which to place the new bookmark under its parent. A value of 0 will put it at the top of the list.

  
`parentId` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which indicates the ID of the parent folder into which to place the new bookmark or bookmark folder. On Chrome and Firefox, the default is the "Other Bookmarks" folder on the Bookmarks menu.

  
`title` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which specifies the title for the bookmark or the name of the folder to be created. If this isn't specified, the title is `""`.

  
`type` Optional
  A [`bookmarks.BookmarkTreeNodeType`](bookmarktreenodetype) object indicating whether this is a bookmark, a folder, or a separator. Defaults to `"bookmark"` unless `url` is omitted, in which case it defaults to `"folder"`.

  
`url` Optional
  `string`. A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which specifies the URL of the page to bookmark. If this is omitted or is `null`, a folder is created instead of a bookmark.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CreateDetails` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `type` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#type-CreateDetails) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/CreateDetails>

bookmarks.get()
===============



Given the ID of a [`bookmarks.BookmarkTreeNode`](bookmarktreenode) or an array of such IDs, the `bookmarks.get()` method retrieves the matching nodes.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getBookmarks = browser.bookmarks.get(
  idOrIdList                // string or string array
)

```
### Parameters


 `idOrIdList`  `string` A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) or [`array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of strings specifying the IDs of one or more [`BookmarkTreeNode`](bookmarktreenode) objects to retrieve.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`BookmarkTreeNode`](bookmarktreenode), one for each matching node. Separators are not included in the results. If no nodes could be found, the promise will be rejected with an error message.

Examples
--------



This example tries to get the bookmark whose ID is `bookmarkAAAA`. If no bookmark with this ID exists, `onRejected` is called:

 
```
function onFulfilled(bookmarks) {
  console.log(bookmarks);
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let gettingBookmarks = browser.bookmarks.get("bookmarkAAAA");
gettingBookmarks.then(onFulfilled, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-get) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/get>

bookmarks.getChildren()
=======================



`bookmarks.getChildren()` retrieves all the immediate children of a given bookmark folder, identified as a [`BookmarkTreeNode`](bookmarktreenode) ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingChildren = browser.bookmarks.getChildren(
  id                     // string
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which specifies the ID of the folder whose children are to be retrieved.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`BookmarkTreeNode`](bookmarktreenode) objects. Each entry represents a single child node. The list is ordered in the same order in which the bookmarks appear in the user interface. Separators are currently not included in the results. The list includes subfolders, but does not include any children contained in subfolders.

 If the specified node has no children, the array is empty.

 If the node identified by `id` is not found, the promise is rejected with an error message.


Examples
--------



```
function onFulfilled(children) {
  for (child of children) {
    console.log(child.id);
  }
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let gettingChildren = browser.bookmarks.getChildren("unfiled\_\_\_\_\_");
gettingChildren.then(onFulfilled, onRejected);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getChildren` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-getChildren) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/getChildren>

bookmarks.getRecent()
=====================



The `bookmarks.getRecent()` method retrieves a specified number of the most recently added bookmarks as an array of [`BookmarkTreeNode`](bookmarktreenode) objects.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingRecent = browser.bookmarks.getRecent(
  numberOfItems          // integer
)

```
### Parameters


 `numberOfItems`  A number representing the maximum number of items to return. The returned list will contain up to this many of the most recently added items. The minimum allowed value here is 1. If you pass 0 or less, the function will throw an error.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of [`BookmarkTreeNode`](bookmarktreenode) objects.

Examples
--------



This example logs the URL for the most recently added bookmark:

 
```
function onFulfilled(bookmarks) {
  for (const bookmark of bookmarks) {
    console.log(bookmark.url);
  }
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

browser.bookmarks.getRecent(1).then(onFulfilled, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getRecent` | Yes | 79 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-getRecent) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/getRecent>

bookmarks.getSubTree()
======================



The `bookmarks.getSubTree()` method asynchronously retrieves a [`bookmarks.BookmarkTreeNode`](bookmarktreenode), given its ID.

 If the item is a folder, you can access all its descendants recursively using its `children` property and the `children` property of its descendants, if they are themselves folders.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingSubTree = browser.bookmarks.getSubTree(
  id                     // string
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) specifying the ID of the root of the subtree to retrieve.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array containing a single object, a [`bookmarks.BookmarkTreeNode`](bookmarktreenode) object, representing the item with the given ID.

 If a node corresponding to `id` could not be found, the promise will be rejected with an error message.


Examples
--------



This example recursively prints out the subtree under a given node:

 
```
function makeIndent(indentLength) {
  return ".".repeat(indentLength);
}

function logItems(bookmarkItem, indent) {
  if (bookmarkItem.url) {
    console.log(makeIndent(indent) + bookmarkItem.url);
  } else {
    console.log(`${makeIndent(indent)}Folder: ${bookmarkItem.id}`);
    indent++;
  }
  if (bookmarkItem.children) {
    for (const child of bookmarkItem.children) {
      logItems(child, indent);
    }
  }
}

function logSubTree(bookmarkItems) {
  logItems(bookmarkItems[0], 0);
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let subTreeID = "root\_\_\_\_\_";

browser.bookmarks.getSubTree(subTreeID).then(logSubTree, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getSubTree` | Yes | 79 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-getSubTree) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/getSubTree>

bookmarks.BookmarkTreeNodeType
==============================


The `bookmarks.BookmarkTreeNodeType` type is used to describe whether a node in the bookmark tree is a bookmark, a folder, or a separator.


Type
----



`bookmarks.BookmarkTreeNodeType` is a [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which can have one of the following three values:

 * `"bookmark"`: the node is a bookmark.
* `"folder"`: the node is a folder.
* `"separator"`: the node is a separator.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BookmarkTreeNodeType` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/BookmarkTreeNodeType>

bookmarks.getTree()
===================



`bookmarks.getTree()` returns an array containing the root of the bookmarks tree as a [`bookmarks.BookmarkTreeNode`](bookmarktreenode) object.

 You can access the entire tree recursively using its `children` property and the `children` property of its descendants, if they are themselves folders.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingTree = browser.bookmarks.getTree()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array containing one object, a [`bookmarks.BookmarkTreeNode`](bookmarktreenode) object representing the root node.

Examples
--------



This example prints out the entire bookmarks tree:

 
```
function makeIndent(indentLength) {
  return ".".repeat(indentLength);
}

function logItems(bookmarkItem, indent) {
  if (bookmarkItem.url) {
    console.log(makeIndent(indent) + bookmarkItem.url);
  } else {
    console.log(`${makeIndent(indent)}Folder`);
    indent++;
  }
  if (bookmarkItem.children) {
    for (child of bookmarkItem.children) {
      logItems(child, indent);
    }
  }
  indent--;
}

function logTree(bookmarkItems) {
  logItems(bookmarkItems[0], 0);
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let gettingTree = browser.bookmarks.getTree();
gettingTree.then(logTree, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTree` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-getTree) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/getTree>

bookmarks.move()
================



The `bookmarks.move()` method moves the specified [`BookmarkTreeNode`](bookmarktreenode) to the specified destination within the tree of bookmarks. This lets you move a bookmark to a new folder and/or position within the folder.

  **Warning:** If your extension attempts to move a bookmark into the bookmarks tree root node, the call will raise an error with the message: "*The bookmark root cannot be modified*" and the move won't be completed.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let movingBookmark = browser.bookmarks.move(
  id,                    // string
  destination           // object
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) containing the ID of the bookmark or folder to move.

  `destination`  An [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) which specifies the destination for the bookmark. This object must contain one or both of the following fields:

  
`parentId` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) which specifies the ID of the destination folder. If this value is left out, the bookmark is moved to a new location within its current folder.

  
`index` Optional
  A 0-based index specifying the position within the folder to which to move the bookmark. A value of 0 moves the bookmark to the top of the folder. If this value is omitted, the bookmark is placed at the end of the new parent folder.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a single [`bookmarks.BookmarkTreeNode`](bookmarktreenode) object, describing the moved node.

 If the node corresponding to the `id` parameter can't be found, the promise is rejected with an error message.

  **Note:** If you move multiple bookmarks, because this API is asynchronous, the move calls may get processed in any order. Consequently, the value of each bookmark's index returned in [`BookmarkTreeNode`](bookmarktreenode) may change or be unknown until all the move calls are completed. If the index associated with a bookmark matters to your extension, then – when moving multiple bookmarks – the extension should wait for each `bookmarks.move` call to complete before moving the next bookmark. Waiting ensures that the index associated with each bookmark is not affected by a move call executing concurrently while the original call is in progress.

 
Examples
--------



This example moves a bookmark so that it's the first bookmark in its current folder.

 
```
function onMoved(bookmarkItem) {
  console.log(bookmarkItem.index);
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

let bookmarkId = "abcdefghijkl";

let movingBookmark = browser.bookmarks.move(bookmarkId, { index: 0 });
movingBookmark.then(onMoved, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `move` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-move) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/move>

bookmarks.removeTree()
======================



The `bookmarks.removeTree()` method recursively removes a bookmark folder and all of its contents.

  **Warning:** If your extension attempts to remove a bookmark tree from the bookmarks tree root node, the call will raise an error with the message: "The bookmark root cannot be modified" and the bookmark won't be removed.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removingTree = browser.bookmarks.removeTree(
  id                // string
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) specifying the ID of the folder node to be deleted along with its descendants.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the tree has been removed.

 If the node corresponding to the `id` parameter can't be found, the promise is rejected with an error message.


Examples
--------



This example locates a bookmark folder named "MDN" and deletes it along with all of its contents.

 
```
function onRemoved() {
  console.log("bookmark item removed!");
}

function onRejected(error) {
  console.log(`An error: ${error}`);
}

function removeMDN(searchResults) {
  if (searchResults.length) {
    let removing = browser.bookmarks.removeTree(searchResults[0].id);
    removing.then(onRemoved, onRejected);
  }
}

let searchingBookmarks = browser.bookmarks.search({ title: "MDN" });
searchingBookmarks.then(removeMDN, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeTree` | Yes | 15 | 47 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-removeTree) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/removeTree>

bookmarks.onMoved
=================



Fired when a bookmark or folder is moved to a different parent folder or position within a folder.

  **Note:** If you're moving multiple bookmarks, because this API is asynchronous, the move calls may get processed in any order. Consequently, the value of each bookmark's index may change or be unknown until all the move calls are completed. If the index associated with a bookmark matters to your extension, then – when moving multiple bookmarks – the extension should wait for each `bookmarks.move` call to complete before moving the next bookmark. Waiting ensures that the index associated with each bookmark is not affected by a move call executing concurrently while the original call is in progress.

 

Syntax
------




```
browser.bookmarks.onMoved.addListener(listener)
browser.bookmarks.onMoved.removeListener(listener)
browser.bookmarks.onMoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `id`  `string`. ID of the item that was moved.

  `moveInfo`  `object`. Object containing more details about the move. See the [moveInfo](#moveinfo_2) section for more details.

    Additional objects
------------------


### moveInfo


 `parentId`  `string`. The new parent folder.

  `index`  `integer`. The new index of this item in its parent.

  `oldParentId`  `string`. The old parent folder.

  `oldIndex`  `integer`. The old index of the item in its parent.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onMoved` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function handleMoved(id, moveInfo) {
  console.log(`Item: ${id} moved`);
  console.log(`Old index: ${moveInfo.oldIndex}`);
  console.log(`New index: ${moveInfo.index}`);
  console.log(`Old folder: ${moveInfo.oldParentId}`);
  console.log(`New folder: ${moveInfo.parentId}`);
}

function handleClick() {
  browser.bookmarks.onMoved.addListener(handleMoved);
}

browser.browserAction.onClicked.addListener(handleClick);

```
  **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onMoved) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onMoved>

bookmarks.onChildrenReordered
=============================


Fired when the children of a folder have changed their order due to the order being sorted in the UI. This is not called as a result of a call to [`bookmarks.move()`](move) or a drag operation in the UI.


Syntax
------




```
browser.bookmarks.onChildrenReordered.addListener(listener)
browser.bookmarks.onChildrenReordered.removeListener(listener)
browser.bookmarks.onChildrenReordered.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `id`  `string`. ID of the folder whose children were reordered.

  `reorderInfo`  `object`. Object containing Additional objects. See the [reorderInfo](#reorderinfo_2) section for more details.

    Additional objects
------------------


### reorderInfo


 `childIds`  `array` of `string`. Array containing the IDs of all the bookmark items in this folder, in the order they now appear in the UI.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChildrenReordered` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function handleChildrenReordered(id, reorderInfo) {
  console.log(`Item: ${id} children reordered`);
  console.log(`Children: ${reorderInfo.childIds}`);
}

function handleClick() {
  browser.bookmarks.onChildrenReordered.addListener(handleChildrenReordered);
}

browser.browserAction.onClicked.addListener(handleClick);

```
  **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onChildrenReordered) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onChildrenReordered>

bookmarks.onImportEnded
=======================



Fired when the browser has finished importing a set of bookmarks.

 See [`bookmarks.onImportBegan`](onimportbegan).



Syntax
------




```
browser.bookmarks.onImportEnded.addListener(listener)
browser.bookmarks.onImportEnded.removeListener(listener)
browser.bookmarks.onImportEnded.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. It's passed no parameters.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onImportEnded` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function handleImportBegan() {
  console.log("Importing…");
}

function handleImportEnded() {
  console.log("Import finished.");
}

function handleClick() {
  browser.bookmarks.onImportBegan.addListener(handleImportBegan);
  browser.bookmarks.onImportEnded.addListener(handleImportEnded);
}

browser.browserAction.onClicked.addListener(handleClick);

```
  **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onImportEnded) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onImportEnded>

bookmarks.update()
==================



`bookmarks.update()` updates the title and/or URL of a bookmark, or the name of a bookmark folder.

  **Warning:** If your extension attempts to update a bookmark in the bookmarks tree root node, the call will raise an error with the message: "The bookmark root cannot be modified" and the bookmark won't be updated.

  This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let updating = browser.bookmarks.update(
  id,                    // string
  changes                // object
)

```
### Parameters


 `id`  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) specifying the ID of the bookmark or bookmark folder to update.

  `changes`  An [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) specifying the changes to apply, with some combination of the following fields. Any items not specified aren't changed in the referenced bookmark or folder:

  
`title` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) containing the new title of the bookmark, or the new name of the folder if `id` refers to a folder.

  
`url` Optional
  A [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) providing a new URL for the bookmark.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a single [`bookmarks.BookmarkTreeNode`](bookmarktreenode) object, representing the updated bookmark. If the bookmark item corresponding to the `id` parameter can't be found, the promise is rejected.

Examples
--------



This example renames all folders named "MDN" to "Mozilla Developer Network (MDN)".

 
```
function onFulfilled(bookmarkItem) {
  console.log(bookmarkItem.title);
}

function onRejected(error) {
  console.error(`Error: ${error}`);
}

function updateFolders(items) {
  for (const item of items) {
    // only folders, so skip items with a `url`
    if (!item.url) {
      browser.bookmarks
        .update(item.id, {
          title: "Mozilla Developer Network (MDN)",
        })
        .then(onFulfilled, onRejected);
    }
  }
}

browser.bookmarks.search({ title: "MDN" }).then(updateFolders, onRejected);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | Yes | 15 | 45 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#method-update) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/update>

bookmarks.onChanged
===================



Fired when there is a change to:

 * the title or URL of a bookmark
* the name of a folder.



Syntax
------




```
browser.bookmarks.onChanged.addListener(listener)
browser.bookmarks.onChanged.removeListener(listener)
browser.bookmarks.onChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters



 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `id`  `string`. ID of the item that changed.

  `changeInfo`  [`object`](#changeinfo). Object containing two properties: `title`, a string containing the item's title, and `url`, a string containing the item's URL. If the item is a folder, `url` is omitted.

      **Note:** Multiple events may occur when a bookmark changes, and that changeInfo object may contain only the data that has changed, rather than all the data for the bookmark. In other words, if the `url` for a bookmark changes, the changeInfo may only contain the new `url` information.

 
Examples
--------



```
function handleChanged(id, changeInfo) {
  console.log(`Item: ${id} changed`);
  console.log(`Title: ${changeInfo.title}`);
  console.log(`Url: ${changeInfo.url}`);
}

function handleClick() {
  browser.bookmarks.onChanged.addListener(handleChanged);
}

browser.browserAction.onClicked.addListener(handleClick);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onChanged) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onChanged>

bookmarks.onImportBegan
=======================



Fired when the browser has started importing a set of bookmarks.

 While a set of bookmarks is being imported, [`onCreated`](oncreated) may fire a lot of times. If your extension is listening to `onCreated`, and the listener is expensive, you should also listen for `onImportBegan` and [`onImportEnded`](onimportended). When you receive `onImportBegan`, ignore `onCreated` until you receive `onImportEnded`. You can handle all other notifications as usual.



Syntax
------




```
browser.bookmarks.onImportBegan.addListener(listener)
browser.bookmarks.onImportBegan.removeListener(listener)
browser.bookmarks.onImportBegan.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. It's passed no parameters.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onImportBegan` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function handleImportBegan() {
  console.log("Importing…");
}

function handleImportEnded() {
  console.log("Import finished.");
}

function handleClick() {
  browser.bookmarks.onImportBegan.addListener(handleImportBegan);
  browser.bookmarks.onImportEnded.addListener(handleImportEnded);
}

browser.browserAction.onClicked.addListener(handleClick);

```
  **Note:** This API is based on Chromium's [`chrome.bookmarks`](https://developer.chrome.com/docs/extensions/reference/bookmarks/#event-onImportBegan) API. This documentation is derived from [`bookmarks.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/bookmarks.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/onImportBegan>

browsingData.removePasswords()
==============================



Clears saved passwords.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only passwords that were saved after a given time
* control whether to clear passwords that were saved on normal web pages or to clear passwords that were saved on hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removePasswords(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only passwords that were saved after a given time, and whether to clear passwords that were saved on normal web pages or to clear passwords that were saved on hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove passwords saved in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removePasswords({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all saved passwords:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removePasswords({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removePasswords` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | ? | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removePasswords>

browsingData.DataTypeSet
========================



The `browsingData.DataTypeSet` type describes a set of data types.

 It contains a number of boolean properties. The name of each property is the name of a particular type of browsing data: "downloads", "history" and so on. All properties are optional.

 This type is used:

 * in [`browsingData.remove()`](remove) to describe which data types to remove
* in [`browsingData.settings()`](settings) to describe which data types are currently selected in the browser's "Clear History" feature.



Type
----



Values of this type are objects. They contain the following properties:

  
`cache` Optional
  `boolean`. The browser's cache.

  
`cookies` Optional
  `boolean`. Cookies acquired while browsing.

  
`downloads` Optional
  `boolean`. The user's download history.

  
`fileSystems` Optional
  `boolean`. Website's file systems.

  
`formData` Optional
  `boolean`. Saved form data, for autocomplete.

  
`history` Optional
  `boolean`. The user's browsing history.

  
`indexedDB` Optional
  `boolean`. IndexedDB data.

  
`localStorage` Optional
  `boolean`. Local storage data.

  
`passwords` Optional
  `boolean`. Saved passwords, for autocomplete.

  
`pluginData` Optional
  `boolean`. Stored data associated with plugins.

  
`serverBoundCertificates` Optional
  `boolean`. Stored server-bound certificates.

  
`serviceWorkers` Optional
  `boolean`. Data cached by service workers.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `cache` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `cookies` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `downloads` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `fileSystems` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `formData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `history` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |
| `indexedDB` | Yes | 79 | 57 | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `localStorage` | Yes | 79 | 57 | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `passwords` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `pluginData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | No | ? |
| `serverBoundCertificates` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `serviceWorkers` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/DataTypeSet>

browsingData.removeCache()
==========================



Clears the browser's cache.

 Note that although this function can take a [`browsingData.RemovalOptions`](removaloptions) object, it will be ignored. The entire cache is always cleared when using this function.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeCache(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 
`removalOptions` Optional
  `object`. A [`browsingData.RemovalOptions`](removaloptions) object. This parameter has no effect.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Clear the browser cache:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeCache({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeCache` | Yes | 79 | 53`removalOptions.since` is not supported. | ? | Yes | No | ? | ? | 85`removalOptions.since` is not supported.57–79`removalOptions.since` is not supported. | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeCache>

browsingData.removeCookies()
============================



Clears the browser's cookies.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only cookies created after a given time
* control whether to clear cookies only set from normal web pages or to clear cookies set from hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeCookies(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only cookies created after a given time, and whether to clear cookies only set from normal web pages or to clear cookies set from hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove cookies created in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removeCookies({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all cookies:

  **Warning:** Using the API to remove all cookies will, simultaneously, clear all local storage objects (including those of other extensions).

 If you want to clear all cookies without disrupting local storage facilities, use [browser.cookies](../cookies) to loop through and remove the contents of all cookie stores.

  
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeCookies({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeCookies` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeCookies>

browsingData.removeDownloads()
==============================



Clears the browser's download history. Note that this does not delete the downloaded objects themselves, only records of downloads in the browser's history.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear records of items downloaded after a given time
* control whether to clear only records of items downloaded from normal web pages or to clear records from hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeDownloads(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only records created after a given time, and whether to clear only records of items downloaded from normal web pages or to clear records from hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove records of objects downloaded in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removeDownloads({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all records of downloaded objects:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeDownloads({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeDownloads` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 57–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeDownloads>

browsingData.removeFormData()
=============================



Clears data that the browser has saved for autofilling forms.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only form data entered after a given time
* control whether to clear only form data entered in normal web pages or to clear data entered in hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeFormData(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only form data entered after a given time, and whether to clear only form data entered in normal web pages or to clear data entered in hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove form data saved in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removeFormData({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all saved form data:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeFormData({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeFormData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 57–79 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeFormData>

browsingData.removeLocalStorage()
=================================



Clears any [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) created by websites.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only local storage objects created after a given time
* control whether to clear only local storage objects created by normal web pages or to clear objects created by hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeLocalStorage(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only local storage objects created by normal web pages or to clear objects created by hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove all local storage:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeLocalStorage({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeLocalStorage` | Yes | 79 | 57`removalOptions.since` is not supported. | ? | Yes | No | ? | ? | 85`removalOptions.since` is not supported. | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeLocalStorage>

browsingData.removeHistory()
============================



Clears the record of web pages that the user has visited (browsing history).

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only records of web pages visited after a given time
* control whether to clear only records of normal web pages or to clear records of hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removeHistory(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only records of web pages visited after a given time, and whether to clear only records of normal web pages or to clear records of hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove records of pages visited in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removeHistory({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all records of visited pages:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removeHistory({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeHistory` | Yes | 79 | 53This function also removes download history and service workers. | ? | Yes | No | ? | ? | 85 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removeHistory>

browsingData.RemovalOptions
===========================


The `browsingData.RemovalOptions` type contains options to control certain aspects of browsing data removal.


Type
----



Values of this type are objects. They contain the following properties:

  
`cookieStoreId` Optional
  `string`. This property only applies to cookies and indexedDB items. The removal is limited to items belonging to a specific [cookie store](../cookies/cookiestore) as specified by the ID.

  **Note:** On Firefox Nightly removal of localStorage items by `cookieStoreId` is also supported.

   
`hostnames` Optional
  `Array` of `string`. This property applies to cookie, indexedDB, local storage, and service worker registration items. Remove only cookie, indexedDB, local storage, and service worker registration items associated with these hostnames.

 You must pass in just a hostname here, without protocol (for example, "google.com" not "<https://google.com>"). You can use the [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) interface to parse a raw URL and retrieve the hostname. Items associated with subdomains of a given hostname are *not* removed: you must explicitly list subdomains.

  
`originTypes` Optional
  `object`. Used to control whether to remove data only from normal web pages, or also from hosted web apps and extensions. If this option is omitted, only data from normal web pages ("`unprotectedWeb`") is removed. Before removing data from web apps or extensions, be very careful to ensure that this is really what the user wants.

 This object may contain any of the following properties:

  
`unprotectedWeb` Optional
  `boolean`. If present and `true`, remove data from normal web pages.

  
`protectedWeb` Optional
  `boolean`. If present and `true`, remove data from websites that have been installed as hosted apps.

  
`extension` Optional
  `boolean`. If present and `true`, remove data from extensions.

    
`since` Optional
  `number`. How far back in time to remove data, given in [milliseconds since the UNIX epoch](https://en.wikipedia.org/wiki/Unix_time). Note that when removing the browser cache, the entire cache is always removed and this option is ignored. If the `since` property is omitted, it defaults to 0, which means "forever".

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `cookieStoreId` | No | No | 84 | ? | No | No | ? | ? | 84This option is currently limited to the `firefox-default` and `firefox-private` values. | ? | No | ? |
| `hostnames` | No | No | 56["From Firefox 56 supports the specification of hostnames for the deletion of cookies and local storage items.", "From Firefox 77 also supports the specification of hostnames for the deletion of service worker and indexedDB items."] | ? | No | No | ? | ? | 85 | ? | No | ? |
| `originTypes` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `since` | Yes | 79 | 53`since` is not supported with the following data types: `cache`, `indexedDB`, `localStorage`, and `serviceWorkers`. | ? | Yes | No | ? | ? | 85`since` is not supported with the following data types: `cache`, `indexedDB`, `localStorage`, and `serviceWorkers`.56–79`since` is not supported with the following data types: `cache`, `indexedDB`, `localStorage`, and `serviceWorkers`. | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/RemovalOptions>

browsingData.settings()
=======================



Browsers have a built-in "Clear History" feature, which enables the user to clear various types of browsing data. This has a UI that enables the user to select what type of data to remove (e.g. history, downloads, …) and how far back in time to remove data.

 This function returns the current value of these settings.

 Note that not all data types will always be removable through the UI, and some UI options may map to more than one data type.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getSettings = browser.browsingData.settings()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object containing the settings information. This object has three properties:

  `options`  `[`browsingData.RemovalOptions`](removaloptions)`. A `RemovalOptions` object describing the removal options currently selected.

  `dataToRemove`  `[`browsingData.DataTypeSet`](datatypeset)`. This will contain a property for every data type that can be toggled in the browser's UI. Each property will have a value of `true` if that type is selected for removal and `false` otherwise.

  `dataRemovalPermitted`  `[`browsingData.DataTypeSet`](datatypeset)`. This will contain a property for every data type that can be toggled in the browser's UI. Each will have a value of `true` if the administrator of the device has allowed the user to remove that type, and `false` otherwise.

   If any error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `settings` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 8556–79 | ? | No | ? |


Examples
--------



Log current settings:

 
```
function onGotSettings(settings) {
  console.log(settings.options);
  console.log(settings.dataToRemove);
  console.log(settings.dataRemovalPermitted);
}

function onError(error) {
  console.error(error);
}

browser.browsingData.settings().then(onGotSettings, onError);

```
  **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/settings>

browsingData.removePluginData()
===============================



Clears data stored by browser plugins.

 You can use the `removalOptions` parameter, which is a [`browsingData.RemovalOptions`](removaloptions) object, to:

 * clear only plugin data stored after a given time
* control whether to clear only data stored by plugins running in normal web pages or to clear data stored by plugins running in hosted apps and extensions as well.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.browsingData.removePluginData(
  removalOptions            // RemovalOptions object
)

```
### Parameters


 `removalOptions`  `object`. A [`browsingData.RemovalOptions`](removaloptions) object, which may be used to clear only plugin data stored after a given time, and whether to clear only data stored by plugins running in normal web pages or to clear data stored by plugins running in hosted apps and extensions as well.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the removal has finished. If any error occurs, the promise will be rejected with an error message.

Examples
--------



Remove data stored by plugins in the last week:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

function weekInMilliseconds() {
  return 1000 \* 60 \* 60 \* 24 \* 7;
}

let oneWeekAgo = new Date().getTime() - weekInMilliseconds();

browser.browsingData
  .removePluginData({ since: oneWeekAgo })
  .then(onRemoved, onError);

```
 Remove all data stored by plugins:

 
```
function onRemoved() {
  console.log("removed");
}

function onError(error) {
  console.error(error);
}

browser.browsingData.removePluginData({}).then(onRemoved, onError);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removePluginData` | Yes | 79 | 53 | ? | Yes | No | ? | ? | 85 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.browsingData`](https://developer.chrome.com/docs/extensions/reference/browsingData/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData/removePluginData>

scripting.registerContentScripts()
==================================



Registers one or more content scripts.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
await browser.scripting.registerContentScripts(
  scripts         // array
)

```
### Parameters


 `scripts`  `array` of [`scripting.RegisteredContentScript`](registeredcontentscript). A list of scripts to register.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an array of [`scripting.RegisteredContentScript`](registeredcontentscript). If there are errors during script parsing and file validation, or if the IDs specified do not exist, no scripts are registered and the promise is rejected.

Examples
--------



This example registers a content script that injects the file `"script.js"`:

 
```
const aScript = {
  id: "a-script",
  js: ["script.js"],
  matches: ["https://example.com/\*"],
};

try {
  await browser.scripting.registerContentScripts([aScript]);
} catch (err) {
  console.error(`failed to register content scripts: ${err}`);
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `registerContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-registerContentScripts) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/registerContentScripts>

contentScripts.RegisteredContentScript
======================================



A `RegisteredContentScript` is returned by a call to [`contentScripts.register()`](register) and represents the content scripts registered in that call.

 It defines a single function [`unregister()`](registeredcontentscript/unregister), which can be used to unregister the content scripts.

  **Note:** If this object is destroyed (for example because it goes out of scope) then the content scripts will be unregistered automatically, so you should keep a reference to this object for as long as you want the content scripts to stay registered.

 

Methods
-------


 [`unregister()`](registeredcontentscript/unregister)  Unregisters the content scripts represented by this object.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RegisteredContentScript` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `unregister` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Examples
--------



This code toggles a registered content script on a browser action click:

 
```
let registered = null;

async function register() {

  registered = await browser.contentScripts.register({
    matches: ["\*://\*.org/\*"],
    js: [{
      code: "document.body.innerHTML = '<h1>This page has been eaten<h1>'"
    }],
    runAt: "document\_idle"
  });

}

function toggle() {
  if (registered) {
    registered.unregister();
    registered = null;
  } else {
    register();
  }
}

browser.browserAction.onClicked.addListener(toggle);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts/RegisteredContentScript>

declarativeNetRequest.RuleCondition
===================================


Details of the condition that determines whether a rule matches a request.


Type
----



Values of this type are objects. They contain these properties:

  
`domainType` Optional
  A `string`. Specifies whether the network request is first-party or third-party to the domain from where it originated. If omitted, all requests are accepted. Possible values are `"firstParty"` and `"thirdParty"`.

  
`domains`  Deprecated  Optional
  An array of `string`. Use [`initiatorDomains`](#initiatordomains) instead. The rule only matches network requests originating from this list of domains.

  
`excludedDomains`  Deprecated  Optional
  An array of `string`. Use [`excludedInitiatorDomains`](#excludedinitiatordomains) instead. The rule does not match network requests originating from this list of domains.

  
`initiatorDomains` Optional
  An array of `string`. The rule only matches network requests originating from this list of domains. If the list is omitted, the rule is applied to requests from all domains. An empty list is not allowed. A [canonical domain](#canonical_domain) should be used. This matches against the request initiator and not the request URL.

  
`excludedInitiatorDomains` Optional
  An array of `string`. The rule does not match network requests originating from this list of domains. If the list is empty or omitted, no domains are excluded. This takes precedence over `initiatorDomains`. A [canonical domain](#whocanonical_domain) should be used. This matches against the request initiator and not the request URL.

  
`isUrlFilterCaseSensitive` Optional
  A `boolean`. Whether the [`urlFilter`](#urlfilter) or [`regexFilter`](#regexfilter) (whichever is specified) is case sensitive. Default is true in (older) versions of Chrome and Safari, and false in Firefox. There is consensus on defaulting to `true` across browsers in [WECG issue 269](https://github.com/w3c/webextensions/issues/269).

  
`regexFilter` Optional
  A `string`. Regular expression to match against the network request URL. Note that:

 * The supported format is not stable and varies across browsers, see ["Regular expressions in DNR API (regexFilter)" in WECG issue 344](https://github.com/w3c/webextensions/issues/344) for details.
* Only one of [`urlFilter`](#urlfilter) or [`regexFilter`](#regexfilter) can be specified.
* The [`regexFilter`](#regexfilter) must be composed of only ASCII characters. This is matched against a URL where the host is encoded in the [punycode](https://en.wikipedia.org/wiki/Punycode) format (in case of internationalized domains) and any other non-ascii characters are URL encoded in utf-8.

  
`requestDomains` Optional
  An array of `string`. The rule only matches network requests when the domain matches one from this list. If the list is omitted, the rule is applied to requests from all domains. An empty list is not allowed. A [canonical domain](#canonical_domain) should be used.

  
`excludedRequestDomains` Optional
  An array of `string`. The rule does not match network requests when the domains matches one from this list. If the list is empty or omitted, no domains are excluded. This takes precedence over `requestDomains`. A [canonical domain](#canonical_domain) should be used.

  
`requestMethods` Optional
  An array of `string`. List of HTTP request methods that the rule matches. An empty list is not allowed. Specifying a `requestMethods` rule condition also excludes non-HTTP(s) requests, whereas specifying [`excludedRequestMethods`](#excludedrequestmethods) does not.

  
`excludedRequestMethods` Optional
  An array of `string`. List of request methods that the rule does not match on. Only one of [`requestMethods`](#requestmethods) and `excludedRequestMethods` should be specified. If neither of them is specified, all request methods are matched.

  
`resourceTypes` Optional
  An array of [`declarativeNetRequest.ResourceType`](resourcetype). List of resource types that the rule matches with. An empty list is not allowed. This must be specified for `"allowAllRequests"` rules and may only include the `"sub_frame"` and `"main_frame"` resource types.

  
`excludedResourceTypes` Optional
  An array of [`declarativeNetRequest.ResourceType`](resourcetype). List of resource types that the rule does not match on. Only one of [`resourceTypes`](#resourcetypes) and `excludedResourceTypes` should be specified. If neither of them is specified, all resource types except `"main_frame"` are blocked.

  
`tabIds` Optional
  An array of `number`. List of [`tabs.Tab`](../tabs/tab).`id` that the rule should match. An ID of [`tabs.TAB_ID_NONE`](../tabs/tab_id_none) matches requests that don't originate from a tab. An empty list is not allowed. Only supported for session-scoped rules.

  
`excludedTabIds` Optional
  An array of `number`. List of [`tabs.Tab`](../tabs/tab).`id` that the rule should not match. An ID of [`tabs.TAB_ID_NONE`](../tabs/tab_id_none) excludes requests that do not originate from a tab. Only supported for session-scoped rules.

  
`urlFilter` Optional
  A `string`. The pattern that is matched against the network request URL. Supported constructs:

 * '\*' : Wildcard: Matches any number of characters.
* '|' : Left or right anchor: If used at either end of the pattern, specifies the beginning or end of the URL respectively.
* '||' : Domain name anchor: If used at the beginning of the pattern, specifies the start of a (sub-)domain of the URL.
* '^' : Separator character: This matches anything except a letter, a digit. or one of \_, -, ., or %. The last `^` may also match the end of the URL instead of a separator character. `urlFilter` is composed of the following parts: (optional left/domain name anchor) + pattern + (optional right anchor). If omitted, all URLs are matched. An empty string is not allowed. A pattern beginning with ||\* is not allowed. Use \* instead. Note that:
* Only one of `urlFilter` or [`regexFilter`](#regexfilter) can be specified.
* The `urlFilter` must be composed of only ASCII characters. This is matched against a URL where the host is encoded in the [punycode](https://en.wikipedia.org/wiki/Punycode) format (in case of internationalized domains) and any other non-ASCII characters are URL encoded in utf-8. For example, when the request URL is `http://abc.рф?q=ф`, the `urlFilter` is matched against the URL `http://abc.xn--p1ai/?q=%D1%84`.

  
### Canonical domain



Domains specified in `initiatorDomains`, `excludedInitiatorDomains`, `requestDomains`, or `excludedRequestDomains` should comply with the following:

 * Sub-domains such as "a.example.com" are allowed.
* The entries must consist of only *lowercase* ASCII characters.
* Use [Punycode](https://en.wikipedia.org/wiki/Punycode) encoding for internationalized domains.
* IPv4 addresses must be represented as 4 numbers separated by a dot.
* IPv6 addresses should be represented in their canonical form, wrapped in brackets.

 To programmatically generate the canonical domain for a URL, use the [URL API](https://developer.mozilla.org/en-US/docs/Web/API/URL) and read its `hostname` property, i.e., `new URL(url).hostname`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RuleCondition` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `domains` | 84Deprecated in Chrome 101, use `initiatorDomains` instead. | 84Deprecated in Edge 101, use `initiatorDomains` instead. | No | ? | 70Deprecated in Opera 87, use `initiatorDomains` instead. | 15 | ? | ? | No | ? | 15 | ? |
| `excludedDomains` | 84Deprecated in Chrome 101, use `excludedInitiatorDomains` instead. | 84Deprecated in Edge 101, use `excludedInitiatorDomains` instead. | No | ? | 70Deprecated in Opera 87, use `excludedInitiatorDomains` instead. | 15 | ? | ? | No | ? | 15 | ? |
| `excludedInitiatorDomains` | 101 | 101 | No | ? | 87 | No | ? | ? | No | ? | No | ? |
| `excludedRequestDomains` | 101 | 101 | No | ? | 87 | preview | ? | ? | No | ? | No | ? |
| `excludedRequestMethods` | 91 | 91 | No | ? | 77 | No | ? | ? | No | ? | No | ? |
| `requestDomains` | 101 | 101 | No | ? | 87 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `requestMethods` | 91 | 91 | No | ? | 77 | No | ? | ? | No | ? | No | ? |
| `tabIds` | 92 | 92 | No | ? | 78 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/RuleCondition>

declarativeNetRequest.getMatchedRules
=====================================


Returns all the rules matched for the extension. Callers can filter the list of matched rules by specifying a `filter`. This method is only available to extensions with the `"declarativeNetRequestFeedback"` permission or that have the `"activeTab"` permission granted for the `tabId` specified in `filter`. Rules not associated with an active document that were matched more than five minutes ago are returned.


Syntax
------



```
let gettingMatchedRules = browser.declarativeNetRequest.getMatchedRules(
    filter                // object
);

```
### Parameters


 
`filter` Optional
  An object to filter the list of matched rules.

  
`minTimeStamp` Optional
  A `number`. If specified, only matches rules after the specified timestamp.

  
`tabId` Optional
  A `number`. If specified, only matches rules for the specified tab. Matches rules not associated with any active tab if set to `-1`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an object with these properties:

  `rule`  [`declarativeNetRequest.MatchedRule`](matchedrule). Details of a matched rule.

  `tabId`  `number` The `tabId` of the tab the request originated from if the tab is still active. Otherwise, `-1`.

  `timeStamp`  `number` The time the rule was matched. Timestamps correspond to the Javascript convention for times, i.e. the number of milliseconds since the epoch.

   If no rules are matched, the object is empty. If the request fail, the promise is rejected with an error message


Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getMatchedRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/getMatchedRules>

declarativeNetRequest.onRuleMatchedDebug
========================================


Fired when a rule is matched with a request. Only available extensions with the `"declarativeNetRequestFeedback"` permission, as this is intended for debugging purposes only. See [Testing](../declarativenetrequest#testing) for details on how testing is enabled in each browser.


Syntax
------




```
browser.declarativeNetRequest.onRuleMatchedDebug.addListener(listener)
browser.declarativeNetRequest.onRuleMatchedDebug.removeListener(listener)
browser.declarativeNetRequest.onRuleMatchedDebug.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that is called when this event occurs. The function is passed these arguments:

  `request`  An object containing information about the request the rule matched.

  
`documentId` Optional
  A `string`. The unique identifier for the frame's document, if this request is for a frame.

  
`documentLifecycle` Optional
  A `string`. The lifecycle of the frame's document, if this request is for a frame. Possible values are: `"prerender"`, `"active"`, `"cached"`, or `"pending_deletion"`.

  `frameId`  A `number`. The value `0` indicates that the request happens in the main frame. A positive value indicates the ID of a subframe where the request happens. If the document of a (sub-)frame is loaded (type is `main_frame` or `sub_frame`), `frameId` indicates this frame's ID, not the outer frame's ID. Frame IDs are unique within a tab.

  
`frameType` Optional
  A `string`. The type of the frame, if this request is for a frame. Possible values are: `"outermost_frame"`, `"fenced_frame"`, or `"sub_frame"`.

  
`initiator` Optional
  A `string`. The origin where the request was initiated. This does not change through redirects. The string 'null' is used if this is an opaque origin.

  `method`  A `string`. A standard HTTP method.

  
`parentDocumentId` Optional
  A `string`. The unique identifier for the frame's parent document, if this request is for a frame and has a parent.

  `parentFrameId`  A `number`. The ID of the frame that wraps the frame which sent the request. Set to `-1` if there is no parent frame.

  `requestId`  A `string`. The ID of the request. Request IDs are unique within a browser session.

  `tabId`  A `number`. The ID of the tab in which the request takes place. Set to `-1` if the request is not related to a tab.

  `type`  [`ResourceType`](resourcetype). The resource type of the request.

  `url`  A `string`. The URL of the request.

    `rule`  [`MatchedRule`](matchedrule). Details of a matched rule.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRuleMatchedDebug` | 84Available only to unpacked extensions. | 84Available only to unpacked extensions. | No | ? | 70Available only to unpacked extensions. | No | ? | ? | No | ? | No | ? |
| `request` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/onRuleMatchedDebug>

declarativeNetRequest.RuleAction
================================


Details of the action to take if a rule is matched.


Type
----



Values of this type are objects. They contain these properties:

  
`redirect` Optional
  [`declarativeNetRequest.Redirect`](redirect). Describes how the redirect should be performed. Only valid for redirect rules.

  
`requestHeaders` Optional
  [`declarativeNetRequest.ModifyHeaderInfo`](modifyheaderinfo). The request headers to modify for the request. Only valid if `RuleActionType` is `"modifyHeaders"`.

  
`responseHeaders` Optional
  [`declarativeNetRequest.ModifyHeaderInfo`](modifyheaderinfo). The response headers to modify for the request. Only valid if `RuleActionType` is `"modifyHeaders"`.

  
`type` Optional
  A `string`. The type of action to perform. Possible values are `"block"`, `"redirect"`, `"allow"`, `"upgradeScheme"`, `"modifyHeaders"`, and `"allowAllRequests"`. The use of the `"redirect"` and `"modifyHeaders"` actions require [host permissions](../../manifest.json/permissions#host_permissions) for the request and request initiator. The "block" and "upgradeScheme" actions also require host permissions unless the "declarativeNetRequest" permission is specified. Without these permissions, matching rules are ignored. See [Permissions at declarativeNetRequest](../declarativenetrequest#permissions). for more information.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RuleAction` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `requestHeaders` | 86 | 86 | No | ? | 72 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `responseHeaders` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/RuleAction>

declarativeNetRequest.updateDynamicRules
========================================



Modifies the set of dynamic rules for the extension. The rules with IDs listed in `options.removeRuleIds` are first removed, and then the rules given in `options.addRules` are added. Note that:

 * This update happens as an atomic operation: either all specified rules are added and removed, or an error is returned.
* These rules are persisted across browser sessions and across extension updates.
* Static rules specified as part of the extension package can not be removed using this function.
* [`declarativeNetRequest.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES`](max_number_of_dynamic_and_session_rules) is the maximum number of dynamic and session rules an extension can add.



Syntax
------



```
let updatedRules = browser.declarativeNetRequest.updateDynamicRules(
    options                // object
);

```
### Parameters


 `options`  An object containing details of the rules to add or delete from the dynamic rules.

  
`addRules` Optional
  An array of [`declarativeNetRequest.Rule`](rule). Details of the rules to add.

  
`removeRuleIds` Optional
  An array of `number`. IDs of the rules to remove. Any invalid IDs are ignored.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) If the request was successful, the promise is fulfilled with no arguments. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `updateDynamicRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/updateDynamicRules>

declarativeNetRequest.updateSessionRules
========================================



Modifies the set of scoped rules for the extension. The rules with IDs listed in `options.removeRuleIds` are first removed, and then the rules given in `options.addRules` are added. Note that:

 * This update happens as an atomic operation: either all specified rules are added and removed, or an error is returned.
* These rules are not persisted across browser sessions.
* [`MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES`](max_number_of_dynamic_and_session_rules) is the maximum number of dynamic and session rules an extension can add.



Syntax
------



```
let updatedRuleset = browser.declarativeNetRequest.updateSessionRules(
    options                // object
);

```
### Parameters


 `options`  An object containing details of the rules to add or delete from the dynamic rules.

  
`addRules` Optional
  An array of [`declarativeNetRequest.Rule`](rule). Details of the rules to add.

  
`removeRuleIds` Optional
  An array of `number`. IDs of the rules to remove. Any invalid IDs are ignored.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) If the request was successful, the promise is fulfilled with no arguments. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `updateSessionRules` | 90 | 90 | No | ? | 76 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/updateSessionRules>

declarativeNetRequest.MAX\_NUMBER\_OF\_STATIC\_RULESETS
=======================================================



The maximum number of static rulesets an extension can specify as part of the [`declarative_net_request.rule_resources`](../../manifest.json/declarative_net_request) manifest key.

 Its value is `50`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_NUMBER_OF_STATIC_RULESETS` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MAX_NUMBER_OF_STATIC_RULESETS>

declarativeNetRequest.GUARANTEED\_MINIMUM\_STATIC\_RULES
========================================================



The minimum number of static rules guaranteed to an extension across its enabled static rulesets. Any rules above this limit are count towards the global static rule limit.

 Its value is `30000` on Chrome.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `GUARANTEED_MINIMUM_STATIC_RULES` | 89 | 89 | No | ? | 75 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/GUARANTEED_MINIMUM_STATIC_RULES>

declarativeNetRequest.MAX\_NUMBER\_OF\_ENABLED\_STATIC\_RULESETS
================================================================



The maximum number of static rulesets an extension can have enabled, i.e., the number of values in the [`declarative_net_request.rule_resources`](../../manifest.json/declarative_net_request) manifest key with `"enabled"` set to `true`. Static rulesets exceeding the limit are ignored.

 An extension can change the number of enabled rulesets using the [`updateEnabledRulesets`](updateenabledrulesets) method.

 Its value is `10`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_NUMBER_OF_ENABLED_STATIC_RULESETS` | 94 | 94 | No | ? | 80 | preview | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MAX_NUMBER_OF_ENABLED_STATIC_RULESETS>

declarativeNetRequest.getAvailableStaticRuleCount
=================================================


Returns the number of static rules that can be activated before the global static rule limit is reached.


Syntax
------



```
let count = await browser.declarativeNetRequest.getAvailableStaticRuleCount();

```
### Parameters


This function takes no parameters.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) fulfilled with a number that indicates how many static rules can enable before the global static rule limit is reached. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAvailableStaticRuleCount` | 89 | 89 | No | ? | 75 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/getAvailableStaticRuleCount>

declarativeNetRequest.MAX\_NUMBER\_OF\_DYNAMIC\_AND\_SESSION\_RULES
===================================================================



The maximum number of combined dynamic and session scoped rules an extension can add.

 In Chrome, this limit is enforced for the combination of dynamic and session scoped rules.

 In Firefox, each ruleset has its own quota.

 Its value is `5000`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES` | 90 | 90 | No | ? | 76 | 16.4 | ? | ? | No | ? | 16.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES>

declarativeNetRequest.ModifyHeaderInfo
======================================



The request or response header to modify for a request, declared in the `rule.action.requestHeaders` array or `rule.action.responseHeaders` array for rules whose [`rule.action`](ruleaction)`.type` is "modifyHeaders".

 Each object describes one header modification. To modify multiple headers, multiple objects can be specified in these arrays, or across multiple rules.

  Matching `modifyHeaders` rules are applied in the order described at [Matching precedents](../declarativenetrequest#matching_precedents). Within each extension, all `modifyHeaders` rules with a priority lower than or equal to matching `allow` or `allowAllRequests` rules are ignored. 

 If multiple `modifyHeaders` rules specify the same header, the resulting modification for the header is determined based on the priority of each rule and the operations specified:

 * If a rule has been appended to a header, then lower-priority rules can only append to that header. `set` and `remove` operations are not permitted.
* If a rule has set a header, lower priority rules cannot modify the header except for `append` rules from the same extension.
* If a rule has removed a header, lower priority rules cannot modify the header.



Type
----



Values of this type are objects. They contain these properties:

  `header`  A `string`. The name of the header to be modified.

  `operation`  A `string`. The operation to be performed on a header. Possible values are `"append"`, `"set"`, and `"remove"`.

  
`value` Optional
  A `string`. The new value for the header. Must be specified for append and set operations. Not allowed for the "remove" operation.

  
Header limits
-------------



In Chrome, `"append"` is supported for the following request headers:

 * `Accept`
* `Accept-Encoding`
* `Accept-Language`
* `Access-Control-Request-Headers`
* `Cache-Control`
* `Connection`
* `Content-Language`
* `Cookie`
* `Forwarded`
* `If-Match`
* `If-None-Match`
* `Keep-Alive`
* `Range`
* `Te`
* `Trailer`
* `Transfer-Encoding`
* `Upgrade`
* `Via`
* `Want-Digest`
* `X-Forwarded-For`

 In Firefox, the extension needs host permissions for the new value of the `Host` header.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ModifyHeaderInfo` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |
| `header` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |
| `operation` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |
| `value` | 86 | 86 | No | ? | 72 | No | ? | ? | No | ? | No | ? |




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ModifyHeaderInfo` | 86 | 86 | No | ? | 72 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `header` | 86 | 86 | No | ? | 72 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `operation` | 86The `"append"` operation is supported from Chrome 108. | 86The `"append"` operation is supported from Edge 108. | No | ? | 72The `"append"` operation is supported from Opera 94. | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `value` | 86 | 86 | No | ? | 72 | 16.4 | ? | ? | No | ? | 16.4 | ? |

### webextensions.api.declarativeNetRequest.RuleAction.requestHeaders


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


### webextensions.api.declarativeNetRequest.RuleAction.responseHeaders


BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/ModifyHeaderInfo>

declarativeNetRequest.testMatchOutcome
======================================


Checks if any of the extension's `declarativeNetRequest` rules would match a hypothetical request. Only available while testing, as this is intended to be used during extension development. See [Testing](../declarativenetrequest#testing) for details on how testing is enabled in each browser.


Syntax
------



```
let result = await browser.declarativeNetRequest.testMatchOutcome(
    request,                // object
    options                 // optional object
);

```
### Parameters


 `request`  The details of the request to test.

  
`initiator` Optional
  A `string`. The initiator URL (if any) for the hypothetical request.

  
`method` Optional
  A `string`. The standard (lower case) HTTP method of the hypothetical request. Defaults to `"get"` for HTTP requests and is ignored for non-HTTP requests.

  
`tabId` Optional
  A `number`. The ID of the tab the hypothetical request takes place in. Does not need to correspond to a real tab ID. Default is `-1`, meaning that the request isn't related to a tab.

  `type`  [`declarativeNetRequest.ResourceType`](resourcetype). The resource type of the hypothetical request.

  `url`  A `string`. The URL of the hypothetical request.

    
`options` Optional
  Details of options for the request.

  
`includeOtherExtensions` Optional
  A `boolean`. Whether matching rules from other extensions are included in `matchedRules`. When rules from other extensions match, the resulting `matchedRule` has an `extensionId` property. Defaults to `false`.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an object with these properties:

  `matchedRules`  [`declarativeNetRequest.MatchedRule`](matchedrule). Details of the rules (if any) that match the hypothetical request.

   If no rules match, the `matchedRules` array is empty. If the request fails, the promise is rejected with an error message.


Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `testMatchOutcome` | 103 | 103 | No | ? | 89 | No | ? | ? | No | ? | No | ? |
| `options` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/testMatchOutcome>

declarativeNetRequest.updateEnabledRulesets
===========================================


Updates the extension's set of static rulesets. The rulesets with IDs listed in `options.disableRulesetIds` are first deactivated, and then the rulesets listed in `options.enableRulesetIds` are activated. Note that the set of enabled static rulesets persists across sessions but not across extension updates, i.e. the [`declarative_net_request.rule_resources` manifest key](../../manifest.json/declarative_net_request) determines the set of enabled static rulesets on each extension update.


Syntax
------



```
let updatedRulesets = browser.declarativeNetRequest.updateEnabledRulesets(
    options                // object
);

```
### Parameters


 `options`  An object detailing the rulesets to activate or deactivate in the extension's static rulesets.

  
`disableRulesetIds` Optional
  An array of `string`. IDs of static Rulesets to deactivated.

  
`enableRulesetIds` Optional
  An array of `string`. IDs of static Rulesets to activated.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) If the request was successful, the promise is fulfilled with no arguments. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `updateEnabledRulesets` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/updateEnabledRulesets>

declarativeNetRequest.MatchedRule
=================================


An object describing the matched rule. This type may be returned by the [`declarativeNetRequest.getMatchedRules`](getmatchedrules) or [`declarativeNetRequest.testMatchOutcome`](testmatchoutcome) methods, or observed through the [`declarativeNetRequest.onRuleMatchedDebug`](onrulematcheddebug) event.


Type
----



Values of this type are objects. They contain these properties:

  `extensionId`  A `string`. The ID of the extension, if this rule belongs to a different extension. This property is only available when used with [`declarativeNetRequest.testMatchOutcome`](testmatchoutcome), with the `includeOtherExtensions` option set to `true`.

  `ruleId`  A `number`. The matching rule's ID.

  `rulesetId`  A `string`. The ID of the [ruleset](../declarativenetrequest#rulesets) this rule belongs to. The value returned is:

 * For a rule originating from the set of static rules, the value specified in the "id" key of the ruleset in the [`declarative_net_request.rule_resources` manifest key](../../manifest.json/declarative_net_request).
* For a rule originating from the set of dynamic rules, the value defined in [`declarativeNetRequest.DYNAMIC_RULESET_ID`](dynamic_ruleset_id), i.e., `"_dynamic"`.
* For a rule originating from the set of session rules, the value defined in [`declarativeNetRequest.SESSION_RULESET_ID`](session_ruleset_id), i.e., `"_session"`.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MatchedRule` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `extensionId` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MatchedRule>

declarativeNetRequest.Redirect
==============================


Details describing how a redirect should be performed. Only valid for redirect rules.


Type
----



Values of this type are objects. They contain these properties:

  
`extensionPath` Optional
  A `string`. The path relative to the extension directory. Should start with '/'.

  
`regexSubstitution` Optional
  A `string`. The substitution pattern for rules that specify a `regexFilter`. The first match of `regexFilter` within the URL is replaced with this pattern. Within `regexSubstitution`, backslash-escaped digits (`\1` to `\9`) are used to insert the corresponding capture groups. `\0` refers to the entire matching text.

  
`transform` Optional
  [`declarativeNetRequest.URLTransform`](urltransform). The URL transformations to perform.

  
`url` Optional
  A `string`. The redirect URL. Redirects to JavaScript URLs are not allowed.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Redirect` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/Redirect>

declarativeNetRequest.ResourceType
==================================


The resource type of a request. Comparable to [`webRequest.ResourceType`](../webrequest/resourcetype).


Type
----



Values of this type are strings. Possible values are:

  `beacon`  Requests sent through the [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API).

  `csp_report`  Requests sent to the [`report-uri`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri) given in the [`Content-Security-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) header, when an attempt to violate the policy is detected.

  `font`  Web fonts loaded for a [`@font-face`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face) CSS rule.

  `image`  Resources loaded to be rendered as image, except for `imageset` on browsers that support that type (see browser compatibility below).

  `imageset`  Images loaded by a [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) element or given in an `<img>` element's [`srcset`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#srcset) attribute.

  `main_frame`  Top-level documents loaded into a tab.

  `media`  Resources loaded by a [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) or [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) element.

  `object`  Resources loaded by an [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) or [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed) element.

 Browsers that don't have a dedicated `object_subrequest` type (see browser compatibility below), also label subsequent requests sent by the plugin as `object`.

  `object_subrequest`  Requests sent by plugins.

  `ping`  Requests sent to the URL given in a hyperlink's [`ping`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#ping) attribute, when the hyperlink is followed.

 Browsers that don't have a dedicated `beacon` type (see browser compatibility below), also label requests sent through the Beacon API as `ping`.

  `script`  Code that is loaded to be executed by a [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) element or running in a [Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).

  `speculative`  In a speculative connection, the browser has determined that a request to a URI may be coming soon, so it starts a TCP and/or TLS handshake immediately, so it is ready more quickly when the resource is actually requested. Note that this type of connection does not provide valid tab information, so request details such as `tabId`, `frameId`, `parentFrameId`, etc. are inaccurate.

  `stylesheet`  [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) stylesheets loaded to describe the representation of a document.

  `sub_frame`  Documents loaded into an [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) or [`<frame>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame) element.

  `web_manifest`  [Web App Manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) loaded for websites that can be installed to the homescreen.

  `webbundle`  Requests initiating a connection to a server through a Web Bundle or [packaged website](https://github.com/WICG/webpackage).

  `websocket`  Requests initiating a connection to a server through the [WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API).

  `webtransport`  Requests initiating a connection to a server through the [WebTransport API](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API).

  `xml_dtd`  [DTDs](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) loaded for an XML document.

  `xmlhttprequest`  Requests sent by an [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object or through the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

  `xslt`  [XSLT](https://developer.mozilla.org/en-US/docs/Web/XSLT) stylesheets loaded for transforming an XML document.

  `other`  Resources that aren't covered by any other available type.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ResourceType` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `beacon` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `csp_report` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `font` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `image` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `imageset` | No | No | No | ? | No | NoUse `image` instead. | ? | ? | No | ? | NoUse `image` instead. | ? |
| `main_frame` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `media` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `object` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `object_subrequest` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `other` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `ping` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `script` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `speculative` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `stylesheet` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `sub_frame` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `web_manifest` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `webbundle` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `websocket` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `webtransport` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |
| `xml_dtd` | No | No | No | ? | No | No | ? | ? | No | ? | No | ? |
| `xmlhttprequest` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |
| `xslt` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/ResourceType>

declarativeNetRequest.DYNAMIC\_RULESET\_ID
==========================================



Ruleset ID for the dynamic rules added by the extension using [`updateDynamicRules`](updatedynamicrules).

 Its value is `"_dynamic"`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `DYNAMIC_RULESET_ID` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/DYNAMIC_RULESET_ID>

declarativeNetRequest.GETMATCHEDRULES\_QUOTA\_INTERVAL
======================================================



The time interval within which [`declarativeNetRequest.MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL`](max_getmatchedrules_calls_per_interval) [`declarativeNetRequest.getMatchedRules`](getmatchedrules) calls can be made, specified in minutes. Additional calls fail immediately and result in a promise rejection. Calls associated with a user gesture are exempt from the quota.

 Its value is `10`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `GETMATCHEDRULES_QUOTA_INTERVAL` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/GETMATCHEDRULES_QUOTA_INTERVAL>

declarativeNetRequest.Rule
==========================



The object describing the actions to take for matching requests. These can be specified in the static rule resources linked by the [manifest.json's `declarative_net_request` key](mozilla/add-ons/webextensions/manifest.json/declarative_net_request), or more dynamically through the [`declarativeNetRequest.updateDynamicRules`](updatedynamicrules) or [`declarativeNetRequest.updateSessionRules`](updatesessionrules) methods.

 See [Rules](../declarativenetrequest#rules) on the API overview page for more information about rules.



Type
----



Values of this type are objects. They contain these properties:

  `action`  [`declarativeNetRequest.RuleAction`](ruleaction). The action to take if this rule is matched.

  `condition`  [`declarativeNetRequest.RuleCondition`](rulecondition). The condition under which this rule is triggered.

  `id`  `number`. An ID that uniquely identifies a rule within a ruleset. Mandatory and should be >= 1.

  
`priority` Optional
  `number`. Rule priority. Defaults to 1. When specified, should be >= 1. See [Matching precedents](../declarativenetrequest#matching_precedents) for details on how priority affects which rules are applied.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Rule` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/Rule>

declarativeNetRequest.URLTransform
==================================


Details describing a URL transformation to perform for a redirect rule. This object can be specified at [`rule.action`](ruleaction).redirect.transform.


Type
----



Values of this type are objects. They contain these properties:

  
`fragment` Optional
  A `string`. The new fragment for the request. Should be either empty, in which case the existing fragment is cleared; or should begin with '#'.

  
`host` Optional
  A `string`. The new host name for the request.

  
`password` Optional
  A `string`. The new password for the request.

  
`path` Optional
  A `string`. The new path for the request. If empty, the existing path is cleared.

  
`port` Optional
  A `string`. The new port for the request. If empty, the existing port is cleared.

  
`query` Optional
  A `string`. The new query for the request. Should be either empty, in which case the existing query is cleared; or should begin with '?'.

  
`queryTransform` Optional
  An object describing how to add, remove, or replace query key-value pairs. Cannot be specified if 'query' is specified.

  
`addOrReplaceParams` Optional
  An object describing the list of query key-value pairs to be added or replaced.

  `key`  A `string`. The key value.

  
`replaceOnly` Optional
  A `boolean`. If true, the query key is replaced only if it's already present. Otherwise, the key is also added if it's missing. Defaults to false.

  `value`  A `string`. The value value.

    
`removeParams` Optional
  A `string`. The list of query keys to be removed.

    
`scheme` Optional
  A `string`. The new scheme for the request. Allowed values are `"http"`, `"https"`, and the scheme of the extension, for example, "moz-extension" in Firefox or "chrome-extension" in Chrome. When the extension scheme is used, the `host` must be specified to generate a meaningful redirection target.

  
`username` Optional
  A `string`. The new username for the request.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `URLTransform` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `queryTransform` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/URLTransform>

declarativeNetRequest.MAX\_GETMATCHEDRULES\_CALLS\_PER\_INTERVAL
================================================================



The number of times [`declarativeNetRequest.getMatchedRules`](getmatchedrules) can be called within a period of [`declarativeNetRequest.GETMATCHEDRULES_QUOTA_INTERVAL`](getmatchedrules_quota_interval).

 Its value is `20`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL>

declarativeNetRequest.getEnabledRulesets
========================================


Returns the IDs for the set of activated static rulesets.


Syntax
------



```
let rulesetIds = await browser.declarativeNetRequest.getEnabledRulesets();

```
### Parameters


This function takes no parameters.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) fulfilled with an array of string containing static rulesets IDs. If no rules are active, the array is empty. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getEnabledRulesets` | 84 | 84 | No | ? | 70 | 15 | ? | ? | No | ? | 15 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/getEnabledRulesets>

declarativeNetRequest.getSessionRules
=====================================


Returns the active set of session scoped rules for the extension.


Syntax
------



```
let sessionRules = await browser.declarativeNetRequest.getSessionRules();

```
### Parameters


This function takes no parameters.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) fulfilled with an array of [`declarativeNetRequest.Rule`](rule) objects. If no rules are active, the object is empty. If the request fails, the promise is rejected with an error message

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getSessionRules` | 90 | 90 | No | ? | 76 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/getSessionRules>

declarativeNetRequest.setExtensionActionOptions
===============================================


Configures whether the action count for tabs is displayed as the extension action's badge text and provides a way for the action count to be incremented.


Syntax
------



```
let count = browser.declarativeNetRequest.setExtensionActionOptions(
    extensionActionOptions, // object
);

```
### Parameters


 `extensionActionOptions`  An object containing the configuration details for the action count for tabs.

  
`displayActionCountAsBadgeText` Optional
  `boolean` Whether to automatically display the action count for a page as the extension's badge text. This preference persists across sessions.

  
`tabUpdate` Optional
  `object`. Details of how the tab's action count should be adjusted. See the [tabUpdate](#tabupdate_2) section for more details.

    Additional objects
------------------


### tabUpdate


 `increment`  `number` The amount to increment the tab's action count by. Negative values decrement the count.

  `tabId`  `number` The tab to update the action count for.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with no arguments. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setExtensionActionOptions` | 88 | 88 | No | ? | 74 | 16.4 | ? | ? | No | ? | 16.4 | ? |
| `options` | 88 | 88 | No | ? | 74 | preview | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/setExtensionActionOptions>

cookies.CookieStore
===================



The `CookieStore` type of the [`cookies`](../cookies) API represents a cookie store in the browser.

 Windows in different browsing modes may use different cookie stores — a private browsing/incognito mode window, for instance, will use a separate cookie store from a non-incognito/private window.



Type
----



Values of this type are objects, which can contain the following properties:

  `id`  A `string` representing the unique identifier for the cookie store.

  `incognito`  A boolean value that indicates whether this is an incognito cookie store.

  `tabIds`  An `array` of `integers`, which identifies all of the browser tabs that share this cookie store.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CookieStore` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------



In the following snippet, the [`cookies.getAllCookieStores()`](getallcookiestores) method is used to retrieve all the cookie stores currently available in the browser, and print out each cookie store ID, and the tabs that currently share each cookie store.

 
```
function logStores(cookieStores) {
  for (const store of cookieStores) {
    console.log(`Cookie store: ${store.id}\n Tab IDs: ${store.tabIds}`);
  }
}

browser.cookies.getAllCookieStores().then(logStores);

```
 The following code snippet gets all cookie stores and then logs the total number of stores and how many of those stores are incognito.

 
```
browser.cookies.getAllCookieStores().then((stores) => {
  const incognitoStores = stores.map((store) => store.incognito);
  console.log(`Of ${stores.length} cookie stores, ${incognitoStores.length} are incognito.`);
});

```
  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#type-CookieStore) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/CookieStore>

declarativeNetRequest.MAX\_NUMBER\_OF\_REGEX\_RULES
===================================================



The maximum number of regular expression rules that an extension can add.

 In Chrome, its value is 1000, and this limit is evaluated separately for the set of dynamic and session rules, and those specified in the rule resources file.

 In Firefox, this limit is evaluated separately per ruleset.

 In Safari, there is no separate limit on the number of `regexFilter` rules.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_NUMBER_OF_REGEX_RULES` | 84 | 84 | No | ? | 70 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/MAX_NUMBER_OF_REGEX_RULES>

declarativeNetRequest.SESSION\_RULESET\_ID
==========================================



The ruleset ID for the session-scoped rules added by the extension.

 Its value is `"_session"`.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `SESSION_RULESET_ID` | 90 | 90 | No | ? | 76 | No | ? | ? | No | ? | No | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/SESSION_RULESET_ID>

declarativeNetRequest.getDynamicRules
=====================================


Returns the set of dynamic rules for the extension.


Syntax
------



```
let gettingDynamicRules = browser.declarativeNetRequest.getDynamicRules();

```
### Parameters


This function takes no parameters.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) is fulfilled with an array of [`declarativeNetRequest.Rule`](rule) objects. Each of these represents a rule that belongs to the extension. If no rules are active, the array is empty. If the request fails, the promise is rejected with an error message.

Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getDynamicRules` | 84 | 84 | No | ? | 70 | 15.4 | ? | ? | No | ? | 15.4 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/getDynamicRules>

declarativeNetRequest.isRegexSupported
======================================


Checks if a regular expression is supported as a [`declarativeNetRequest.RuleCondition`](rulecondition)`.regexFilter` rule condition.


Syntax
------



```
let count = browser.declarativeNetRequest.isRegexSupported(
    regexOptions                // object
);

```
### Parameters


 `regexOptions`  An object containing the regular expression to check.

  
`isCaseSensitive` Optional
  `boolean` Whether the regex specified is case sensitive. Default is `true`.

  `regex`  `string` The regular expression to check.

  
`requireCapturing` Optional
  `boolean` Whether the regex specified requires capturing. Capturing is only required for redirect rules that specify a regexSubstitution action. The default is false.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an object with these properties:

  `isSupported`  `boolean` Whether the regular expression is supported.

  
`reason` Optional
  `string` Specifies the reason why the regular expression is not supported. Possible values are `"syntaxError"` and `"memoryLimitExceeded"`. Only provided if `isSupported` is false.

   If the request fails, the promise is rejected with an error message.


Examples
--------


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isRegexSupported` | 87 | 87 | No | ? | 73 | 15 | ? | ? | No | ? | 15 | ? |




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/isRegexSupported>

dom.openOrClosedShadowRoot()
============================



Gets the open shadow root or the closed shadow root hosted by the specified element. If the shadow root isn't attached to the element, it will return `null`.

  **Note:** In Firefox, the equivalent property is `element.openOrClosedShadowRoot`. This read-only property represents the shadow root hosted by the element, regardless of whether its [`mode`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode) is `open` or `closed`.

 Use [`Element.attachShadow()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow) to add a shadow root to an element.

 

Syntax
------



```
let shadowRoot = browser.dom.openOrClosedShadowRoot(
  element,    // HTMLElement
)

```
### Parameters


 `element`  `HTMLElement`. The host element.

  ### Return value


 A [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot) object instance, regardless of whether its [`mode`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode) is set to `open` or `closed`, or `null` if no shadow root is present. 

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `openOrClosedShadowRoot` | 88 | 88 | NoUse `element.openOrClosedShadowRoot`, available since Firefox 63. | ? | 74 | No | ? | ? | NoUse `element.openOrClosedShadowRoot`, available since Firefox 63. | ? | No | ? |


See also
--------


* [`Element.shadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot)
* [`chrome.dom.openOrClosedShadowRoot`](https://developer.chrome.com/docs/extensions/reference/dom/#method-openOrClosedShadowRoot)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dom/openOrClosedShadowRoot>

find.removeHighlighting()
=========================


Remove any highlighting of a previous search that was applied by a previous call to [`find.highlightResults()`](highlightresults), or by the browser's native UI.


Syntax
------



```
browser.find.removeHighlighting()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeHighlighting` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



```
browser.find.removeHighlighting();

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find/removeHighlighting>

cookies.Cookie
==============


The `Cookie` type of the [`cookies`](../cookies) API represents information about an HTTP cookie.


Type
----



Values of this type are objects, which can contain the following properties:

  `domain`  A `string` representing the domain the cookie belongs to (e.g. "[www.google.com](https://www.google.com)", "example.com").

  
`expirationDate` Optional
  A `number` representing the expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies.

  `firstPartyDomain`  A `string` representing the first-party domain associated with the cookie. This will be an empty string if the cookie was set while first-party isolation was off. See [First-party isolation](../cookies#first-party_isolation).

  `hostOnly`  A `boolean`, `true` if the cookie is a host-only cookie (i.e. the request's host must exactly match the domain of the cookie), or `false` otherwise.

  `httpOnly`  A `boolean`, `true` if the cookie is marked as HttpOnly (i.e. the cookie is inaccessible to client-side scripts), or `false` otherwise.

  `name`  A `string` representing the name of the cookie.

  
`partitionKey` Optional
  An `object` representing the description of the [storage partition](../cookies#storage_partitioning) containing the cookie. This object is omitted (null) if the cookie is not in partitioned storage. This object contains the following properties:

  `topLevelSite`  A `string` representing the first-party URL of the cookie's storage partition, if the cookie is in storage that is partitioned by top-level site.

    `path`  A `string` representing the path of the cookie.

  `secure`  A `boolean`, `true` if the cookie is marked as secure (i.e. its scope is limited to secure channels, typically HTTPS), or `false` otherwise.

  `session`  A `boolean`, `true` if the cookie is a session cookie, or `false` if it is a persistent cookie with an expiration date.

  `sameSite`  A [`cookies.SameSiteStatus`](samesitestatus) value that indicates the SameSite state of the cookie.

  `storeId`  A `string` representing the ID of the cookie store containing this cookie, as provided by [`cookies.getAllCookieStores()`](getallcookiestores).

  `value`  A `string` representing the value of the cookie.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Cookie` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `firstPartyDomain` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |
| `partitionKey` | No | No | 94 | ? | No | No | ? | ? | 94 | ? | No | ? |
| `sameSite` | Yes | 79 | 63 | ? | No | 14Only supports explicit. | ? | ? | 63 | ? | 15Only supports explicit. | ? |


Examples
--------



Most methods in the cookies API involve a `Cookie` object being used either as an input parameter or as part of the return value. For example, a call to [`cookies.getAll()`](getall) returns an array of `Cookie` objects.

 In the example below we've asked for all cookies, then logged some of the values of each of the resulting `Cookie` objects:

 
```
function logCookies(cookies) {
  for (cookie of cookies) {
    console.log(`Domain: ${cookie.domain}`);
    console.log(`Name: ${cookie.name}`);
    console.log(`Value: ${cookie.value}`);
    console.log(`Persistent: ${!cookie.session}`);
  }
}

let gettingAll = browser.cookies.getAll({});
gettingAll.then(logCookies);

```
  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#type-Cookie) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/Cookie>

cookies.OnChangedCause
======================


The `OnChangedCause` type of the [`cookies`](../cookies) API represents the reason a cookie changed.


Type
----



Values of this type are strings. Possible values are:

  `evicted`  A cookie has been automatically removed due to garbage collection.

  `expired`  A cookie has been automatically removed due to expiry.

  `explicit`  A cookie has been inserted or removed via an explicit call to [`cookies.remove()`](remove).

  `expired_overwrite`  A cookie has been overwritten by a cookie with an already-expired expiration date.

  `overwrite`  A call to [`cookies.set()`](set) overwrote this cookie with a different one.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnChangedCause` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


Examples
--------



You can listen to the [`cookies.onChanged`](onchanged) event to be notified when cookies change. The listener is passed a `changeInfo` object that contains a `cause` property, whose value is the `OnChangeCaused` string:

 
```
browser.cookies.onChanged.addListener((changeInfo) => {
  console.log(`Cookie changed: \n`
    + ` \* Cookie: ${JSON.stringify(changeInfo.cookie)}\n`
    + ` \* Cause: ${changeInfo.cause}\n`
    + ` \* Removed: ${changeInfo.removed}`);
});

```
  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#type-OnChangedCause) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/OnChangedCause>

cookies.SameSiteStatus
======================


The `SameSiteStatus` type of the [`cookies`](../cookies) API represents information about the `SameSite` state of a cookie.


Type
----



Values of this type are strings. Possible values are:

  `no_restriction`  Represents a cookie set without a `SameSite` attribute.

  `lax`  Corresponds to `SameSite=Lax`

  `strict`  Corresponds to a cookie set with `SameSite=Strict`

   See [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#samesite_cookies) for more information.




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/SameSiteStatus>

cookies.getAllCookieStores()
============================



The `getAllCookieStores()` method of the [`cookies`](../cookies) API returns a list of all cookie stores.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingStores = browser.cookies.getAllCookieStores()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an `array` of [`cookies.CookieStore`](cookiestore) objects representing all the existing cookie stores.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAllCookieStores` | Yes | 14Always returns the same default cookie store with ID 0. All cookies belong to this store. | 45Before version 52, only the default cookie store was visible. From version 52 onwards, the cookie stores for private browsing mode and container tabs are also readable. | ? | Yes | 14Always returns the same default cookie store with ID 0. | ? | ? | 48 | ? | 15Always returns the same default cookie store with ID 0. | ? |


Examples
--------



In the following snippet, the `getAllCookieStores()` method is used to retrieve all the cookie stores currently available in the browser, and print out each cookie store ID, and the tabs that currently share each cookie store.

 
```
function logStores(cookieStores) {
  for (const store of cookieStores) {
    console.log(`Cookie store: ${store.id}\n Tab IDs: ${store.tabIds}`);
  }
}

browser.cookies.getAllCookieStores().then(logStores);

```
 Each member of the `cookieStores` array is a [`cookies.CookieStore`](cookiestore) object.

  **Note:** This API is based on Chromium's [`chrome.cookies`](https://developer.chrome.com/docs/extensions/reference/cookies/#method-getAllCookieStores) API. This documentation is derived from [`cookies.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/getAllCookieStores>

events.Event
============


An object which allows the addition and removal of listeners for a browser event.


Type
----


Values of this type are objects.

Methods
-------


 [`events.Event.addListener()`](event/addlistener)  Registers an event listener callback to an event.

  [`events.Event.removeListener()`](event/removelistener)  Deregisters an event listener callback from an event.

  [`events.Event.hasListener()`](event/haslistener)  Tests registration status of a listener.

  [`events.Event.hasListeners()`](event/haslisteners)  Tests whether any listeners are registered to the event.

  [`events.Event.addRules()`](event/addrules)  Registers rules to handle events.

  [`events.Event.getRules()`](event/getrules)  Returns currently registered rules.

  [`events.Event.removeRules()`](event/removerules)  Unregisters currently registered rules.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Event` | Yes | 14 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `addListener` | Yes | 14 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `addRules` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `getRules` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `hasListener` | Yes | 14 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `hasListeners` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `removeListener` | Yes | 14 | No | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `removeRules` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.events`](https://developer.chrome.com/docs/extensions/reference/events/#type-Event) API. This documentation is derived from [`events.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/events.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events/Event>

dns.resolve()
=============



Resolves the given hostname to a DNS record.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let resolving = browser.dns.resolve(
  hostname,    // string
  flags        // array of string
)

```
### Parameters


 `hostname`  `string`. The hostname to resolve.

  
`flags` Optional
  `array` of `string`. Flags to modify the way the hostname is resolved. Any omitted flags default to `false`. You can pass zero or more of the following flags:

 * `"allow_name_collisions"`: Allow name collision results which are normally filtered out.
* `"bypass_cache"`: Suppresses the internal DNS lookup cache.
* `"canonical_name"`: The canonical name of the specified host will be queried.
* `"disable_ipv4"`: Only IPv6 addresses will be returned.
* `"disable_ipv6"`: Only IPv4 addresses will be returned.
* `"disable_trr"`: Do not use the Trusted Recursive Resolver (TRR) for resolving the host name. A TRR enables resolving of host names using a dedicated [DNS-over-HTTPS](https://datatracker.ietf.org/doc/html/draft-ietf-doh-dns-over-https-02) server.
* `"offline"`: Only literals and cached entries will be returned.
* `"priority_low"`: The request is given lower priority. If "priority\_medium" is also given, the query is given medium priority.
* `"priority_medium"`: The request is given medium priority. If "priority\_low" is also given, the query is given medium priority.
* `"speculate"`: Indicates that the request is speculative. Speculative requests return errors if prefetching is disabled by the browser's configuration.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a `DNSRecord` object. This object can contain the following properties:

  `addresses`  `array` of `string`. The IP addresses associated with this DNS record.

  `canonicalName`  `string`. The canonical name for this record. This is only included in the response if the `"canonical_name"` flag was passed to `resolve()`.

  `isTRR`  `boolean`: `true` if the record was retrieved using a Trusted Recursive Resolver (TRR).

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `resolve` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |


Examples
--------




```
function resolved(record) {
  console.log(record.addresses);
}

let resolving = browser.dns.resolve("example.com");
resolving.then(resolved);

// > e.g. Array [ "73.284.240.12" ]

```
 Bypass the cache, and ask for the canonical name:

 
```
function resolved(record) {
  console.log(record.canonicalName);
  console.log(record.addresses);
}

let resolving = browser.dns.resolve("developer.mozilla.org",
                                   ["bypass\_cache", "canonical\_name"]);
resolving.then(resolved);

// > e.g. xyz.us-west-2.elb.amazonaws.com
// > e.g. Array [ "78.18.187.134", "34.79.135.234" ]

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve>

events.Rule
===========


Description of a declarative rule for handling events.


Type
----



Values of this type are objects. They contain the following properties:

  
`id` Optional
  `string`. Optional identifier that allows referencing this rule.

  
`tags` Optional
  `array` of `string`. Tags can be used to annotate rules and perform operations on sets of rules.

  `conditions`  `array` of `any`. List of conditions that can trigger the actions.

  `actions`  `array` of `any`. List of actions that are triggered if one of the conditions is fulfilled.

  
`priority` Optional
  `integer`. Optional priority of this rule. Defaults to 100.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Rule` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.events`](https://developer.chrome.com/docs/extensions/reference/events/#type-Rule) API. This documentation is derived from [`events.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/events.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events/Rule>

extension.ViewType
==================


The type of extension view.


Type
----


Values of this type are strings. Possible values are: `"tab"`, `"popup"`, `"sidebar"`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ViewType` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | 15 | ? |
| `sidebar` | No | No | 54 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#type-ViewType) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/ViewType>

extension.lastError
===================



 **Warning:** This function is deprecated, use [`runtime.lastError`](../runtime/lasterror) instead.

  An alias for [`runtime.lastError`](../runtime/lasterror).



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `lastError` | Yes | 79 | 47 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#property-lastError) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/lastError>

extension.getExtensionTabs()
============================



 **Warning:** This method has been deprecated. Use [`extension.getViews()`](getviews) instead.

  Returns an array of the JavaScript [Window](https://developer.mozilla.org/en-US/docs/Web/API/Window) objects for each of the tabs running inside the current extension. If `windowId` is specified, returns only the Window objects of tabs attached to the specified window.



Syntax
------




```
chrome.extension.getExtensionTabs(
  windowId // optional integer
)

```
 This API is also available as `browser.extension.getExtensionTabs()`.


### Parameters


 
`windowId` Optional
  `integer`.

  ### Return value


`array` of `object`. Array of global window objects

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getExtensionTabs` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-getExtensionTabs) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/getExtensionTabs>

extension.isAllowedFileSchemeAccess()
=====================================



Returns `true` if the extension can access the "file://" scheme, `false` otherwise.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let isAllowed = browser.extension.isAllowedFileSchemeAccess()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean: `true` if the extension is allowed access to "file://" URLs, `false` otherwise.

 Firefox will always return `false`.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isAllowedFileSchemeAccess` | Yes | 79 | 48 | ? | Yes | 14Always returns false. | ? | ? | 48 | ? | 15Always returns false. | ? |


Examples
--------




```
function logIsAllowed(answer) {
  console.log(`Is allowed: ${answer}`);
}

let isAllowed = browser.extension.isAllowedFileSchemeAccess();
isAllowed.then(logIsAllowed);

```
  **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-isAllowedFileSchemeAccess) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/isAllowedFileSchemeAccess>

extension.sendRequest()
=======================



**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

  **Warning:** This method has been deprecated. Use [`runtime.sendMessage`](../runtime/sendmessage) instead.

  Sends a single request to other listeners within the extension. Similar to [`runtime.connect`](../runtime/connect), but only sends a single request with an optional response. The [`extension.onRequest`](onrequest) event is fired in each page of the extension.



Syntax
------




```
chrome.extension.sendRequest(
  extensionId,             // optional string
  request,                 // any
  (response) => {/\* … \*/}  // optional function
)

```
 This API is also available as `browser.extension.sendRequest()` in a [version that returns a promise](../../api#callbacks_and_promises).


### Parameters


 
`extensionId` Optional
  `string`. The extension ID of the extension you want to connect to. If omitted, default is your own extension.

  `request`  `any`.

  
`responseCallback` Optional
  `function`. The function is passed the following arguments:

  `response`  `any`. The JSON response object sent by the handler of the request. If an error occurs while connecting to the extension, the callback will be called with no arguments and [`runtime.lastError`](../runtime/lasterror) will be set to the error message.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `sendRequest` | Yes | 79 | No | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-sendRequest) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/sendRequest>

extension.setUpdateUrlData()
============================


Sets parameters for the extension's update URL. This value is ignored for extensions that are hosted in the browser vendor's store.


Syntax
------



```
browser.extension.setUpdateUrlData(
  data // string
)

```
### Parameters


 `data`  `string`.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setUpdateUrlData` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#method-setUpdateUrlData) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/setUpdateUrlData>

events.UrlFilter
================



Describes various criteria for filtering URLs. If all of the criteria specified in the filter's properties match the URL, then the filter matches. Filters are often provided to API methods in an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of UrlFilters. For example, [webNavigation](../webnavigation) listeners can be added with a filter which is an object with a single `url` property that is an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of UrlFilters, e.g. `{url:[UrlFilter, UrlFilter, …]}`. If any filter within the Array of UrlFilters matches, then it is considered a match for the Array. Effectively, the criteria specified within a single filter are AND'ed together, while all of the individual filters within an Array are OR'ed.

 All criteria are case sensitive.



Type
----



Values of this type are objects. They contain the following properties:

 However, note that these last two patterns will not match the last component of the hostname, because no implicit dot is added at the end of the hostname. So for example, `"org."` will match `https://borg.com` but not `https://example.org`. To match these patterns, use `hostSuffix`.

  
`hostContains` Optional
  `string`. Matches if the [hostname](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/hostname) of the URL (without protocol or port – see `schemes` and `ports`) contains the given string.

 * To test whether a hostname component starts with "foo", use `".foo"`. This matches `www.foobar.com` and `foo.com`, because an implicit dot is added at the beginning of the hostname.
* To test whether a hostname component ends with "foo", use `"foo."`.
* To test whether a hostname component exactly matches "foo", use `".foo."`.

  
`hostEquals` Optional
  `string`. Matches if the hostname of the URL is equal to a specified string.

 * Example: `"www.example.com"` matches `http://www.example.com` and `https://www.example.com/`, but not `http://example.com/`.

  
`hostPrefix` Optional
  `string`. Matches if the hostname of the URL starts with a specified string.

  
`hostSuffix` Optional
  `string`. Matches if the hostname of the URL ends with a specified string.

 * Example: `".example.com"` matches `http://www.example.com/`, but not `http://example.com/`.
* Example: `"example.com"` matches `http://www.example.com/`, and `http://fakeexample.com/`.

  
`pathContains` Optional
  `string`. Matches if the path segment of the URL contains a specified string.

  
`pathEquals` Optional
  `string`. Matches if the path segment of the URL is equal to a specified string.

  
`pathPrefix` Optional
  `string`. Matches if the path segment of the URL starts with a specified string.

  
`pathSuffix` Optional
  `string`. Matches if the path segment of the URL ends with a specified string.

  
`queryContains` Optional
  `string`. Matches if the query segment of the URL contains a specified string.

  
`queryEquals` Optional
  `string`. Matches if the query segment of the URL is equal to a specified string.

  
`queryPrefix` Optional
  `string`. Matches if the query segment of the URL starts with a specified string.

  
`querySuffix` Optional
  `string`. Matches if the query segment of the URL ends with a specified string.

  
`urlContains` Optional
  `string`. Matches if the URL (without fragment identifier) contains a specified string. Port numbers are stripped from the URL if they match the default port number.

  
`urlEquals` Optional
  `string`. Matches if the URL (without fragment identifier) is equal to a specified string. Port numbers are stripped from the URL if they match the default port number.

  
`urlMatches` Optional
  `string`. Matches if the URL (without fragment identifier) matches a specified [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions). Port numbers are stripped from the URL if they match the default port number.

 * For example: `urlMatches: "^[^:]*:(?://)?(?:[^/]*\\.)?mozilla\\.org/.*$"` matches `https://mozilla.org/`, `https://developer.mozilla.org/`, but not `https://developer.fakemozilla.org/`.

  
`originAndPathMatches` Optional
  `string`. Matches if the URL without query segment and fragment identifier matches a specified [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions). Port numbers are stripped from the URL if they match the default port number.

  
`urlPrefix` Optional
  `string`. Matches if the URL (without fragment identifier) starts with a specified string. Port numbers are stripped from the URL if they match the default port number.

 * Example: `"https://developer"` matches `https://developer.mozilla.org/` and `https://developers.facebook.com/`.

  
`urlSuffix` Optional
  `string`. Matches if the URL (without fragment identifier) ends with a specified string. Port numbers are stripped from the URL if they match the default port number. Note that an implicit forward slash "/" is added after the host, so `"com/"` matches `https://example.com`, but `"com"` does not.

  
`schemes` Optional
  `array` of `string`. Matches if the scheme of the URL is equal to any of the schemes specified in the array. Because schemes are always converted to lowercase, this should always be given in lowercase or it will never match.

 * Example: `["https"]` will match only HTTPS URLs.

  
`ports` Optional
  `array` of (`integer` or (`array` of `integer`)). An array which may contain integers and arrays of integers. Integers are interpreted as port numbers, while arrays of integers are interpreted as port ranges. Matches if the port of the URL matches any port number or is contained in any ranges.

 * For example: `[80, 443, [1000, 1200]]` matches all requests on ports 80, 443, and in the range 1000-1200.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `UrlFilter` | Yes | 79 | 50 | ? | Yes | 14 | ? | ? | 50 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.events`](https://developer.chrome.com/docs/extensions/reference/events/#type-UrlFilter) API. This documentation is derived from [`events.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/events.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events/UrlFilter>

extension.onRequest
===================



 **Warning:** This is not implemented in Firefox because it has been deprecated since Chrome 33. Please use [runtime.onMessage](../runtime/onmessage) instead.

  Fired when a request is sent from either an extension process or a content script.



Syntax
------




```
chrome.extension.onRequest.addListener(function(
  request,         // optional any
  sender,          // runtime.MessageSender
  () => {/\* … \*/}  // function
) {/\* … \*/})
chrome.extension.onRequest.removeListener(listener)
chrome.extension.onRequest.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `request`  `any`. The request sent by the calling script.

  `sender`  [`runtime.MessageSender`](../runtime/messagesender).

  `sendResponse`  `function`. Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object, or undefined if there is no response. If you have more than one `onRequest` listener in the same document, then only one may send a response.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRequest` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#event-onRequest) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/onRequest>

extension.onRequestExternal
===========================



 **Warning:** This is not implemented in Firefox because it has been deprecated since Chrome 33. Please use [runtime.onMessageExternal](../runtime/onmessageexternal) instead.

  Fired when a request is sent from another extension.



Syntax
------




```
chrome.extension.onRequestExternal.addListener(function(
  request,      // optional any
  sender,       // runtime.MessageSender
  sendResponse, // function
) { })
chrome.extension.onRequestExternal.removeListener(listener)
chrome.extension.onRequestExternal.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `request`  `any`. The request sent by the calling script.

  `sender`  [`runtime.MessageSender`](../runtime/messagesender).

  `sendResponse`  `function`. Function to call when you have a response. The argument should be any JSON-ifiable object, or undefined if there is no response.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRequestExternal` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.extension`](https://developer.chrome.com/docs/extensions/reference/extension/#event-onRequestExternal) API. This documentation is derived from [`extension.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/extension.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/onRequestExternal>

extensionTypes.ImageFormat
==========================


The format of an image.


Type
----


Values of this type are strings. Possible values are: `"jpeg"`, `"png"`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageFormat` | YesThis feature is supported but not exposed through the 'extensionTypes' object. | 14This feature is supported but not exposed through the 'extensionTypes' object. | 45 | ? | YesThis feature is supported but not exposed through the 'extensionTypes' object. | 14This feature is supported but not exposed through the 'extensionTypes' object. | ? | ? | 48 | ? | 15This feature is supported but not exposed through the 'extensionTypes' object. | ? |


 **Note:** This API is based on Chromium's [`chrome.extensionTypes`](https://developer.chrome.com/docs/extensions/reference/extensionTypes/#type-ImageFormat) API. This documentation is derived from [`extension_types.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/extension_types.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes/ImageFormat>

history.onVisited
=================


Fired each time the user visits a page. A [`history.HistoryItem`](historyitem) object is passed to the listener. This event fires before the page has loaded.


Syntax
------




```
browser.history.onVisited.addListener(listener)
browser.history.onVisited.removeListener(listener)
browser.history.onVisited.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `result`  [`history.HistoryItem`](historyitem). An object representing the item in the browser's history.

 At the time that this event is sent, the browser doesn't yet know the title of the page. If the browser has visited this page before and has remembered its old title, then the `HistoryItem.title` object will contain the old title of the page. If the browser doesn't have a record of the page's old title, then `HistoryItem.title` will be empty. To get the titles of pages as soon as they are known, listen for [`history.onTitleChanged`](ontitlechanged).

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onVisited` | Yes | 79 | 50Before version 56, the result object's 'title' was always an empty string. From version 56 onwards, it is set to the last known title, if that is available, or an empty string otherwise. | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Listen for visits, and log the URL and visit time.

 
```
function onVisited(historyItem) {
  console.log(historyItem.url);
  console.log(new Date(historyItem.lastVisitTime));
}

browser.history.onVisited.addListener(onVisited);

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#event-onVisited) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/onVisited>

history.addUrl()
================



Adds a record to the browser's history of a visit to the given URL. The visit's time is recorded as the time of the call, and the [`TransitionType`](transitiontype) is recorded as "link".

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let addingUrl = browser.history.addUrl(
  details         // object
)

```
### Parameters


 `details`  `object`. Object containing the URL to add.

  `url`  `string`. The URL to add.

  
`title` Optional
  string: The title of the page. If this is not supplied, the title will be recorded as `null`.

  
`transition` Optional
  [`history.TransitionType`](transitiontype). Describes how the browser navigated to the page on this occasion. If this is not supplied, a transition type of "link" will be recorded.

  
`visitTime` Optional
  `number` or `string` or `object`. A value indicating a date and time. This can be represented as: a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object, an [ISO 8601 date string](https://www.iso.org/iso-8601-date-and-time-format.html), or the number of milliseconds since the epoch. Sets the visit time to this value. If this is not supplied, the current time will be recorded.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with no parameters when the item has been added.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `addUrl` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `title` | No | No | 49 | ? | No | No | ? | ? | No | ? | No | ? |
| `transition` | No | No | 49 | ? | No | No | ? | ? | No | ? | No | ? |
| `visitTime` | No | No | 49 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Add a record of a visit to "<https://example.org/>", then check that the new visit was recorded by searching history for the most recent item and logging it:

 
```
function onGot(results) {
  if (results.length) {
    console.log(results[0].url);
    console.log(new Date(results[0].lastVisitTime));
  }
}

browser.history
  .addUrl({ url: "https://example.org/" })
  .then(() =>
    browser.history.search({
      text: "https://example.org/",
      startTime: 0,
      maxResults: 1,
    })
  )
  .then(onGot);

```
 Add a record of a visit to "<https://example.org>", but give it a `visitTime` 24 hours in the past, and a `transition` of "typed":

 
```
const DAY = 24 \* 60 \* 60 \* 1000;

function oneDayAgo() {
  return Date.now() - DAY;
}

function onGot(visits) {
  for (const visit of visits) {
    console.log(new Date(visit.visitTime));
    console.log(visit.transition);
  }
}

browser.history
  .addUrl({
    url: "https://example.org/",
    visitTime: oneDayAgo(),
    transition: "typed",
  })
  .then(() =>
    browser.history.getVisits({
      url: "https://example.org/",
    })
  )
  .then(onGot);

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-addUrl) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/addUrl>

history.deleteAll()
===================



Deletes all visits from the browser's history.

 This function triggers [`history.onVisitRemoved`](onvisitremoved) just once, with `allHistory` set to `true` and an empty `urls` argument.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let deletingAll = browser.history.deleteAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with no parameters when all history has been deleted.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `deleteAll` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Delete all history when the user clicks a browser action:

 
```
function onDeleteAll() {
  console.log("Deleted all history");
}

function deleteAllHistory() {
  let deletingAll = browser.history.deleteAll();
  deletingAll.then(onDeleteAll);
}

deleteAllHistory();

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-deleteAll) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/deleteAll>

history.deleteRange()
=====================



Removes all visits to pages that the user made during the given time range. If this removes all visits made to a given page, then the page will be no longer appear in the browser history and [`history.onVisitRemoved`](onvisitremoved) will fire for it.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let deletingRange = browser.history.deleteRange(
  range           // object
)

```
### Parameters


 `range`  `object`. Specification of the time range for which to delete visits.

  `startTime`  `number` or `string` or `object`. A value indicating a date and time. This can be represented as: a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object, an [ISO 8601 date string](https://www.iso.org/iso-8601-date-and-time-format.html), or the number of [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time). Specifies the start time for the range.

  `endTime`  `number` or `string` or `object`. A value indicating a date and time. This can be represented as: a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object, an [ISO 8601 date string](https://www.iso.org/iso-8601-date-and-time-format.html), or the number of [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time). Specifies the end time for the range.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with no parameters when the range has been deleted.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `deleteRange` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Delete all visits made in the last minute:

 
```
const MINUTE = 60 \* 1000;

function oneMinuteAgo() {
  return Date.now() - MINUTE;
}

browser.history.deleteRange({
  startTime: oneMinuteAgo(),
  endTime: Date.now()
});

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-deleteRange) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/deleteRange>

history.TransitionType
======================


This describes how the browser navigated to a particular page. For example, "link" means that the browser navigated to the page because the user clicked a link.


Type
----



Values of this type are strings. Possible values are:

  "link"  The user clicked a link in another page.

  "typed"  The user typed the URL into the address bar. This is also used if the user started typing into the address bar, then selected a URL from the suggestions it offered. See also "generated".

  "auto\_bookmark"  The user clicked a bookmark or an item in the browser history.

  "auto\_subframe"  Any nested iframes that are automatically loaded by their parent.

  "manual\_subframe"  Any nested iframes that are loaded as an explicit user action. Loading such an iframe will generate an entry in the back/forward navigation list.

  "generated"  The user started typing in the address bar, then clicked on a suggested entry that didn't contain a URL.

  "auto\_toplevel"  The page was passed to the command line or is the start page.

  "form\_submit"  The user submitted a form. Note that in some situations, such as when a form uses a script to submit its contents, submitting a form does not result in this transition type.

  "reload"  The user reloaded the page, using the Reload button or by pressing Enter in the address bar. This is also used for session restore and reopening closed tabs.

  "keyword"  The URL was generated using a [keyword search](https://support.mozilla.org/en-US/kb/how-search-from-address-bar) configured by the user.

  "keyword\_generated"  Corresponds to a visit generated for a keyword.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TransitionType` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#type-TransitionType) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/TransitionType>

extensionTypes.InjectDetails
============================



This type is given as a parameter to the `tabs.executeScript()`, `tabs.insertCSS()`, and `tabs.removeCSS()` methods. For the details of its properties and what they are used for, see the documentation pages for those methods:

 * [`tabs.executeScript()`](../tabs/executescript)
* [`tabs.insertCSS()`](../tabs/insertcss)
* [`tabs.removeCSS()`](../tabs/removecss)




 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes/InjectDetails>

history.HistoryItem
===================


A `HistoryItem` object provides information about a page in the browser history.


Type
----



This is an object with the following properties:

  `id`  `string`. Unique identifier for the item.

  
`url` Optional
  `string`. The URL of the page.

  
`title` Optional
  `string`. The title of the page.

  
`lastVisitTime` Optional
  `number`. The date and time the page was last loaded, represented in milliseconds since the epoch.

  
`visitCount` Optional
  `number`. The number of times the user has visited the page.

  
`typedCount` Optional
  `number`. The number of times the user has navigated to this page by typing in the address.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `HistoryItem` | Yes | 79 | 49 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `typedCount` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#type-HistoryItem) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/HistoryItem>

history.getVisits()
===================



Retrieves information about all visits to the given URL.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.history.getVisits(
  details                // object
)

```
### Parameters


 `details`  An object with the following properties:

  `url`  `string`. The URL for which to retrieve visit information.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) will be fulfilled with an array of `[`history.VisitItem`](visititem)` objects each representing a visit to the given URL. Visits are sorted in reverse chronological order.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getVisits` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



List all visits to the most recently-visited page:

 
```
function gotVisits(visits) {
  console.log(`Visit count: ${visits.length}`);
  for (const visit of visits) {
    console.log(visit.visitTime);
  }
}

function listVisits(historyItems) {
  if (historyItems.length) {
    console.log(`URL ${historyItems[0].url}`);
    const gettingVisits = browser.history.getVisits({
      url: historyItems[0].url
    });
    gettingVisits.then(gotVisits);
  }
}

let searching = browser.history.search({
  text: "",
  startTime: 0,
  maxResults: 1
});

searching.then(listVisits);

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#method-getVisits) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/getVisits>

history.VisitItem
=================


An object describing a single visit to a page.


Type
----



Values of this type are objects. They contain the following properties:

  `id`  `string`. The unique identifier for the [`history.HistoryItem`](historyitem) associated with this visit.

  `visitId`  `string`. The unique identifier for this visit.

  
`visitTime` Optional
  `number`. When this visit occurred, represented in milliseconds since the epoch.

  `referringVisitId`  `string`. The visit ID of the referrer.

  `transition`  [`history.TransitionType`](transitiontype). Describes how the browser navigated to the page on this occasion.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `VisitItem` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#type-VisitItem) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/VisitItem>

menus.ContextType
=================


The different contexts a menu item can appear in.


Type
----



Values of this type are strings. The item is displayed when the given context applies. Possible values are:

  all  Specifying 'all' is equivalent to the combination of all other contexts except for 'bookmark', 'tab' and 'tools\_menu'.

  action  Applies when the user context-clicks your browser action in a Manifest V3 extension. The maximum number of items that can be added to the top-level browser action context menu is [`menus.ACTION_MENU_TOP_LEVEL_LIMIT`](action_menu_top_level_limit), but you can add any number of items to submenus.

  audio  Applies when the user context-clicks an [audio](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) element.

  bookmark  Applies when the user context-clicks a bookmark item in the bookmarks toolbar, bookmarks menu, bookmarks sidebar (`Ctrl`+`B`) and the Library window (`Ctrl`+`Shift`+`B`). The latter two are supported as of Firefox 66. Requires the "bookmarks" [API permission](../../manifest.json/permissions#api_permissions) in the manifest.

  browser\_action  Applies when the user context-clicks your browser action in a Manifest V2 extension. The maximum number of items that can be added to the top-level browser action context menu is [`menus.ACTION_MENU_TOP_LEVEL_LIMIT`](action_menu_top_level_limit), but you can add any number of items to submenus.

  editable  Applies when the user context-clicks an editable element, like a [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea).

  frame  Applies when the user context-clicks in a nested [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).

  image  Applies when the user context-clicks an image.

  link  Applies when the user context-clicks on a link.

  page  Applies when the user context-clicks in the page, but none of the other page contexts apply (for example, the click is not on an image or a nested iframe or a link).

  page\_action  Applies when the user context-clicks your page action. The maximum number of items that can be added to the top-level page action context menu is [`menus.ACTION_MENU_TOP_LEVEL_LIMIT`](action_menu_top_level_limit), but you can add any number of items to submenus.

  password  Applies when the user context-clicks on a [password input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/password).

  selection  Applies when part of the page is selected.

  tab  Applies when the user context-clicks on a tab (specifically, this refers to the tab-strip or other user interface element enabling the user to switch from one browser tab to another, not to the page itself).

 From Firefox 63, clicking the menu item on a tab grants the [activeTab](../../manifest.json/permissions#activetab_permission) permission for the tab clicked, even if that isn't the currently active tab.

  tools\_menu  The item will be added to the browser's tools menu. Note that this is only available if you access `ContextType` through the `menus` namespace. It is not available if you access it through the `contextMenus` namespace.

  video  Applies when the user context-clicks a [video](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) element.

   Note that "launcher" is not supported.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ContextType` | Yes | Yes | 55'The 'editable' context does not include password fields. Use the 'password' context for this.48 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `action` | Yes | Yes | 109 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `bookmark` | NoSee [bug 825443](https://crbug.com/825443). | NoSee [bug 825443](https://crbug.com/825443). | 59 | ? | NoSee [bug 825443](https://crbug.com/825443). | No | ? | ? | No | ? | No | ? |
| `browser_action` | Yes | Yes | 53'The 'editable' context does not include password fields. Use the 'password' context for this. | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `launcher` | Yes | Yes | 48 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `page_action` | Yes | Yes | 53 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `password` | No | No | 53 | ? | No | No | ? | ? | No | ? | No | ? |
| `tab` | No | No | 53 | ? | No | No | ? | ? | No | ? | No | ? |
| `tools_menu` | No | No | 56Only available at `menus.ContextType`, not at `contextMenus.ContextType`. | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#type-ContextType) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/ContextType>

menus.ItemType
==============


The type of menu item.


Type
----



Values of this type are strings. Possible values are:

  normal  A menu item that just displays a label.

  checkbox  A menu item that represents a binary state. It displays a checkmark next to the label. Clicking the item toggles the checkmark. The [`menus.onClicked`](onclicked) listener will be passed two extra properties: "checked", indicating whether the item is checked now, and "wasChecked", indicating whether the item was checked before the click event.

  radio  A menu item that represents one of a group of choices. Just like a checkbox, this also displays a checkmark next to the label, and its [`menus.onClicked`](onclicked) listener is passed "checked" and "wasChecked". However, if you create more than one radio item, then the items function as a group of radio items: only one item in the group can be checked, and clicking an item makes it the checked item.

  separator  A line separating a group of items.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ItemType` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#type-ItemType) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/ItemType>

menus.overrideContext()
=======================



Hide all default Firefox menu items in favor of providing a custom context menu UI.

 The overrideContext method will cause the matching menu items from this extension to be shown instead of the default menu. This method should be called from a [`contextmenu`](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event) DOM event handler, and only applies to the menu that opens after this event.

 This interface requires the `menus.overrideContext` [permission](../../manifest.json/permissions).



Syntax
------



```
browser.menus.overrideContext(
  contextOptions // object
)

```
### Parameters


 `contextOptions`  `object`. Options for how the context menus will be overridden.

  
`showDefaults` Optional
  `boolean`. Whether to also include default menu items in the menu.

  
`context` Optional
  `string`. ContextType to override, to allow menu items from other extensions in the menu. Currently only `'bookmark'` and `'tab'` are supported. `showDefaults` cannot be used with this option.

  
`bookmarkId` Optional
  `string`. Required when context is `'bookmark'`. Requires 'bookmark' permission.

  
`tabId` Optional
  `integer`. Required when context is `'tab'`. Requires 'tabs' permission.

    Examples
--------



Open the tab context menu on your custom UI, in this case:

 
```
document.addEventListener(
  "contextmenu",
  (event) => {
    const foo = event.target.closest(".foo");
    if (foo) {
      // When the context menu is opened on an element with the foo class
      // set the context to "opening a tab context menu".
      browser.menus.overrideContext({
        context: "tab",
        tabId: parseInt(foo.dataset.tabId),
      });
    }
  },
  { capture: true }
);

```
 See [this blog post](https://blog.mozilla.org/addons/2018/11/08/extensions-in-firefox-64/#cm) for more details.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `overrideContext` | No | No | 64 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/overrideContext>

history.onTitleChanged
======================


Fired when the title of a page visited by the user is recorded. To listen for visits to a page you use [`history.onVisited`](onvisited). However, the [`history.HistoryItem`](historyitem) that this event passes to its listener does not include the page title, because the page title is typically not known at the time `history.onVisited` is sent. Instead, the stored [`history.HistoryItem`](historyitem) is updated with the page title after the page has loaded, once the title is known. The `history.onTitleChanged` event is fired at that time. So if you need to know the titles of pages as they are visited, listen for `history.onTitleChanged`.


Syntax
------




```
browser.history.onTitleChanged.addListener(listener)
browser.history.onTitleChanged.removeListener(listener)
browser.history.onTitleChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that is called when this event occurs. The function is passed an object with these properties:

  `id`  `String`. The unique identifier for the [`history.HistoryItem`](historyitem) associated with this visit.

  `url`  `String`. URL of the page visited.

  `title`  `String`. Title of the page visited.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onTitleChanged` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |
| `id` | No | No | 86 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Listen for title change events, and log the ID, URL, and title of the visited pages.

 
```
function handleTitleChanged(item) {
  console.log(item.id);
  console.log(item.title);
  console.log(item.url);
}

browser.history.onTitleChanged.addListener(handleTitleChanged);

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#event-onVisited) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/onTitleChanged>

history.onVisitRemoved
======================



Fired when a page is removed completely from the browser history.

 * If all visits to a single page are removed (for example, using [`history.deleteUrl`](deleteurl)), then this event is fired once.
* If a range of visits is removed (for example, using [`history.deleteRange`](deleterange) or a browser feature like "Clear Recent History"), then it is fired once for each page *whose visits all fall within the cleared range*.
* If the browser's entire history is cleared (for example, using [`history.deleteAll`](deleteall)), then it is fired only once.



Syntax
------




```
browser.history.onVisitRemoved.addListener(listener)
browser.history.onVisitRemoved.removeListener(listener)
browser.history.onVisitRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following argument:

  `removed`  `object`. Details of the removal. This is an object containing two properties: a boolean `allHistory` and an array `urls`.

 * If this event is firing because all history was cleared, `allHistory` will be `true` and `urls` will be an empty array.
* Otherwise, `allHistory` will be `false` and `urls` will contain one item, which is the URL of the removed page.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onVisitRemoved` | Yes | 79 | 50 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function onRemoved(removed) {
  if (removed.allHistory) {
    console.log("All history removed");
  } else if (removed.urls.length) {
    console.log(`URL removed: ${removed.urls[0]}`);
  }
}

browser.history.onVisitRemoved.addListener(onRemoved);

```
  **Note:** This API is based on Chromium's [`chrome.history`](https://developer.chrome.com/docs/extensions/reference/history/#event-onVisitRemoved) API. This documentation is derived from [`history.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/history.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history/onVisitRemoved>

menus.OnClickData
=================


Information passed to the [`menus.onClicked`](onclicked) event listener when a menu item is clicked.


Type
----



Values of this type are objects. They contain the following properties:

  
`bookmarkId` Optional
  `string`. The ID of the bookmark where the context menu was clicked.

  
`button` Optional
  `integer`. Which mouse button was pressed. The values are the same as for [`MouseEvent.button`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button).

  
`checked` Optional
  `boolean`. A flag indicating whether a checkbox or radio item was checked after it was clicked.

  `editable`  `boolean`. A flag indicating whether the element is editable: for example, if it is a [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea).

  
`frameId` Optional
  `integer`. The ID of the frame in which the item was clicked. The frame ID can be used in other APIs that accept frame IDs, such as [`tabs.sendMessage()`](../tabs/sendmessage). If the item was clicked in the top level document, `frameId` is zero. If the item was clicked outside the page entirely (for example, in the `tools_menu` or `tab` context), then `frameId` is `undefined`.

  
`frameUrl` Optional
  `string`. The URL of the frame of the element where the context menu was clicked, if it was in a frame.

  
`linkText` Optional
  `string`. If the element is a link, the text for the link. If the link contains no text, the URL itself is given here.

  
`linkUrl` Optional
  `string`. If the element is a link, the URL it points to.

  
`mediaType` Optional
  `string`. One of "image", "video", or "audio" if the context menu was activated on one of these types of elements.

  `menuItemId`  `integer` or `string`. The ID of the menu item that was clicked.

  `modifiers`  `array` of `string`. An array containing any modifier keys that were pressed when the item was clicked. Possible values are: "Alt", "Command", "Ctrl", "MacCtrl", and "Shift". On a Mac, if the user has the Control key pressed, then both "Ctrl" and "MacCtrl" are included.

  
`pageUrl` Optional
  `string`. The URL of the page in which the menu item was clicked. This property is not present if the click occurred in a context where there is no current page, such as on a browser action.

  
`parentMenuItemId` Optional
  `integer` or `string`. The parent ID, if any, for the item clicked.

  
`selectionText` Optional
  `string`. If some text was selected in the page, this contains the selected text.

  
`srcUrl` Optional
  `string`. If present, the `src` value for the media in the clicked element.

  
`targetElementId` Optional
  `integer`. An identifier of the element, if any, over which the context menu was created. Use [`menus.getTargetElement()`](gettargetelement) in the content script to locate the element. Note that this is not the [id](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) attribute of the page element.

  
`viewType` Optional
  [`ViewType`](../extension/viewtype). The type of extension view.

  
`wasChecked` Optional
  `boolean`. A flag indicating whether a checkbox or radio item was checked before it was clicked.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnClickData` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `bookmarkId` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |
| `button` | No | No | 64 | ? | No | No | ? | ? | No | ? | No | ? |
| `frameId` | 35 | 79 | 55 | ? | 22 | 14 | ? | ? | No | ? | No | ? |
| `linkText` | No | No | 56 | ? | No | No | ? | ? | No | ? | No | ? |
| `modifiers` | No | No | 54 | ? | No | No | ? | ? | No | ? | No | ? |
| `srcUrl` | Yes | Yes | 59–94Returns a post-redirect URL rather than the raw value of the `src` attribute of the clicked element.48 | ? | Yes | 14 | ? | ? | No | ? | No | ? |
| `targetElementId` | No | No | 63 | ? | No | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#type-OnClickData) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/OnClickData>

menus.ACTION\_MENU\_TOP\_LEVEL\_LIMIT
=====================================



The maximum number of top level extension items that can be added to a menu item whose [`ContextType`](contexttype) is "browser\_action" or "page\_action". Any items beyond this limit will be ignored.

 Its value is `6` on Firefox and Chrome.

 For compatibility with other browsers, Firefox makes this property available via the `contextMenus` namespace as well as the `menus` namespace.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ACTION_MENU_TOP_LEVEL_LIMIT` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#property-ACTION_MENU_TOP_LEVEL_LIMIT) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/ACTION_MENU_TOP_LEVEL_LIMIT>

menus.removeAll()
=================



Removes all menu items added by the extension.

 For compatibility with other browsers, Firefox makes this method available via the `contextMenus` namespace as well as the `menus` namespace.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.menus.removeAll()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when all items have been removed.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeAll` | Yes | Yes | 5548 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


Examples
--------



This example adds two menu items. When the user clicks the item labeled "Remove all!", the extension removes both items using `removeAll()`.

 
```
function onRemoved() {
  console.log("items removed successfully");
}

browser.menus.create({
  id: "click-me",
  title: "Click me!",
  contexts: ["all"],
});

browser.menus.create({
  id: "remove-all",
  title: "Remove all!",
  contexts: ["all"],
});

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "remove-all") {
    let removing = browser.menus.removeAll();
    removing.then(onRemoved);
  }
});

```
  **Note:** This API is based on Chromium's [`chrome.contextMenus`](https://developer.chrome.com/docs/extensions/reference/contextMenus/#method-removeAll) API. This documentation is derived from [`context_menus.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/context_menus.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/removeAll>

menus.onHidden
==============



Fired when the browser stops displaying a menu: for example because the user clicked outside it or selected an item.

 It is only triggered for menus that can be manipulated using the [`menus`](../menus) API itself: this includes the context menu, the browser's tools menu, and the bookmarks menu.

 This is most likely to be used in combination with the [`menus.onShown`](onshown) and [`menus.refresh()`](refresh) APIs: an extension can update the menu when it is shown, then undo the changes when it is hidden.

 Firefox makes this event available via the `contextMenus` namespace as well as the `menus` namespace.



Syntax
------




```
browser.menus.onHidden.addListener(listener)
browser.menus.onHidden.removeListener(listener)
browser.menus.onHidden.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed no parameters.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHidden` | No | No | 6060 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This example just logs a message whenever a menu is hidden:

 
```
function hidden() {
  console.log("Menu was hidden");
}

browser.menus.onHidden.addListener(hidden);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/onHidden>

i18n.LanguageCode
=================


A [language tag](https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.10) such as `"en-US"` or "`fr`".


Type
----


Values of this type are strings.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `LanguageCode` | 47 | 14 | 45 | ? | 34 | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.i18n`](https://developer.chrome.com/docs/extensions/reference/i18n/#type-LanguageCode) API. This documentation is derived from [`i18n.json`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/extensions/common/api/i18n.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/LanguageCode>

idle.setDetectionInterval()
===========================



Sets the interval, in seconds, used to determine when the system is in an idle state for [`idle.onStateChanged`](onstatechanged) events. The default interval is 60 seconds.

 The detection interval is specific to the extension that calls the method. Changing the interval in one extension will not affect the detection interval in another extension.



Syntax
------



```
browser.idle.setDetectionInterval(
  intervalInSeconds // integer
)

```
### Parameters


 `intervalInSeconds`  `integer`. Threshold, in seconds, used to determine when the system is in an idle state. The minimum value you can supply here is 15.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setDetectionInterval` | Yes | 15 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |


Examples
--------




```
browser.idle.setDetectionInterval(15);

```
  **Note:** This API is based on Chromium's [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/#method-setDetectionInterval) API. This documentation is derived from [`idle.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/idle.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle/setDetectionInterval>

ExtensionInfo
=============


An `ExtensionInfo` object contains information about an add-on.


Type
----



It is an object with the following properties:

  `description`  `string`. The add-on's description, taken from the manifest.json [description](../../manifest.json/description) key.

  `disabledReason`  `string`. If the add-on is disabled, the reason it was disabled. One of "unknown" or "permissions\_increase".

  `enabled`  `boolean`. Whether or not the add-on is currently enabled.

  `homepageUrl`  `string`. The add-on's homepage URL, taken from the manifest.json [homepage\_url](../../manifest.json/homepage_url) key.

  `hostPermissions`  `array` of `string`. The add-on's [host permissions](../../manifest.json/permissions#host_permissions).

  `icons`  `array` of `object`. Information about the add-on's icons. An array of objects, one for each icon. Each object contains two properties:

 * `size`: an integer representing the icon's width and height in pixels.
* `url`: a string containing a relative URL to the icon, starting at the add-on's root.

  `id`  `string`. The add-on's ID.

  `installType`  `string`. String describing how the add-on was installed. One of the following:

 * "admin": the add-on was installed because of an administrative policy.
* "development": the add-on was installed unpacked from disk.
* "normal": the add-on was installed normally from an install package.
* "sideload": the add-on was installed by some other software on the user's computer.
* "other": the add-on was installed in some other way.

  `mayDisable`  `boolean`. Whether this add-on can be disabled or uninstalled by the user.

  `name`  `string`. The add-on's name, taken from the manifest.json [name](../../manifest.json/name) key.

  `offlineEnabled`  `boolean`. Whether the add-on claims to support offline.

  `optionsUrl`  `string`. URL for the item's [options page](../../user_interface/options_pages), if it has one. This is a relative URL, starting at the add-on's root.

  `permissions`  `array` of `string`. The add-on's [API permissions](../../manifest.json/permissions#api_permissions).

  `shortName`  `string`. A short version of the add-on's name, taken from the manifest.json [short\_name](../../manifest.json/short_name) key.

  `type`  `string`. String describing the type of add-on. This is used to distinguish extensions from apps and themes. It may take any of the following values:

 * "extension": most common type of add-on.
* "hosted\_app"
* "packaged\_app"
* "legacy\_packaged\_app"
* "theme"

  `updateUrl`  `string`. URL for updates to this add-on, taken from the manifest.json [browser\_specific\_settings](../../manifest.json/browser_specific_settings) key.

  `version`  `string`. Version of this add-on, taken from the manifest.json [version](../../manifest.json/version) key.

  `versionName`  `string`. Descriptive name for this add-on's version, taken from the manifest.json [version\_name](../../manifest.json/version_name) key.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ExtensionInfo` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `disabledReason` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `offlineEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `type` | Yes | 79 | 55 | ? | Yes | No | ? | ? | 55 | ? | No | ? |
| `versionName` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#type-ExtensionInfo) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/ExtensionInfo>

management.get()
================



Retrieves an [`ExtensionInfo`](extensioninfo) object containing information about the specified add-on.

 This API requires the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingInfo = browser.management.get(
  id                  // string
)

```
### Parameters


 `id`  `string`. ID of the add-on whose info you want to retrieve.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [`ExtensionInfo`](extensioninfo) object, containing information about the add-on. The promise will be rejected if no extension with the given ID is installed or the extension is not allowed to be accessed by the caller.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 79 | 56 | ? | Yes | No | ? | ? | 56 | ? | No | ? |


Examples
--------



Log the name of the add-on whose ID is "my-add-on":

 
```
let id = "my-add-on";

function got(info) {
  console.log(info.name);
}

let getting = browser.management.get(id);
getting.then(got);

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-get) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/get>

idle.IdleState
==============


String describing the device's idle state.


Type
----


Values of this type are strings. Possible values are: `"active"`, `"idle"`, `"locked"`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `IdleState` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/#type-IdleState) API. This documentation is derived from [`idle.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/idle.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle/IdleState>

idle.queryState()
=================



Returns `"locked"` if the system is locked, `"idle"` if the user has not generated any input for a specified number of seconds, or `"active"` otherwise.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let querying = browser.idle.queryState(
  detectionIntervalInSeconds // integer
)

```
### Parameters


 `detectionIntervalInSeconds`  `integer`. The system is considered idle if `detectionIntervalInSeconds` seconds have elapsed since the last user input detected.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [`idle.IdleState`](idlestate) string, indicating the current state.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `queryState` | Yes | 15 | 45Before version 51, Firefox always reports 'active'. After version 51, Firefox reports 'active' or 'idle' as appropriate. | ? | Yes | No | ? | ? | 48Before version 51, Firefox always reports 'active'. After version 51, Firefox reports 'active' or 'idle' as appropriate. | ? | No | ? |
| `locked` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



In this simple snippet, we call `queryState()` and then check if the returned `newState` is `idle` or `active`, logging a message as appropriate. Because we have specified a `detectionIntervalInSeconds` of 15, an `idle` state will only be reported if there has been no user activity for at least 15 seconds

 
```
function onGot(newState) {
  if (newState === 'idle') {
    console.log('Please come back — we miss you!');
  } else if (newState === 'active') {
    console.log('Glad to still have you with us!');
  }
}

let querying = browser.idle.queryState(15);
querying.then(onGot);

```
  **Note:** This API is based on Chromium's [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/#method-queryState) API. This documentation is derived from [`idle.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/idle.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle/queryState>

idle.onStateChanged
===================



Fired when the system changes to an active, idle or locked state. The event listener is passed a string that has one of three values:

 * "locked" if the screen is locked or the screensaver activates
* "idle" if the system is unlocked and the user has not generated any input for a specified number of seconds. This number defaults to 60, but can be set using [`idle.setDetectionInterval()`](setdetectioninterval).
* "active" when the user generates input on an idle system.



Syntax
------




```
browser.idle.onStateChanged.addListener(listener)
browser.idle.onStateChanged.removeListener(listener)
browser.idle.onStateChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `newState`  [`idle.IdleState`](idlestate). The new idle state.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onStateChanged` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `locked` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------




```
function newState(state) {
  console.log(`New state: ${state}`);
}

browser.idle.onStateChanged.addListener(newState);

```
  **Note:** This API is based on Chromium's [`chrome.idle`](https://developer.chrome.com/docs/extensions/reference/idle/#event-onStateChanged) API. This documentation is derived from [`idle.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/idle.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle/onStateChanged>

management.install()
====================



Installs and enables a theme extension from the given URL.

 This API requires the "management" [API permission](../../manifest.json/permissions) and will only work with signed themes.

 This is an asynchronous function that returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.management.install(options)

```
### Parameters


 options  An object that includes the URL of the XPI file of the theme at [addons.mozilla.org](https://addons.mozilla.org) and an optional a hash of the XPI file, using sha256 or stronger.

  ### Return value


A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object, containing the `ExtensionID` defined for the theme in manifest.json.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `install` | No | No | 63The installable file pointed to by `url` must be a [theme](https://developer.mozilla.org/docs/Mozilla/Add-ons/Themes), and not a normal browser extension. | ? | No | No | ? | ? | 63The installable file pointed to by `url` must be a [theme](https://developer.mozilla.org/docs/Mozilla/Add-ons/Themes), and not a normal browser extension. | ? | No | ? |


Examples
--------



Cycle through a list of themes:

 
```
"use strict";

const themes = [
  "https://addons.mozilla.org/firefox/downloads/file/1063216/insightscare-1.0-fx.xpi",
  "https://addons.mozilla.org/firefox/downloads/file/1063419/orange\_roses-1.0-fx.xpi",
  "https://addons.mozilla.org/firefox/downloads/file/1062647/sticktoyourguns-2.0-fx.xpi",
  "https://addons.mozilla.org/firefox/downloads/file/0/bad\_url.xpi",
];

let current;

async function install(url) {
  try {
    current = url;
    const { id } = await browser.management.install({ url });
    console.log(`Theme installed: ${id}`);
  } catch (e) {
    console.error(`Installation failed: ${e}`);
  }
}

browser.browserAction.onClicked.addListener(() => {
  const id = themes.indexOf(current);
  install(themes[(id + 1) % themes.length]);
});

for (const url of themes) {
  browser.menus.create({
    title: url,
    onclick: () => install(url),
    contexts: ["browser\_action"],
  });
}

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/install>

management.uninstall()
======================



Uninstalls an add-on, given its ID.

 This API requires the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let uninstalling = browser.management.uninstall(
  id,                  // string
  options              // object
)

```
### Parameters



 `id`  `string`. ID of the add-on to uninstall.

  
`options` Optional
  `object`. Object which may contain a single property, `showConfirmDialog`. If `showConfirmDialog` is `true`, the browser will show a dialog asking the user to confirm that the add-on should be uninstalled.

   * If `id` is the calling add-on's ID, `showConfirmDialog` defaults to `false`.
* If `id` is a the ID of a different add-on, the `showConfirmDialog` option is ignored and the confirmation dialog is always shown.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be rejected with an error message if the user canceled uninstall.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `uninstall` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Uninstall the add-on whose ID is "my-addon-id", asking the user to confirm. In the callback, check whether the user canceled uninstallation.

 Note that we haven't passed a fulfillment handler because if uninstallation succeeds, the add-on is no longer around to handle it.

 
```
let id = "my-addon-id";

function onCanceled(error) {
  console.log(`Uninstall canceled: ${error}`);
}

let uninstalling = browser.management.uninstall(id);
uninstalling.then(null, onCanceled);

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-uninstall) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/uninstall>

management.uninstallSelf()
==========================



Uninstalls the calling add-on.

 This API *does not* require the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let uninstallingSelf = browser.management.uninstallSelf(
  options              // object
)

```
### Parameters


 
`options` Optional
  `object`. Object which may two properties, both optional:

  
`showConfirmDialog` Optional
  Boolean. If `showConfirmDialog` is `true`, the browser will show a dialog asking the user to confirm that the add-on should be uninstalled. Defaults to `false`.

  
`dialogMessage` Optional
  String. An extra message that will be displayed in the confirmation dialog.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be rejected with an error message if the user canceled uninstall.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `uninstallSelf` | Yes | 79 | 51 | ? | Yes | No | ? | ? | 51 | ? | No | ? |
| `dialogMessage` | No | No | 51 | ? | No | No | ? | ? | 51 | ? | No | ? |


Examples
--------



Uninstall the add-on, asking the user to confirm. In the callback, check whether the user canceled uninstallation.

 Note that we haven't passed a fulfillment handler because if uninstallation succeeds, the add-on is no longer around to handle it.

 
```
function onCanceled(error) {
  console.log(`Canceled: ${error}`);
}

let uninstalling = browser.management.uninstallSelf({
  showConfirmDialog: true
});

uninstalling.then(null, onCanceled);

```
 The same, but also adding a custom message to the dialog:

 
```
function onCanceled(error) {
  console.log(`Canceled: ${error}`);
}

let uninstalling = browser.management.uninstallSelf({
  showConfirmDialog: true,
  dialogMessage: "Testing self-uninstall"
});

uninstalling.then(null, onCanceled);

```
  **Note:**

 This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-uninstallSelf) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/uninstallSelf>

management.getPermissionWarningsById()
======================================



When the user installs or upgrades an add-on, the browser may warn the user about any particularly powerful [permissions](../../manifest.json/permissions) that the add-on has requested. Not all permissions result in warnings, and this behavior is not standardized across browsers.

 Given the ID of an add-on, this function returns the permission warnings for it as an array of strings.

 This API requires the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingWarnings = browser.management.getPermissionWarningsById(
  id                  // string
)

```
### Parameters


 `id`  `string`. ID of the add-on whose permission warnings you want to retrieve.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of strings, each of which contains the text of a permission warning.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPermissionWarningsById` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the permission warnings for the add-on whose ID is "my-add-on":

 
```
let id = "my-add-on";

function gotWarnings(warnings) {
  for (const warning of warnings) {
    console.log(warning);
  }
}

browser.management.getPermissionWarningsById(id).then(gotWarnings);

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-getPermissionWarningsById) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/getPermissionWarningsById>

management.getPermissionWarningsByManifest()
============================================



When the user installs or upgrades an add-on, the browser may warn the user about any particularly powerful [permissions](../../manifest.json/permissions) that the add-on has requested. Not all permissions result in warnings, and this behavior is not standardized across browsers.

 Given the text of a [manifest.json](../../manifest.json) file, this function returns the permission warnings that would be given for the resulting add-on, as an array of strings.

 This API *does not* require the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingWarnings = browser.management.getPermissionWarningsByManifest(
  manifestString      // string
)

```
### Parameters


 `manifestString`  `string`. String containing the manifest file. This must be a valid manifest: for example, it must contain all the mandatory manifest keys.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of strings, each of which contains the text of a permission warning.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPermissionWarningsByManifest` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the permission warnings for the given manifest file:

 
```
let manifest = {
  "manifest\_version": 2,
  "name": "test",
  "version": "1.0",
  "permissions": ["management", "<all\_urls>"]
}

let manifestString = JSON.stringify(manifest);

function gotWarnings(warnings) {
  console.log(warnings);
}

function gotError(error) {
  console.log(`Error: ${error}`);
}

let gettingWarnings = browser.management.getPermissionWarningsByManifest(manifestString);
gettingWarnings.then(gotWarnings, gotError);

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-getPermissionWarningsByManifest) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/getPermissionWarningsByManifest>

management.onInstalled()
========================



Fired when an add-on is installed.

 This API requires the "management" [API permission](../../manifest.json/permissions).



Syntax
------




```
browser.management.onInstalled.addListener(listener)
browser.management.onInstalled.removeListener(listener)
browser.management.onInstalled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  Callback function that will be called when this event occurs. The function will be passed the following argument:

  `info`  [`ExtensionInfo`](extensioninfo): info about the add-on that was installed.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInstalled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |


Examples
--------



Log the names of add-ons when they are installed:

 
```
browser.management.onInstalled.addListener((info) => {
  console.log(`${info.name} was installed`);
});

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#event-onInstalled) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/onInstalled>

management.getSelf()
====================



Retrieves an [`ExtensionInfo`](extensioninfo) object containing information about the calling add-on.

 This API *does not* require the "management" [API permission](../../manifest.json/permissions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingSelf = browser.management.getSelf()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [`ExtensionInfo`](extensioninfo) object, containing information about the add-on.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getSelf` | Yes | 79 | 51 | ? | No | No | ? | ? | 51 | ? | No | ? |


Examples
--------



Log the add-on's name:

 
```
function gotSelf(info) {
  console.log(`Add-on name: ${info.name}`);
}

const gettingSelf = browser.management.getSelf();
gettingSelf.then(gotSelf);

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#method-getSelf) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/getSelf>

management.onUninstalled()
==========================



Fired when an add-on is uninstalled.

 This API requires the "management" [API permission](../../manifest.json/permissions).



Syntax
------




```
browser.management.onUninstalled.addListener(listener)
browser.management.onUninstalled.removeListener(listener)
browser.management.onUninstalled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  Callback function that will be called when this event occurs. The function will be passed the following argument:

  `info`  [`ExtensionInfo`](extensioninfo): info about the add-on that was uninstalled.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onUninstalled` | Yes | 79 | 55["Before version 56, only extensions whose `type` is `'theme'` are supported.", "This event is not fired when the extension is in the \"pending uninstall\" state. The event is fired as expected once the extension is completely removed (for example, when the `about:addons` tab is closed)."] | ? | Yes | No | ? | ? | 55["Before version 56, only extensions whose `type` is `'theme'` are supported.", "This event is not fired when the extension is in the \"pending uninstall\" state. The event is fired as expected once the extension is completely removed (for example, when the `about:addons` tab is closed)."] | ? | No | ? |


Examples
--------



Log the names of add-ons when they are uninstalled:

 
```
browser.management.onUninstalled.addListener((info) => {
  console.log(`${info.name} was uninstalled`);
});

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#event-onUninstalled) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/onUninstalled>

management.onEnabled()
======================



The event listener called when the `enabled` event is fired, indicating that an add-on is now enabled.

 This API requires the "management" [API permission](../../manifest.json/permissions).



Syntax
------




```
browser.management.onEnabled.addListener(listener)
browser.management.onEnabled.removeListener(listener)
browser.management.onEnabled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  Callback function that will be called when this event occurs. The function will be passed the following argument:

  `info`  [`ExtensionInfo`](extensioninfo): info about the add-on that was enabled.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onEnabled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |


Examples
--------



Log the names of add-ons when they are enabled:

 
```
browser.management.onEnabled.addListener((info) => {
  console.log(`${info.name} was enabled`);
});

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#event-onEnabled) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/onEnabled>

management.onDisabled()
=======================



Fired when an add-on is disabled.

 This API requires the "management" [API permission](../../manifest.json/permissions).



Syntax
------




```
browser.management.onDisabled.addListener(listener)
browser.management.onDisabled.removeListener(listener)
browser.management.onDisabled.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `function`  Callback function that will be called when this event occurs. The function will be passed the following argument:

  `info`  [`ExtensionInfo`](extensioninfo): info about the add-on that was disabled.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onDisabled` | Yes | 79 | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | Yes | No | ? | ? | 55Before version 56, only extensions whose `type` is `'theme'` are supported. | ? | No | ? |


Examples
--------



Log the names of add-ons when they are disabled:

 
```
browser.management.onDisabled.addListener((info) => {
  console.log(`${info.name} was disabled`);
});

```
  **Note:** This API is based on Chromium's [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/#event-onDisabled) API. This documentation is derived from [`management.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/management.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/onDisabled>

notifications.clear()
=====================



Clears a notification, given its ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let clearing = browser.notifications.clear(
  id                            // string
)

```
### Parameters


 `id`  `string`. The ID of the notification to clear. This is the same as the ID passed into [`notifications.create()`](create)'s callback.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean: `true` if the notification was cleared, or `false` if it was not (for example, because the notification referenced by `id` did not exist).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `clear` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



This example shows a notification when the user clicks a browser action, unless the notification was already being shown, in which case it clears the notification:

 
```
let myNotification = "my-notification";

function toggleAlarm(all) {
  if (myNotification in all) {
    browser.notifications.clear(myNotification);
  } else {
    browser.notifications.create(myNotification, {
      "type": "basic",
      "iconUrl": browser.runtime.getURL("icons/cake-48.png"),
      "title": "Am imposing title",
      "message": "Some interesting content"
    });
  }
}

function handleClick() {
  let gettingAll = browser.notifications.getAll();
  gettingAll.then(toggleAlarm);
}

browser.browserAction.onClicked.addListener(handleClick);

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/clear>

notifications.getAll()
======================



Gets all currently active notifications created by the extension.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingAll = browser.notifications.getAll()

```
### Parameters


None.

### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object. Each currently active notification is a property of this object: the name of the property is the ID of the notification, and the value of the property is a [`notifications.NotificationOptions`](notificationoptions) object describing that notification.

 Note that you can define an ID for a notification explicitly by passing it into [`notifications.create()`](create). If you don't do this, the browser will generate one. Explicitly-specified IDs are strings, but generated IDs are numbers.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAll` | 29 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



This example shows a notification when the user clicks a browser action, unless the notification was already being shown, in which case it clears the notification. It uses getAll() to figure out whether the notification is being shown:

 
```
const myNotification = "my-notification";

function toggleAlarm(all) {
  const ids = Object.keys(all);
  if (ids.includes(myNotification)) {
    browser.notifications.clear(myNotification);
  } else {
    console.log("showing");

    browser.notifications.create(myNotification, {
      type: "basic",
      title: "Am imposing title",
      message: "Some interesting content",
    });
  }
}

function handleClick() {
  console.log("clicked");
  browser.notifications.getAll().then(toggleAlarm);
}

browser.browserAction.onClicked.addListener(handleClick);

```
 This example logs the title of all active notifications:

 
```
function logNotifications(all) {
  for (const id in all) {
    console.log(`Title: ${all[id].title}`);
  }
}

browser.notifications.getAll().then(logNotifications);

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/getAll>

notifications.update()
======================



Updates a notification, given its ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let updating = browser.notifications.update(
  id,                            // string
  options                        // NotificationOptions
)

```
### Parameters


 `id`  `string`. The ID of the notification to update. This is the same as the ID passed into [`notifications.create()`](create)'s callback.

  `options`  [`notifications.NotificationOptions`](notificationoptions). Defines the notification's new content and behavior.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a boolean: `true` if the notification was updated, or `false` if it was not (for example, because the notification referenced by `id` did not exist).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `update` | 28 | 17 | No | ? | 25Not supported on macOS. | No | ? | ? | No | ? | No | ? |


Examples
--------



This example uses `update()` to update a progress notification. Clicking the browser action shows the notification and starts an [`alarm`](../alarms), which we use to update the notification's progress indicator.

 Note that you'll need the "alarms" [permission](../../manifest.json/permissions) to create alarms (as well as the "notifications" permission to create notifications). Also note that Firefox does not support the `progress` attribute.

 
```
let cakeNotification = "cake-notification";

/\*

CAKE\_INTERVAL is set to 0.3 seconds in this example.
Such a short period is chosen to make the extension's behavior
more obvious, but this is not recommended in real life.
Note that in Chrome, alarms cannot be set for less than
a minute.

\*/
let CAKE\_PREP\_INTERVAL = 0.005;

let progress = 0;

browser.alarms.onAlarm.addListener((alarm) => {
  progress += 10;
  if (progress > 100) {
    browser.notifications.clear(cakeNotification);
    browser.alarms.clear("cake-progress");
  } else {
    browser.notifications.update(cakeNotification, { progress });
  }
});

browser.browserAction.onClicked.addListener(() => {
  browser.notifications.getAll((all) => {
    if (all.length > 0) {
      browser.notifications.clear(cakeNotification);
      return;
    }
    progress = 0;
    browser.notifications.create(cakeNotification, {
      type: "progress",
      iconUrl: browser.extension.getURL("icons/cake-48.png"),
      title: "Your cake is being prepared…",
      message: "Something something cake",
      progress,
    });
    browser.alarms.create(
      "cake-progress",
      { periodInMinutes: CAKE\_PREP\_INTERVAL }
    );
  });
});

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/update>

notifications.onButtonClicked
=============================


Fired when the user clicks one of the notification's buttons.


Syntax
------




```
browser.notifications.onButtonClicked.addListener(listener)
browser.notifications.onButtonClicked.removeListener(listener)
browser.notifications.onButtonClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `notificationId`  `string`. ID of the notification whose button was clicked.

  `buttonIndex`  `integer`. The [zero-based](https://en.wikipedia.org/wiki/Zero-based_numbering) index of the button that was clicked.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onButtonClicked` | 28 | 17 | No | ? | 25 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/onButtonClicked>

notifications.onClicked
=======================


Fired when the user clicks a notification, but not on any of the notification's buttons (for that, see [`notifications.onButtonClicked`](onbuttonclicked)).


Syntax
------




```
browser.notifications.onClicked.addListener(callback)
browser.notifications.onClicked.removeListener(listener)
browser.notifications.onClicked.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `notificationId`  `string`. ID of the notification that the user clicked.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onClicked` | 28 | 17 | 47 | ? | 25 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



In this simple example we add a listener to the [`notifications.onClicked`](onclicked) event to listen for system notifications being clicked. When this occurs, we log an appropriate message to the console.

 
```
browser.notifications.onClicked.addListener((notificationId) => {
  console.log(`Notification ${notificationId} was clicked by the user`);
});

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/onClicked>

notifications.NotificationOptions
=================================



This type contains all the data needed to:

 * create a notification using [`notifications.create()`](create),
* update an existing notification using [`notifications.update()`](update).



Type
----



Values of this type are objects. They contain the properties listed below.

 The first three properties - `type`, `title`, `message` - are mandatory in [`notifications.create()`](create), but optional in [`notifications.update()`](update). Firefox currently: only supports the `type`, `title`, `message`, and `iconUrl` properties; and the only supported value for `type` is `'basic'`.

  `type`  [`notifications.TemplateType`](templatetype). The type of notification you want. Depending on your choice here, certain other properties are either mandatory or are not permitted.

  `message`  `string`. The notification's main content.

  `title`  `string`. The notification's title.

  
`iconUrl` Optional
  `string`. A URL pointing to an icon to display in the notification. The URL can be: a data URL, a blob URL, a http or https URL, or the [relative URL of a file within the extension](../../chrome_incompatibilities#relative_urls). When using an SVG image, ensure that the image includes height and width attributes, for example, `<svg width="96" height="96"…`. Otherwise, the image may not display.

  
`contextMessage` Optional
  `string`. Supplementary content to display.

  
`priority` Optional
  `number`. The notification's priority: may be 0, 1, or 2. Defaults to 0 if omitted.

  
`eventTime` Optional
  `number`. A timestamp for the notification in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  
`buttons` Optional
  `array` of `button`. An array of up to 2 buttons to include in the notification. You can listen for button clicks using [`notifications.onButtonClicked`](onbuttonclicked). Each button is specified as an object with the following properties:

  `title`  `string`. Title for the button.

  
`iconUrl` Optional
  `string`. URL pointing to an icon for the button.

    `imageUrl`  `string`. A URL pointing to an image to use in the notification. The URL can be: a data URL, a blob URL, or the [relative URL](../../chrome_incompatibilities#relative_urls) of a file within the extension. When using an SVG image, ensure that the image includes height and width attributes, for example, `<svg width="96" height="96"…`. Otherwise, the image may not display.

 *This property is only permitted if `type` is `"image"`. In this case, it is mandatory if the `NotificationOptions` is used in [`notifications.create()`](create), and optional if it is used in [`notifications.update()`](update).*

  `items`  `array` of `item`. An array of items to include in the notification. Depending on the settings for the operating system's notification mechanism, some of the items you provide might not be displayed. Each item is specified as an object with the following properties:

  `title`  `string`. Title to display in the item.

  `message`  `string`. Message to display in the item.

   *This property is only permitted if `type` is `"list"`. In this case, it is mandatory if the `NotificationOptions` is used in [`notifications.create()`](create), and optional if it is used in [`notifications.update()`](update).*

  `progress`  `integer`. An integer between 0 and 100, used to represent the current progress in a progress indicator.

 *This property is only permitted if `type` is `"progress"`. In this case, it is mandatory if the `NotificationOptions` is used in [`notifications.create()`](create), and optional if it is used in [`notifications.update()`](update).*

   Note that `appIconMaskUrl` and `isClickable` are not supported.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `NotificationOptions` | Yes | 17 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `appIconMaskUrl` | Yes | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | Yes | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `buttons` | Yes | 79 | No | ? | NoSpecifying the 'buttons' option will cause an asynchronous error on Opera. | No | ? | ? | No | ? | No | ? |
| `contextMessage` | 31 | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | NoSpecifying this option doesn't throw an error, but its value is ignored, on Opera 18 and above. | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `eventTime` | Yes | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | Yes | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `imageUrl` | Yes | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `isClickable` | 32 | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | NoSetting 'isClickable' to false will cause an asynchronous error on Opera 19 and above. Older Opera versions throw an error synchronously if this options is given. | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `items` | YesOn macOS only the first item is shown. | 79On macOS only the first item is shown. | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `priority` | Yes | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | Yes | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `progress` | 30 | 79 | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | NoSpecifying this option doesn't throw an error, but its value is ignored, on Opera 17 and above. | No | ? | ? | NoSpecifying this option doesn't throw an error, but its value is ignored. | ? | No | ? |
| `requireInteraction` | 50 | 79 | No | ? | NoSpecifying this option doesn't throw an error, but its value is ignored, on Opera 37 and above. | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/NotificationOptions>

notifications.TemplateType
==========================



This is a string, and represents the type of notification to create. There are four types of notification: "basic", "image", "list", "progress".

 This is passed into [`notifications.create()`](create) and [`notifications.update()`](update) as the `type` property of [`NotificationOptions`](notificationoptions).



Type
----



Values of this type are strings. Possible values are:

 * `"basic"`: the notification includes:
	+ a title (`NotificationOptions.title`)
	+ a message (`NotificationOptions.message`)
	+ an icon (`NotificationOptions.iconUrl`) Optional
	+ an extra message (`NotificationOptions.contextMessage`) Optional
	+ up to two buttons (`NotificationOptions.buttons`) Optional
* `"image"`: everything in `"basic"` and also:
	+ an image (`NotificationOptions.imageUrl`)
* `"list"`: everything in `"basic"` and also:
	+ a list of items (`NotificationOptions.items`)
* `"progress"`: everything in `"basic"` and also:
	+ a progress indicator (`NotificationOptions.progress`)

 Currently Firefox only supports "basic" here.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TemplateType` | Yes | 17 | 45Only the 'basic' type is supported. | ? | YesOnly the 'basic' type is supported. | No | ? | ? | 48Only the 'basic' type is supported. | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/TemplateType>

notifications.onClosed
======================


Fired when a notification is closed, either by the system or by the user.


Syntax
------




```
browser.notifications.onClosed.addListener(listener)
browser.notifications.onClosed.removeListener(listener)
browser.notifications.onClosed.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `notificationId`  `string`. ID of the notification that closed.

  `byUser`  `boolean`. `true` if the notification was closed by the user, or `false` if it was closed by the system. This argument is not supported in Firefox.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onClosed` | 28 | 17 | 45 | ? | 25 | No | ? | ? | 48 | ? | No | ? |
| `byUser` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



In this simple example we add a listener to the [`notifications.onClosed`](onclosed) event to listen for system notifications being closed. When this occurs, we log an appropriate message to the console.

 
```
browser.notifications.onClosed.addListener((notificationId) => {
  console.log(`Notification ${notificationId} has closed.`);
});

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/onClosed>

omnibox.onInputCancelled
========================


Fired when the user has cancelled their interaction with your extension (for example, by clicking outside the address bar).


Syntax
------




```
browser.omnibox.onInputCancelled.addListener(listener)
browser.omnibox.onInputCancelled.removeListener(listener)
browser.omnibox.onInputCancelled.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


The listener function is passed no parameters.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInputCancelled` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------




```
browser.omnibox.onInputCancelled.addListener(() => {
  console.log("The user cancelled the session.");
});

```
  **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/onInputCancelled>

omnibox.OnInputEnteredDisposition
=================================



The `omnibox.OnInputEnteredDisposition` type describes how the extension should handle a user selection from the suggestions in the address bar's drop-down list.

 It's passed into the [`omnibox.onInputEntered`](oninputentered) event listener, along with the selection itself.



Type
----



Values of this type are strings. They may take any one of the following values:

  "currentTab"  Open the selection in the current tab.

  "newForegroundTab"  Open the selection in a new tab, and bring this new tab into the foreground.

  "newBackgroundTab"  Open the selection in a new background tab, keeping the current tab in the foreground.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `OnInputEnteredDisposition` | 44 | 79 | 52 | ? | 31 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/OnInputEnteredDisposition>

pkcs11.installModule()
======================



Installs the named PKCS #11 module, making it available to Firefox.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let installing = browser.pkcs11.installModule(
  name,              // string
  flags              // integer
)

```
### Parameters


 `name`  `string`. Name of the module to install. This must match the `name` property in the [PKCS #11 manifest](../../native_manifests#pkcs_11_manifests) for the module.

  
`flags` Optional
  `integer`. Flags to pass to the module.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the module is installed.

 If the module could not be found or some other error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `installModule` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Installs a module, then lists its slots and list the tokens they contain:

 
```
function onInstalled() {
  return browser.pkcs11.getModuleSlots("my\_module");
}

function onGotSlots(slots) {
  for (const slot of slots) {
    console.log(`Slot: ${slot.name}`);
    if (slot.token) {
      console.log(`Contains token: ${slot.token.name}`);
    } else {
      console.log("Is empty");
    }
  }
}

browser.pkcs11.installModule("my\_module").then(onInstalled).then(onGotSlots);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11/installModule>

notifications.onShown
=====================


Fired immediately after a notification has been shown.


Syntax
------




```
browser.notifications.onShown.addListener(listener)
browser.notifications.onShown.removeListener(listener)
browser.notifications.onShown.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `notificationId`  `string`. ID of the notification that has been shown.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onShown` | No | No | 56 | ? | No | No | ? | ? | 56 | ? | No | ? |


Examples
--------



Add a listener to the [`notifications.onShown`](onshown) event and log its details:

 
```
function logShown(itemId) {
  console.log(`shown: ${itemId}`);
  browser.notifications.getAll().then((all) => {
    console.log(all[itemId]);
  })
}

browser.notifications.onShown.addListener(logShown);

```
  **Note:** This API is based on Chromium's [`chrome.notifications`](https://developer.chrome.com/docs/extensions/reference/notifications/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications/onShown>

omnibox.onInputStarted
======================



Fired when the user starts interacting with your extension by entering its keyword in the address bar and then pressing the space key.

 This will be sent before any [`omnibox.onInputChanged`](oninputchanged) events.



Syntax
------




```
browser.omnibox.onInputStarted.addListener(listener)
browser.omnibox.onInputStarted.removeListener(listener)
browser.omnibox.onInputStarted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed no arguments.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onInputStarted` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |


Examples
--------




```
browser.omnibox.onInputStarted.addListener(() => {
  console.log("User has started interacting with me.")
});

```
  **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/onInputStarted>

omnibox.onDeleteSuggestion
==========================


 Fired whenever the user deletes a suggestion. A suggestion can be deleted when [`SuggestResult`](suggestresult)`.deletable` is set to true. 


Syntax
------




```
browser.omnibox.onDeleteSuggestion.addListener(listener)
browser.omnibox.onDeleteSuggestion.removeListener(listener)
browser.omnibox.onDeleteSuggestion.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `text`  `string`. The description of the deleted suggestion.

  Examples
--------



This example prints the deleted suggestion to the console:

 
```
function logDeletedSuggestion(text) {
  console.log(`The user deleted: ${text}`);
}

browser.omnibox.onDeleteSuggestion.addListener(logDeletedSuggestion);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onDeleteSuggestion` | 63 | 79 | 109 | ? | 50 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/onDeleteSuggestion>

omnibox.SuggestResult
=====================



The `omnibox.SuggestResult` type defines a suggestion that the extension can add to the address bar's drop-down list.

 The extension's [`omnibox.onInputChanged`](oninputchanged) event listener is passed a callback. To populate the address bar's drop-down list in response to the user's input, the extension can pass an array of `omnibox.SuggestResult` objects into this callback.



Type
----



Values of this type are objects. They have the following properties:

  `content`  This is the value that will appear in the address bar itself when the user highlights this suggestion in the drop-down list. This is also the string sent to the [`omnibox.onInputEntered`](oninputentered) event listener if the user selects this suggestion. If the string is the same as what the user has already typed, this entry will not appear in the drop-down list.

  `deletable`  Whether the suggest result can be deleted by the user.

  `description`  This is the string that's displayed in the address bar's drop-down list.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `SuggestResult` | 9 | 79 | 52'description' is interpreted as plain text, and XML markup is not recognized. | ? | 15 | No | ? | ? | No | ? | No | ? |
| `content` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |
| `deletable` | 63 | 79 | 109 | ? | 50 | No | ? | ? | No | ? | No | ? |
| `description` | 9 | 79 | 52 | ? | 15 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.omnibox`](https://developer.chrome.com/docs/extensions/reference/omnibox/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox/SuggestResult>

pkcs11.getModuleSlots()
=======================



Enumerate a module's slots. This function returns an array containing one entry for each slot. Each entry contains the slot's name and, if the slot contains a token, information about the token.

 You can only call this for a module that is installed in Firefox.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.pkcs11.getModuleSlots(
  name              // string
)

```
### Parameters


 `name`  `string`. Name of the module. This must match the `name` property in the [PKCS #11 manifest](../../native_manifests#pkcs_11_manifests) for the module.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of objects, one for each slot that the module provides access to. Each object has two properties:

 * `name`: the name of the slot
* `token`: if a token is present in this slot, a `Token` object. If no token is present in the slot, this property is `null`.

 `Token` objects have the following properties:

  `name`  `string`. Name of the token.

  `manufacturer`  `string`. Name of the token's manufacturer.

  `HWVersion`  `string`. Hardware version, as a PKCS #11 version number (two 32-bit integers separated with a dot, like "1.0".

  `FWVersion`  `string`. Firmware version, as a PKCS #11 version number (two 32-bit integers separated with a dot, like "1.0".

  `serial`  `string`. Serial number, whose format is defined by the token specification.

  `isLoggedIn`  `boolean`: `true` if the token is logged on already, `false` otherwise.

   If the module could not be found or some other error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getModuleSlots` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Installs a module, then lists its slots and list the tokens they contain:

 
```
function onInstalled() {
  return browser.pkcs11.getModuleSlots("my\_module");
}

function onGotSlots(slots) {
  for (const slot of slots) {
    console.log(`Slot: ${slot.name}`);
    if (slot.token) {
      console.log(`Contains token: ${slot.token.name}`);
    } else {
      console.log("Is empty");
    }
  }
}

browser.pkcs11.installModule("my\_module").then(onInstalled).then(onGotSlots);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11/getModuleSlots>

pkcs11.isModuleInstalled()
==========================



Checks whether the named PKCS #11 module is currently installed in Firefox.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let checking = browser.pkcs11.isModuleInstalled(
  name              // string
)

```
### Parameters


 `name`  `string`. Name of the module to check.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the module is installed, `false` otherwise.

 If the module an error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isModuleInstalled` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Checks whether the module named "pkcs11\_module" is installed:

 
```
function logIsInstalled(isInstalled) {
  console.log(`Module is installed: ${isInstalled}`);
}

browser.pkcs11.isModuleInstalled("pkcs11\_module").then(logIsInstalled);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11/isModuleInstalled>

pkcs11.uninstallModule()
========================



Uninstalls the named PKCS #11 module from Firefox.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let uninstalling = browser.pkcs11.uninstallModule(
  name              // string
)

```
### Parameters


 `name`  `string`. Name of the module to uninstall. This must match the `name` property in the [PKCS #11 manifest](../../native_manifests#pkcs_11_manifests) for the module.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the module is uninstalled.

 If the module could not be found or some other error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `uninstallModule` | No | No | 58 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Uninstalls the module named "pkcs11\_module":

 
```
browser.pkcs11.uninstallModule("pkcs11\_module");

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11/uninstallModule>

privacy.network
===============



The [`privacy.network`](network) property contains privacy-related network settings. Each property is a [`types.BrowserSetting`](../types/browsersetting) object.

 Default values for these properties tend to vary across browsers.



Properties
----------


 `networkPredictionEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If `true`, the browser attempts to speed up web browsing by pre-resolving DNS entries, prerendering sites (using, for example, `<link rel='prefetch' …>`), and preemptively opening TCP and SSL connections to servers.

  `peerConnectionEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If `false`, the [`RTCPeerConnection`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) interface is disabled. Note that [`getUserMedia()`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) is *not* affected by this setting.

  `webRTCIPHandlingPolicy`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a string. This setting allows users to specify the media performance/privacy tradeoffs which affect how WebRTC traffic will be routed and how much local address information is exposed. It may take any one of the following values, from least private to most private:

 * `default`
* `default_public_and_private_interfaces`
* `default_public_interface_only`
* `disable_non_proxied_udp`
* `proxy_only` (only connections using TURN on a TCP connection through a proxy are allowed)

  `httpsOnlyMode`   This setting allows your extension to determine if a user has enabled [HTTPS-Only mode](https://support.mozilla.org/kb/https-only-prefs). This property is read-only on all platforms. Its underlying value is a string that may take one of three values: 

 * `"always"`: HTTPS-Only mode is on.
* `"never"`: HTTPS-Only mode is off.
* `"private_browsing"`: HTTPS-Only mode is on in private browsing windows only.

  `globalPrivacyControl`   this setting allows your extension to determine if a user has enabled [Global Privacy Control](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/globalPrivacyControl). This property is read-only on all platforms. Its underlying value is a boolean where `true` indicates that the browser sends Global Privacy Control signals and `false` indicates the browser does not send the signals. 

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `globalPrivacyControl` | No | No | 95 | ? | No | No | ? | ? | 95 | ? | No | ? |
| `httpsOnlyMode` | Yes | Yes | 84 | ? | Yes | No | ? | ? | 84 | ? | No | ? |
| `networkPredictionEnabled` | Yes | 79 | 54 | ? | Yes | No | ? | ? | 54 | ? | No | ? |
| `peerConnectionEnabled` | No | No | 55 | ? | No | No | ? | ? | 55 | ? | No | ? |
| `webRTCIPHandlingPolicy` | Yes | 79 | 54Starting in Firefox 70, a value of `disable_non_proxied_udp` requires a proxy if one is configured, but allows connections to go through if no proxy is set up. Previously, in this mode WebRTC could only be used if a proxy was configured and TURN over TCP was available; this behavior is now exposed as `proxy_only`. | ? | Yes | No | ? | ? | 54 | ? | No | ? |


Examples
--------



Set the `webRTCIPHandlingPolicy` property:

 
```
function onSet(result) {
  if (result) {
    console.log("success");
  } else {
    console.log("failure");
  }
}

browser.browserAction.onClicked.addListener(() => {

  let getting = browser.privacy.network.webRTCIPHandlingPolicy.get({});
  getting.then((got) => {
    console.log(got.value);
    if ((got.levelOfControl === "controlled\_by\_this\_extension") ||
        (got.levelOfControl === "controllable\_by\_this\_extension")) {
      let setting = browser.privacy.network.webRTCIPHandlingPolicy.set({
        value: "default\_public\_interface\_only"
      });
      setting.then(onSet);
    } else {
      console.log("Not able to set webRTCIPHandlingPolicy");
    }
  });

});

```
  **Note:** This API is based on Chromium's [`chrome.privacy`](https://developer.chrome.com/docs/extensions/reference/privacy/) API. This documentation is derived from [`privacy.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/privacy.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/network>

scripting.ExecutionWorld
========================


 Specifies the execution environment of a script injected with [`scripting.executeScript()`](executescript) or registered with [`scripting.registerContentScripts()`](registercontentscripts). 


Type
----



Values of this type are strings. Possible values are:

 * `ISOLATED` The default execution environment of [content scripts](../../content_scripts). This environment is isolated from the page's context: while they share the same document, the global scopes and available APIs differ.
* `MAIN` The execution environment of the web page. This environment is shared with the web page, without isolation. Scripts in this environment do not have any access to APIs that are only available to content scripts.   **Warning:** Due to the lack of isolation, the web page can detect the executed code and interfere with it. Do not use the `MAIN` world unless it is acceptable for web pages to read, access, or modify the logic or data that flows through the executed code.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ISOLATED` | 102 | 102 | 102 | ? | 88 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |
| `MAIN` | 102 | 102 | No | ? | 88 | 15.4 | ? | ? | No | ? | 15.4 | ? |
| `ExecutionWorld` | 102 | 102 | 102 | ? | 88 | 15.4 | ? | ? | 102 | ? | 15.4 | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#type-ExecutionWorld) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/ExecutionWorld>

scripting.InjectionTarget
=========================


This object contains details specifying the injection target for CSS and JavaScript. Its used in [`scripting.executeScript()`](executescript), [`scripting.insertCSS()`](insertcss), and [`scripting.removeCSS()`](removecss).


Type
----



Values of this type are objects. They contain these properties:

  
`allFrames` Optional
  `boolean`. Whether the script or CSS is injected into all frames within the tab. Defaults to `false`. Cannot be `true` if `frameIds` is specified.

  
`frameIds` Optional
  `array` of `number`. Array of the IDs of the frames to inject into.

  `tabId`  `number`. The ID of the tab to inject into.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `InjectionTarget` | 88 | 88 | 102 | ? | 74 | 15.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 15.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#type-InjectionTarget) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/InjectionTarget>

privacy.services
================


The [`privacy.services`](services) property contains privacy-related settings controlling services offered by the browser or by third parties. Each property is a [`types.BrowserSetting`](../types/browsersetting) object.


Properties
----------


 `passwordSavingEnabled`  A [`types.BrowserSetting`](../types/browsersetting) object whose underlying value is a boolean. If `true`, the browser's password manager will offer to store passwords when the user enters them. Defaults to `true`.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `alternateErrorPagesEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `autofillAddressEnabled` | 70 | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `autofillCreditCardEnabled` | 70 | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `autofillEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `passwordSavingEnabled` | 38 | 79 | 56 | ? | Yes | No | ? | ? | 56 | ? | No | ? |
| `safeBrowsingEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `safeBrowsingExtendedReportingEnabled` | 42 | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `searchSuggestEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `spellingServiceEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `translationServiceEnabled` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Disable the password manager if possible.

 
```
function onSet(result) {
  if (result) {
    console.log("success");
  } else {
    console.log("failure");
  }
}

  let getting = browser.privacy.services.passwordSavingEnabled.get({});
  getting.then((got) => {
    console.log(got.value);
    if ((got.levelOfControl === "controlled\_by\_this\_extension") ||
        (got.levelOfControl === "controllable\_by\_this\_extension")) {
      let setting = browser.privacy.services.passwordSavingEnabled.set({
        value: false
      });
      setting.then(onSet);
    } else {
      console.log("Not able to set passwordSavingEnabled");
    }
  });

```
  **Note:** This API is based on Chromium's [`chrome.privacy`](https://developer.chrome.com/docs/extensions/reference/privacy/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/services>

scripting.getRegisteredContentScripts()
=======================================



Returns all the content scripts registered with [`scripting.registerContentScripts()`](registercontentscripts) or a subset of the registered scripts when using a filter.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let scripts = await browser.scripting.getRegisteredContentScripts(
  filter          // object
)

```
### Parameters


 
`filter` Optional
  [`scripting.ContentScriptFilter`](contentscriptfilter). A filter for the registered script details to return.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an array of [`scripting.RegisteredContentScript`](registeredcontentscript). If any error occurs, the promise is rejected.

Examples
--------



This example returns all the registered content scripts:

 
```
// Register two content scripts.
await browser.scripting.registerContentScripts([
  {
    id: "script-1",
    js: ["script-1.js"],
    matches: ["\*://example.com/\*"],
  },
  {
    id: "script-2",
    js: ["script-2.js"],
    matches: ["\*://example.com/\*"],
  },
]);

// Retrieve all content scripts.
let scripts = await browser.scripting.getRegisteredContentScripts();
console.log(scripts.map((script) => script.id)); // ["script-1", "script-2"]

// Only retrieve the second script.
scripts = await browser.scripting.getRegisteredContentScripts({
  ids: ["script-2"],
});
console.log(scripts.map((script) => script.id)); // ["script-2"]

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getRegisteredContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-getRegisteredContentScripts) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/getRegisteredContentScripts>

scripting.unregisterContentScripts()
====================================



Unregisters one or more content scripts.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
await browser.scripting.unregisterContentScripts(
  scripts         // object
)

```
### Parameters


 
`scripts` Optional
  [`scripting.ContentScriptFilter`](contentscriptfilter). A filter to identify the dynamic content scripts to unregistered. If not specified, all dynamic content scripts are unregistered.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with no arguments when all the scripts are unregistered. If any error occurs, the promise is rejected.

Examples
--------



This example unregisters a registered content script with ID `a-script`:

 
```
try {
  await browser.scripting.unregisterContentScripts({
    ids: ["a-script"],
  });
} catch (err) {
  console.error(`failed to unregister content scripts: ${err}`);
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `unregisterContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-unregisterContentScripts) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/unregisterContentScripts>

scripting.ContentScriptFilter
=============================


This object contains a list of IDs of scripts to retrieve with [`scripting.getRegisteredContentScripts()`](getregisteredcontentscripts) or to unregister with [`scripting.unregisterContentScripts()`](unregistercontentscripts).


Type
----



Values of this type are objects. They contain these properties:

  `ids`  `array` of `string`. Array of scripts IDs.

  
Browser compatibility
---------------------


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#type-ContentScriptFilter) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/ContentScriptFilter>

scripting.updateContentScripts()
================================



Updates registered content scripts. If there are errors during script parsing and file validation, or if the IDs specified do not exist, no scripts are updated.

  **Note:** This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Firefox 102+, this method is also available in Manifest V2.

  To use this API you must have the `"scripting"` [permission](../../manifest.json/permissions) and permission for the page's URL, either explicitly as a [host permission](../../manifest.json/permissions#host_permissions) or using the [activeTab permission](../../manifest.json/permissions#activetab_permission).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



### Syntax



```
await browser.scripting.updateContentScripts(
  scripts         // object
)

```
### Parameters


 `scripts`  `array` of [`scripting.RegisteredContentScript`](registeredcontentscript). Details of a script to update. All the properties are optional except for `id`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that fulfills with an array of [`scripting.RegisteredContentScript`](registeredcontentscript). If any error occurs, the promise is rejected.

Examples
--------



This example updates a content script registered with ID `a-script` by setting `allFrames` to `true`:

 
```
try {
  await browser.scripting.registerContentScripts([
    {
      id: "a-script",
      js: ["script.js"],
      matches: ["\*://example.org/\*"],
    },
  ]);

  // Update content script registered before to allow execution
  // in all frames:
  await browser.scripting.updateContentScripts([
    {
      id: "a-script",
      allFrames: true,
    },
  ]);
} catch (err) {
  console.error(`failed to register or update content scripts: ${err}`);
}

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `updateContentScripts` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#method-updateContentScripts) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/updateContentScripts>

search.query()
==============



Perform a search using the browser's default search engine.

 The results are displayed in the current tab, a new tab, or a new window according to the `disposition` property or in the tab specified in the `tabId` property. If neither is specified, the results display in the current tab.

 To use this function, your extension must have the `"search"` [manifest permission](../../manifest.json/permissions).



Syntax
------



```
browser.search.query(
  queryInfo             // object
)

```
### Parameters


 `queryInfo`  `object`. An object with the following properties:

  
`disposition` Optional
  `string`. The location where the search results are displayed. Valid values are `CURRENT_TAB`, `NEW_TAB`, and `NEW_WINDOW`. Defaults to `CURRENT_TAB`. Cannot be specified with `tabId`.

  
`tabId` Optional
  `integer`. An optional identifier for the tab you want to execute the search in. If this property is omitted, the search results are displayed in a new tab. Cannot be specified with `disposition`.

  `text`  `string`. The search query.

    ### Return value


None.

Examples
--------



A search with the results shown in the current tab (default):

 
```
function search() {
  browser.search.query({
    text: "styracosaurus"
  });
}

browser.browserAction.onClicked.addListener(search);

```
 A search with the results shown in a new window:

 
```
function search() {
  browser.search.query({
    text: "styracosaurus",
    disposition: "NEW\_WINDOW"
  });
}

browser.browserAction.onClicked.addListener(search);

```
 A search with the results shown in a specific tab:

 
```
function search(tab) {
  browser.search.query({
    query: "styracosaurus",
    tabId: tab.id
  });
}

browser.browserAction.onClicked.addListener(search);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `query` | 87 | 87 | 111 | ? | 73 | No | ? | ? | No | ? | No | ? |
| `queryInfo` | 87 | 87 | 111 | ? | 73 | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/search/query>

sessions.getRecentlyClosed()
============================



Returns an array of [`Session`](session) objects, representing windows and tabs that were closed in the current browsing session (that is: the time since the browser was started).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingSessions = browser.sessions.getRecentlyClosed(
  filter             // optional object
)

```
### Parameters


 
`filter` Optional
  `object`. A [`sessions.Filter`](filter) object that limits the set of sessions returned.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). This will be fulfilled with an array of [`Session`](session) objects, one for each of the most recently closed tabs or windows in the current browsing session, up to [`sessions.MAX_SESSION_RESULTS`](max_session_results) or the number included in the `filter` argument, whichever is smaller. The array is given in the reverse of the order in which tabs or windows were closed, so the most recently closed will be at index 0.

 If an error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getRecentlyClosed` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This code restores the single most recently-closed session, whether it's a tab or a window:

 
```
function restoreMostRecent(sessionInfos) {
  if (!sessionInfos.length) {
    console.log("No sessions found")
    return;
  }
  let sessionInfo = sessionInfos[0];
  if (sessionInfo.tab) {
    browser.sessions.restore(sessionInfo.tab.sessionId);
  } else {
    browser.sessions.restore(sessionInfo.window.sessionId);
  }
}

function onError(error) {
  console.log(error);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingSessions = browser.sessions.getRecentlyClosed({
    maxResults: 1
  });
  gettingSessions.then(restoreMostRecent, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/getRecentlyClosed>

sessions.MAX\_SESSION\_RESULTS
==============================


This value represents the maximum number of sessions that will be returned by a call to [`sessions.getRecentlyClosed()`](getrecentlyclosed). It is read-only for WebExtension code, and is set to 25.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_SESSION_RESULTS` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/MAX_SESSION_RESULTS>

sessions.restore()
==================



Restores a closed tab or window. Restoring doesn't just reopen the tab or window: it also restores the tab's navigation history so the back/forward buttons will work. Restoring a window will restore all the tabs that the window contained when it was closed.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let restoringSession = browser.sessions.restore(
  sessionId             // string
)

```
### Parameters


 `sessionId`  `string`. A string containing the session ID for the window or tab to restore. This can be found in the `sessionId` property of the [`Tab`](../tabs/tab) or [`Window`](../windows/window) object in the [`Session`](session) returned from [`sessions.getRecentlyClosed()`](getrecentlyclosed).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). This will be fulfilled with a [`Session`](session) object representing the session that was restored.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `restore` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This restores the single most recently-closed session, whether it's a window or tab:

 
```
function restoreMostRecent(sessionInfos) {
  if (!sessionInfos.length) {
    console.log("No sessions found")
    return;
  }
  let sessionInfo = sessionInfos[0];
  if (sessionInfo.tab) {
    browser.sessions.restore(sessionInfo.tab.sessionId);
  } else {
    browser.sessions.restore(sessionInfo.window.sessionId);
  }
}

function onError(error) {
  console.log(error);
}

browser.browserAction.onClicked.addListener(() => {
  let gettingSessions = browser.sessions.getRecentlyClosed({
    maxResults: 1
  });
  gettingSessions.then(restoreMostRecent, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 
Known issues
------------


[Bug 1538119](https://bugzil.la/1538119) - Duplicate sessionId in browser.sessions.getRecentlyClosed() after "Restore previous session"



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/restore>

scripting.RegisteredContentScript
=================================


This object contains details of a script to be registered or that is registered.


Type
----



Values of this type are objects. They contain these properties:

  
`allFrames` Optional
  `boolean`. If specified `true`, the script is 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 does not inject into child frames if the URL requirements are not met. Defaults to `false`, meaning that only the top frame is matched.

  
`css` Optional
  `array` of `string`. The list of CSS files to be injected into matching pages. These are injected in the order they appear in this array.

  
`excludeMatches` Optional
  `array` of `string`. Array of pages that this content script is excluded from but would otherwise be injected into.

  `id`  `string`. The ID of the content script, specified in the API call.

  
`js` Optional
  `array` of `string`. Array of path to JavaScript files in the extension package to inject into matching pages. Scripts are injected in the order they appear in this array.

  
`matches` Optional
  `array` of `string`. Array of the pages this content script is injected into. Must be specified for [`scripting.registerContentScripts()`](registercontentscripts).

  
`persistAcrossSessions` Optional
  `boolean`. Specifies if this content script persists across browser restarts and updates and extension restarts. Defaults to `true`.

  
`runAt` Optional
  [`extensionTypes.RunAt`](../extensiontypes/runat). Specifies when JavaScript files are injected into the web page. The default value is `document_idle`. In Firefox, `runAt` also affects the point where the CSS is inserted. In Chrome, `runAt` does not affect the CSS insertion point.

  
`world` Optional
  [`scripting.ExecutionWorld`](executionworld). The execution environment for a script to execute in. The default value is `ISOLATED`.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RegisteredContentScript` | 88 | 88 | 102 | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102 | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `persistAcrossSessions` | 88 | 88 | 102["Since Firefox 105, this option is optional and accepts any boolean value.", "Prior to Firefox 105, this option was required and only accepted the `false` value."] | ? | 74 | 16.4Available for use in Manifest V2 or later. | ? | ? | 102["Since Firefox 105, this option is optional and accepts any boolean value.", "Prior to Firefox 105, this option was required and only accepted the `false` value."] | ? | 16.4Available for use in Manifest V2 or later. | ? |
| `world` | 102 | 102 | No | ? | 88 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.scripting`](https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/RegisteredContentScript>

sessions.Filter
===============


The `Filter` object enables you to restrict the number of [`Session`](session) objects returned by a call to [`sessions.getRecentlyClosed()`](getrecentlyclosed).


Type
----



Values of this type are objects. They contain the following properties:

  
`maxResults` Optional
  `number`. The maximum number of results to return.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Filter` | Yes | 79 | 52 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------


 **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/Filter>

sessions.Session
================



The `Session` object represents a tab or window that the user has closed in the current browsing session.

 Sessions are represented as [`Tab`](../tabs/tab) objects if the tab was closed but its window was not closed: for example, because the user clicked the "Close tab" button, and this tab was not the only tab in its window.

 Sessions are represented as [`Window`](../windows/window) objects if the window was closed: for example, because the user clicked the "Close window" button, or closed the only tab open in a window.

 Note that different browsers might have a different idea of when a session is a Tab and when it is a Window. For example:

 * In Chrome a session is recorded as a Window if the user closes a window that contained more than one tab. If the user closed a window that contained only one tab, this is recorded as a Tab.
* In Firefox, a session is recorded as a Window if the user closes a window (or a tab that was the last tab in the window), and a Tab if the user closes a tab that wasn't the last tab in its window.

 The Tab object for a tab that is open will not have a `sessionId`. When the tab is closed, it will have a `sessionId` but will not have a tab `id`. If the tab is restored, it will get a new tab `id` and will lose the `sessionId`.



Type
----



Values of this type are objects. They contain the following properties:

  `lastModified`  `number`. The time the tab or window was closed, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  
`tab` Optional
  `object`. If the object represents a closed tab, then this property is present and will be a [`tabs.Tab`](../tabs/tab) object. This will contain `url`, `title`, and `favIconUrl` only if the extension has the "tabs" [permission](../../manifest.json/permissions) or [host permissions](../../manifest.json/permissions#host_permissions) to access the tab's URL.

  
`window` Optional
  `object`. If the object represents a closed window, then this property is present and will be a [`windows.Window`](../windows/window) object.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Session` | Yes | 79 | 52'Tab' objects in Sessions don't contain the 'url', 'title', or 'favIconUrl' properties. | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/Session>

sessions.forgetClosedTab()
==========================



Removes a closed tab from the browser's list of recently closed tabs. Note that the sites visited by that tab are not removed from the browser's history. Use the [`browsingData`](../browsingdata) or [`history`](../history) APIs to remove history.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let forgettingTab = browser.sessions.forgetClosedTab(
  windowId,            // integer
  sessionId            // string
)

```
### Parameters


 `windowId`  `Integer`. The ID of the window that hosted the tab you want to forget.

  `sessionId`  `String`. The ID of the session you want to forget.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). This will be fulfilled with no arguments when the session has been removed.

 If an error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `forgetClosedTab` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code forgets the single most recently-closed session, whether it's a tab or a window:

 
```
function forgetMostRecent(sessionInfos) {
  if (!sessionInfos.length) {
    console.log("No sessions found")
    return;
  }
  let sessionInfo = sessionInfos[0];
  if (sessionInfo.tab) {
    browser.sessions.forgetClosedTab(sessionInfo.tab.windowId, sessionInfo.tab.sessionId);
  } else {
    browser.sessions.forgetClosedWindow(sessionInfo.window.sessionId);
  }
}

function onError(error) {
  console.log(error);
}

browser.sessions.getRecentlyClosed({maxResults: 1})
.then(forgetMostRecent, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/forgetClosedTab>

sessions.setWindowValue()
=========================



Stores a key/value pair to associate with a given window. You can subsequently retrieve this value using [`sessions.getWindowValue`](getwindowvalue).

 Note that this data will only be visible to the extension that set it, and not to any other extensions.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let storing = browser.sessions.setWindowValue(
  windowId,    // integer
  key,         // string
  value        // string or object
)

```
### Parameters


 `windowId`  `integer`. ID of the window with which you want to associate the data. Error is thrown if ID is invalid.

  `key`  `string`. Key that you can later use to retrieve this particular data value.

  `value`  `string` or `object`. If this is an object it is [stringified](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify), so object methods, for example, will be omitted. If a function is given here it will be stored as the value `null`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved with no arguments if the call succeeded. If the call failed (for example, because the window ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Set a value on the active window when the user selects a menu item. Note that you'll need the "menus" [permission](../../manifest.json/permissions) to run this example:

 
```
async function setOnActiveWindow() {
  let currentWindow = await browser.windows.getLastFocused();
  await browser.sessions.setWindowValue(currentWindow.id, "my-key", "my-value");
}

browser.menus.create({
  id: "my-item",
  title: "my item",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(setOnActiveWindow);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/setWindowValue>

sessions.getWindowValue()
=========================



Retrieves a value previously stored by a call to [`sessions.setWindowValue`](setwindowvalue).

 You can retrieve a value from a window even over a close/restore cycle: meaning that if you set a value, then the user closes the window, then restores the window using the browser's "restore window" feature (for example, by pressing Control+Shift+N), then you will be able to retrieve the value from the restored window. Note, though, that a restored window does not get the same ID as the original, so the ID you pass into `getWindowValue()` will be different from the ID you passed into `setWindowValue()`, even though they both refer to the same window.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let retrieving = browser.sessions.getWindowValue(
  windowId,    // integer
  key          // string
)

```
### Parameters


 `windowId`  `integer`. ID of the window whose data you are trying to retrieve. Error is thrown if ID is invalid.

  `key`  `string`. Key identifying the particular value to retrieve. This needs to match the key previously given in [`sessions.setWindowValue`](setwindowvalue).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved with the value if it exists, or `undefined` if it does not exist. If the call failed (for example, because the window ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the value of "my-key" for all newly created windows (this will include any windows that have been restored):

 
```
function onGetResolved(r) {
  console.log(`success: ${r}`);
}

function onGetRejected(e) {
  console.log(`error: ${e}`);
}

browser.windows.onCreated.addListener((window) => {
  browser.sessions.getWindowValue(window.id, "my-key").then(onGetResolved, onGetRejected);
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/getWindowValue>

sessions.removeWindowValue()
============================



Removes a value previously stored by a call to [`sessions.setWindowValue`](setwindowvalue).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.sessions.removeWindowValue(
  windowId,    // integer
  key          // string
)

```
### Parameters


 `windowId`  `integer`. ID of the window whose data you are trying to remove. Error is thrown if ID is invalid.

  `key`  `string`. Key identifying the particular value to remove. This needs to match the key previously given in [`sessions.setWindowValue`](setwindowvalue).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved no arguments if the item was successfully removed. If the call failed (for example, because the window ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeWindowValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code adds two context menu items: one stores a value associated with the current window, the other one removes it:

 
```
async function setOnActiveWindow() {
  let currentWindow = await browser.windows.getLastFocused();
  await browser.sessions.setWindowValue(currentWindow.id, "my-key", "my-value");
}

async function removeFromActiveWindow() {
  let currentWindow = await browser.windows.getLastFocused();
  await browser.sessions.removeWindowValue(currentWindow.id, "my-key");
}

browser.menus.create({
  id: "add-my-item",
  title: "add item",
  contexts: ["all"]
});

browser.menus.create({
  id: "remove-my-item",
  title: "remove item",
  contexts: ["all"]
});

browser.menus.onClicked.addListener((info) => {
  if (info.menuItemId === "add-my-item") {
    setOnActiveWindow();
  } else {
    removeFromActiveWindow();
  }
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/removeWindowValue>

sessions.onChanged
==================


Fired whenever the list of closed tabs or windows changes.


Syntax
------




```
browser.sessions.onChanged.addListener(listener)
browser.sessions.onChanged.removeListener(listener)
browser.sessions.onChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. It's passed no parameters.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | Yes | 79 | 53 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This very annoying extension listens for `onChanged`, then immediately restores the most recently closed session, thus making it impossible to close windows or tabs:

 
```
function restoreSession(sessionInfos) {
  if (!sessionInfos.length) {
    console.log("No sessions found")
    return;
  }
  let sessionInfo = sessionInfos[0];
  if (sessionInfo.tab) {
    browser.sessions.restore(sessionInfo.tab.sessionId);
  } else {
    browser.sessions.restore(sessionInfo.window.sessionId);
  }
}

function onError(error) {
  console.log(error);
}

function restoreMostRecent() {
  let gettingSessions = browser.sessions.getRecentlyClosed({
    maxResults: 1
  });
  gettingSessions.then(restoreSession, onError);
}

browser.sessions.onChanged.addListener(restoreMostRecent);

```
  **Note:** This API is based on Chromium's [`chrome.sessions`](https://developer.chrome.com/docs/extensions/reference/sessions/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/onChanged>

sidebarAction.ImageDataType
===========================


Pixel data for an image. Must be an [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object (for example, from a [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element).


Type
----


An [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ImageDataType` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/ImageDataType>

sessions.forgetClosedWindow()
=============================



Removes a closed window from the browser's list of recently closed windows. Note that the sites visited by that window are not removed from the browser's history. Use the [`browsingData`](../browsingdata) or [`history`](../history) APIs to remove history.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let forgettingWindow = browser.sessions.forgetClosedWindow(
  sessionId            // string
)

```
### Parameters


 `sessionId`  `String`. The ID of the session you want to forget.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). This will be fulfilled with no arguments when the session has been removed.

 If an error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `forgetClosedWindow` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code forgets the single most recently-closed session, whether it's a tab or a window:

 
```
function forgetMostRecent(sessionInfos) {
  if (!sessionInfos.length) {
    console.log("No sessions found")
    return;
  }
  let sessionInfo = sessionInfos[0];
  if (sessionInfo.tab) {
    browser.sessions.forgetClosedTab(sessionInfo.tab.windowId, sessionInfo.tab.sessionId);
  } else {
    browser.sessions.forgetClosedWindow(sessionInfo.window.sessionId);
  }
}

function onError(error) {
  console.log(error);
}

browser.sessions.getRecentlyClosed({maxResults: 1})
.then(forgetMostRecent, onError);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/forgetClosedWindow>

sessions.removeTabValue()
=========================



Removes a value previously stored by a call to [`sessions.setTabValue`](settabvalue).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let removing = browser.sessions.removeTabValue(
  tabId,    // integer
  key       // string
)

```
### Parameters


 `tabId`  `integer`. ID of the tab whose data you are trying to remove. Error is thrown if ID is invalid.

  `key`  `string`. Key identifying the particular value to remove. This needs to match the key previously given in [`sessions.setTabValue`](settabvalue).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be resolved no arguments if the item was successfully removed. If the call failed (for example, because the tab ID could not be found) then the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `removeTabValue` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code adds two context menu items: one stores a value associated with the current tab, the other one removes it:

 
```
async function setOnActiveTab() {
  let tabArray = await browser.tabs.query({currentWindow: true, active: true});
  let tabId = tabArray[0].id;
  await browser.sessions.setTabValue(tabId, "my-key", "my-value");
}

async function removeFromActiveTab() {
  let tabArray = await browser.tabs.query({currentWindow: true, active: true});
  let tabId = tabArray[0].id;
  await browser.sessions.removeTabValue(tabId, "my-key");
}

browser.menus.create({
  id: "add-my-item",
  title: "add item",
  contexts: ["all"]
});

browser.menus.create({
  id: "remove-my-item",
  title: "remove item",
  contexts: ["all"]
});

browser.menus.onClicked.addListener((info) => {
  if (info.menuItemId === "add-my-item") {
    setOnActiveTab();
  } else {
    removeFromActiveTab();
  }
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions/removeTabValue>

sidebarAction.close()
=====================



Closes the sidebar in the active window, if it is the extension's own sidebar.

 You can only call this function from inside the handler for a [user action](../../user_actions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.sidebarAction.close()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `close` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Close the sidebar when the user selects a context menu item:

 
```
browser.menus.create({
  id: "close-sidebar",
  title: "close sidebar",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(() => {
  browser.sidebarAction.close();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/close>

sidebarAction.open()
====================



Open the sidebar in the active window.

 You can only call this function from inside the handler for a [user action](../../user_actions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.sidebarAction.open()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `open` | No | No | 57 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Open the sidebar when the user selects a context menu item:

 
```
browser.menus.create({
  id: "open-sidebar",
  title: "open sidebar",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(() => {
  browser.sidebarAction.open();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/open>

sidebarAction.setIcon()
=======================



Sets the icon for the sidebar.

 You can specify a single icon as either the path to an image file or a [`sidebarAction.ImageDataType`](imagedatatype) object.

 You can specify multiple icons in different sizes by supplying a dictionary containing multiple paths or `ImageData` objects. This means the icon doesn't have to be scaled for a device with a different pixel density.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Types of icon
-------------



Your extension should specify an icon for the sidebar in the [`sidebar_action`](../../manifest.json/sidebar_action) manifest key. This is called the *"manifest icon"*.

 If you don't specify an icon in the `sidebar_action` key, you get the browser's default icon. This is called the *"default icon"*.

 If you set a new icon using `setIcon()`, and include the `tabId` option, then the icon is set only for the given tab. This icon is called the *"tab-specific icon"*.

 If you set a new icon using `setIcon()`, and include the `windowId` option, then the icon is set only for the given window. This icon is called the *"window-specific icon"*, and will appear in all tabs of that window that do not have a tab-specific icon set.

 If you set a new icon using `setIcon()`, and omit both the `tabId` and `windowId` options, then this sets the *"global icon"*. The global icon will then appear in all tabs that do not have a tab-specific icon set and whose window does not have a window-specific icon.


Syntax
------



```
let settingIcon = browser.sidebarAction.setIcon(
  details         // object
)

```
### Parameters



 `details`  `object`. An object with the following properties:

  
`imageData` Optional
  `[`sidebarAction.ImageDataType`](imagedatatype)` or `object`. This is either a single `ImageData` object or a dictionary object.

 Use a dictionary object to specify multiple `ImageData` objects in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `imageData` is a dictionary, the value of each property is an `ImageData` object, and its name is its size, like this:

 
```
{
    16: image16,
    32: image32
  }

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

  
`path` Optional
  `string` or `object`. This is either a relative path to an icon file or it is a dictionary object.

 Use a dictionary object to specify multiple icon files in different sizes, so the icon does not have to be scaled for a device with a different pixel density. If `path` is a dictionary, the value of each property is a relative path, and its name is its size, like this:

 
```
{
    16: "path/to/image16.jpg",
    32: "path/to/image32.jpg"
  }

```
 The browser will choose the image to use depending on the screen's pixel density. See [Choosing icon sizes](../../manifest.json/browser_action#choosing_icon_sizes) for more information on this.

 If `path` is an empty string, the browser will use the default icon.

 If `path` is not empty but does not point to an icon file, then the icon is hidden.

 If `path` is `null`, and `tabId` was specified, and the specified tab had a tab-specific icon set: then the tab-specific icon is reset to the global icon (if a global icon is set) or the manifest icon.

 if `path` is `null`, and `tabId` was omitted, and there was a global icon set, it will be reset to the manifest icon.

  
`tabId` Optional
  `integer`. Sets the icon only for the given tab.

  
`windowId` Optional
  `integer`. Sets the icon only for the given window.

     * If `windowId` and `tabId` are both specified, the function fails and the icon is not set.
* If `windowId` and `tabId` are both omitted, the icon is set globally.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments once the icon has been set.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setIcon` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `null` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



The code below toggles the sidebar icon for the active tab when the user clicks a browser action:

 
```
let on = false;

function toggle(tab) {
  if (on) {
    browser.sidebarAction.setIcon({
      path: "off.svg",
      tabId: tab.id
    });
    on = false;
  } else {
    browser.sidebarAction.setIcon({
      path: "on.svg",
      tabId: tab.id
    });
    on = true;
  }
}

browser.browserAction.onClicked.addListener(toggle);

```
  **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/setIcon>

sidebarAction.setTitle()
========================


Sets the sidebar's title. The title is displayed anywhere the browser lists available sidebars. For example, Firefox will show it in the "View > Sidebar" menu. It's also shown at the top o the sidebar when the sidebar is open.


Types of title
--------------



Your extension should specify an title for the sidebar in the [sidebar\_action](../../manifest.json/sidebar_action) manifest key. This is called the *"manifest title"*. If you don't specify the manifest title, it will default to the extension name.

 If you set a new title using `setTitle()`, and include the `tabId` option, then the title is set only for the given tab. This title is called the *"tab-specific title"*.

 If you set a new title using `setTitle()`, and include the `windowId` option, then the title is set only for the given window. This title is called the *"window-specific title"*, and will appear in all tabs of that window that do not have a tab-specific title set.

 If you set a new title using `setTitle()`, and omit both the `tabId` and `windowId` options, then this sets the *"global title"*. The global title will then appear in all tabs that do not have a tab-specific title set and whose window does not have a window-specific title.


Syntax
------



```
browser.sidebarAction.setTitle(
  details // object
)

```
### Parameters



 `details`  `object`. An object with the following properties:

  `title`  `string` or `null`. The sidebar's new title.

 If `title` is an empty string, the used title will be the extension name, but [`sidebarAction.getTitle`](gettitle) will still provide the empty string.

 If `title` is `null`, then a previously set title will be removed, so that:

 * If `tabId` is specified, and the tab has a tab-specific title set, then the tab will inherit the title from the window it belongs to.
* If `windowId` is specified, and the window has a window-specific title set, then the window will inherit the global title.
* Otherwise, the global title will be reset to the manifest title.

  
`tabId` Optional
  `integer`. Sets the title only for the given tab.

  
`windowId` Optional
  `integer`. Sets the title only for the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the title is not set.
* If `windowId` and `tabId` are both omitted, the global title is set.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setTitle` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |
| `null` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



This code changes the title for the sidebar when the user clicks a browser action, but only for the current tab:

 
```
let title = "A different title";

function setTitleForTab(tab) {
  browser.sidebarAction.setTitle({title, tabId: tab.id});
}

browser.browserAction.onClicked.addListener(setTitleForTab);

```
  **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/setTitle>

sidebarAction.toggle()
======================



Toggles the visibility of the sidebar in the active window, if the sidebar belongs to the extension.

 You can only call this function from inside the handler for a [user action](../../user_actions).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.sidebarAction.toggle()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved with no arguments.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `toggle` | No | No | 73 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Toggles the sidebar when the user selects an item from the context menu:

 
```
browser.menus.create({
  id: "toggle-sidebar",
  title: "Toggle sidebar",
  contexts: ["all"]
});

browser.menus.onClicked.addListener(() => {
  browser.sidebarAction.toggle();
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/toggle>

proxy.settings
==============



A [`BrowserSetting`](../types/browsersetting) object that can be used to change the browser's proxy settings.

  **Note:** Changing proxy settings requires private browsing window access because proxy settings affect private and non-private windows. Whether an extension can access private browsing windows is under user control. For details, see [Extensions in Private Browsing](https://support.mozilla.org/en-US/kb/extensions-private-browsing). Your extension can check whether it can access private browsing windows using [`extension.isAllowedIncognitoAccess`](../extension/isallowedincognitoaccess). If your extension does not have private window permission, calls to `proxy.settings.set()` throw an exception.

  The underlying value is an object with the properties listed below.

 When setting this object, all properties are optional. Note that any properties that are omitted will be reset to their default value.

  
`autoConfigUrl` Optional
  `string`. A URL to use to configure the proxy.

  
`autoLogin` Optional
  `boolean`. Do not prompt for authentication if the password is saved. Defaults to `false`.

  
`ftp` Optional  Deprecated 
  `string`. The address of the FTP proxy. Can include a port.

  
`http` Optional
  `string`. The address of the HTTP proxy. Can include a port.

  
`httpProxyAll` Optional
  `boolean`. Use the HTTP proxy server for all protocols. Defaults to `false`.

  
`passthrough` Optional
  `string`. A comma-separated list of hosts which should not be proxied. Defaults to "localhost, 127.0.0.1".

  
`proxyDNS` Optional
  `boolean`. Proxy DNS when using SOCKS5. Defaults to `false`.

  
`proxyType` Optional
  `string`. The type of proxy to use. This may take any one of the following values: "none", "autoDetect", "system", "manual", "autoConfig". Defaults to "system".

  
`socks` Optional
  `string`. The address of the SOCKS proxy. Can include a port.

  
`socksVersion` Optional
  `integer`. The version of the SOCKS proxy. May be 4 or 5. Defaults to 5.

  
`ssl` Optional
  `string`. The address of the SSL proxy. Can include a port.

  

Examples
--------



```
let proxySettings = {
  proxyType: "manual",
  http: "http://proxy.org:8080",
  socksVersion: 4,
  passthrough: ".example.org"
};

browser.proxy.settings.set({value: proxySettings});

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `settings` | No | No | 60From version 88, the `ftp` setting has no effect because FTP is no longer supported (see [bug 1626365](https://bugzil.la/1626365)). | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/settings>

sidebarAction.getPanel()
========================



Gets a URL to the HTML document that defines the sidebar's contents.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingPanel = browser.sidebarAction.getPanel(
  details               // object
)

```
### Parameters



 `details`  `object`. An object with the following properties:

  
`tabId` Optional
  `integer`. Get the panel for the sidebar specific to the given tab.

  
`windowId` Optional
  `integer`. Get the panel for the sidebar specific to the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the promise it returns is rejected.
* If `windowId` and `tabId` are both omitted, the global panel is returned.


### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the URL for the panel's document. This will be a fully qualified URL, such as:

 
```
moz-extension://d1d8a2eb-fe60-f646-af30-a866c5b39942/sidebar.html

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getPanel` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |


Examples
--------



Get the panel's URL:

 
```
function onGot(sidebarUrl) {
  console.log(sidebarUrl);
}

let gettingPanel = browser.sidebarAction.getPanel({});
gettingPanel.then(onGot);

```
  **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/getPanel>

sidebarAction.getTitle()
========================



Gets the sidebar's title.

 Just as you can set the title on a per-tab basis using [`sidebarAction.setTitle()`](settitle), so you can retrieve a tab-specific title by passing the tab's ID into this function.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingTitle = browser.sidebarAction.getTitle(
  details               // object
)

```
### Parameters



 `details`  `object`. An object with the following properties:

  
`tabId` Optional
  `integer`. Get the title for the sidebar specific to the given tab.

  
`windowId` Optional
  `integer`. Get the title for the sidebar specific to the given window.

     * If `windowId` and `tabId` are both supplied, the function fails and the promise it returns is rejected.
* If `windowId` and `tabId` are both omitted, the global title is returned.


### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a string containing the sidebar's title.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getTitle` | No | No | 54 | ? | 30 | No | ? | ? | No | ? | No | ? |


Examples
--------



This code switches the title between "this" and "that" each time the user clicks the browser action

 
```
function toggleTitle(title) {
  if (title === "this") {
    browser.sidebarAction.setTitle({title: "that"});
  } else {
    browser.sidebarAction.setTitle({title: "this"});
  }
}

browser.browserAction.onClicked.addListener(() => {
  let gettingTitle = browser.sidebarAction.getTitle({});
  gettingTitle.then(toggleTitle);
});

```
  **Note:** This API is based on Opera's [`chrome.sidebarAction`](https://dev.opera.com/extensions/sidebar-action-api/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/getTitle>

sidebarAction.isOpen()
======================



Returns `true` if the extension's sidebar is open in a given window.

 This function accepts a `windowId` as a parameter:

 * If you supply `windowId`, the function will check the given browser window.
* If you omit `windowId`, the function will check the topmost browser window.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingIsOpen = browser.sidebarAction.isOpen(
  details // object
)

```
### Parameters


 `details`  `object`. An object optionally containing the `windowId` to check.

  
`windowId` Optional
  `integer`. ID of a browser window to check. If omitted defaults to [`windows.WINDOW_ID_CURRENT`](../windows/window_id_current), which refers to the topmost browser window.

    ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with `true` if the extension's sidebar is open in the given window, or `false` otherwise.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `isOpen` | No | No | 59 | ? | No | No | ? | ? | No | ? | No | ? |


Examples
--------



Check the topmost window:

 
```
browser.sidebarAction.isOpen({}).then((result) => {
  console.log(result);
});

```
 Check all open windows:

 
```
async function checkWindow(windowId) {
  const result = await browser.sidebarAction.isOpen({ windowId });
  console.log(`window: ${windowId} status: ${result}`);
}

browser.windows.getAll().then((all) => {
  for (const { id } of all) {
    checkWindow(id);
  }
});

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction/isOpen>

webRequest.ResourceType
=======================



This type is a string, which represents the context in which a resource was fetched in a web request.

 It's used to [filter](requestfilter) the requests you listen to using the webRequest API. For example: you can listen to requests only for images, or only for scripts.



Type
----



Values of this type are strings. Possible values are:

  `beacon`  Requests sent through the [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API).

  `csp_report`  Requests sent to the [`report-uri`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri) given in the [`Content-Security-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) header, when an attempt to violate the policy is detected.

  `font`  Web fonts loaded for a [`@font-face`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face) CSS rule.

  `image`  Resources loaded to be rendered as image, except for `imageset` on browsers that support that type (see browser compatibility below).

  `imageset`  Images loaded by a [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) element or given in an `<img>` element's [`srcset`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#srcset) attribute.

  `main_frame`  Top-level documents loaded into a tab.

  `media`  Resources loaded by a [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) or [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) element.

  `object`  Resources loaded by an [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) or [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed) element.

 Browsers that don't have a dedicated `object_subrequest` type (see browser compatibility below), also label subsequent requests sent by the plugin as `object`.

  `object_subrequest`  Requests sent by plugins.

  `ping`  Requests sent to the URL given in a hyperlink's [`ping`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#ping) attribute, when the hyperlink is followed.

 Browsers that don't have a dedicated `beacon` type (see browser compatibility below), also label requests sent through the Beacon API as `ping`.

  `script`  Code that is loaded to be executed by a [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) element or running in a [Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).

  `speculative`  In a speculative connection, the browser has determined that a request to a URI may be coming soon, so it starts a TCP and/or TLS handshake immediately, so it is ready more quickly when the resource is actually requested. Note that this type of connection does not provide valid tab information, so request details such as `tabId`, `frameId`, `parentFrameId`, etc. are inaccurate.

  `stylesheet`  [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) stylesheets loaded to describe the representation of a document.

  `sub_frame`  Documents loaded into an [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) or [`<frame>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame) element.

  `web_manifest`  [Web App Manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) loaded for websites that can be installed to the homescreen.

  `websocket`  Requests initiating a connection to a server through the [WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API).

  `xml_dtd`  [DTDs](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) loaded for an XML document.

  `xmlhttprequest`  Requests sent by an [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object or through the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

  `xslt`  [XSLT](https://developer.mozilla.org/en-US/docs/Web/XSLT) stylesheets loaded for transforming an XML document.

  `other`  Resources that aren't covered by any other available type.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ResourceType` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `beacon` | No | No | 45 | ? | No | No | ? | ? | 48 | ? | No | ? |
| `csp_report` | 58 | 79 | 45 | ? | 45 | No | ? | ? | 48 | ? | No | ? |
| `font` | 49 | 79 | 45 | ? | 36 | No | ? | ? | 48 | ? | No | ? |
| `image` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `imageset` | No | No | 45 | ? | No | No | ? | ? | 48 | ? | No | ? |
| `main_frame` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `media` | 58 | 79 | 45 | ? | 45 | No | ? | ? | 48 | ? | No | ? |
| `object` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `object_subrequest` | No | No | 55Requests have been reported as `object_subrequest` before, but the type was missing in the `ResourceType` object before Firefox 55. | ? | No | No | ? | ? | 55Requests have been reported as `object_subrequest` before, but the type was missing in the `ResourceType` object before Firefox 55. | ? | No | ? |
| `other` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `ping` | 49Requests sent by `navigator.sendBeacon()`, and CSP reports in Chrome 49-57 (Opera 36-44), are also labeled as `ping`. | 79 | 45 | ? | 36Requests sent by `navigator.sendBeacon()`, and CSP reports in Chrome 49-57 (Opera 36-44), are also labeled as `ping`. | No | ? | ? | 48 | ? | No | ? |
| `script` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `speculative` | No | No | 63 | ? | No | No | ? | ? | 63 | ? | No | ? |
| `stylesheet` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `sub_frame` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `web_manifest` | No | No | 45 | ? | No | No | ? | ? | 48 | ? | No | ? |
| `websocket` | 58 | 79 | 45 | ? | 45 | No | ? | ? | 48 | ? | No | ? |
| `xml_dtd` | No | No | 45 | ? | No | No | ? | ? | 48 | ? | No | ? |
| `xmlhttprequest` | 44 | 79 | 45 | ? | 31 | No | ? | ? | 48 | ? | No | ? |
| `xslt` | No | No | 45 | ? | No | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#type-ResourceType) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType>

proxy.ProxyInfo
===============


Contains information about a proxy. This object, or an array of these objects, is returned from the listener to [`proxy.onRequest`](onrequest). It instructs the browser whether to proxy the request, and if so, which proxy to use.


Type
----



Values of this type are objects. They contain the following properties:

  `type`  `string`. This describes whether to proxy at all, and if so, what kind of proxy to use. It may take one of the following values:

 * `"direct"`: don't proxy the request. If this value is given, all other properties of this object are ignored. However, this setting doesn't override any [proxy set by the user](https://support.mozilla.org/en-US/kb/connection-settings-firefox). Use [`proxy.settings`](settings) to check whether a manual proxy is being used and, if necessary, monitor those settings for changes using [`BrowserSetting.onChange`](../types/browsersetting/onchange).
* `"http"`: HTTP proxy (or SSL CONNECT for HTTPS)
* `"https"`: HTTP proxying over TLS connection to proxy
* `"socks"`: SOCKS v5 proxy
* `"socks4"`: SOCKS v4 proxy

  `host`  `string`. The hostname of the proxy server. Mandatory unless `type` is `"direct"`.

  `port`  `number`. The port number of the proxy server. Mandatory unless `type` is `"direct"`.

  `username`  `string`. Username for the proxy service. This is usable with "socks". For HTTP proxy authorizations, use [`webRequest.onAuthRequired`](../webrequest/onauthrequired).

  `password`  `string`. Password for the proxy service. This is usable with "socks". For HTTP proxy authorizations, use [`webRequest.onAuthRequired`](../webrequest/onauthrequired).

  `proxyDNS`  `boolean`. If true, the proxy server is used to resolve certain DNS queries (only usable with `"socks4"` and `"socks"`). Defaults to `false`.

  `failoverTimeout`  `number`. Failover timeout in seconds. If the connection fails to connect the proxy server after this number of seconds, the next proxy server in the array returned from the `proxy.onRequest` listener will be used.

  `proxyAuthorizationHeader`  `string`. This string, if set to non-empty, is passed directly as a value to the [`Proxy-Authorization`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authorization) request header sent to HTTPS proxies as part of HTTPS and CONNECT requests. In other words, this can be used to directly authenticate to HTTPS proxies that allow (non-challenging) authentication.

 For instance, if you want to send "username" and "password" for "basic" authentication, you can set the `proxyAuthorizationHeader` property to `Basic dXNlcm5hbWU6cGFzc3dvcmQ=`

  
`connectionIsolationKey` Optional
  `string`. An optional key used for additional isolation of this proxy connection. Applies to HTTPS proxies only.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ProxyInfo` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/ProxyInfo>

proxy.RequestDetails
====================


Contains information about a web request. An instance of this object is passed into the [`proxy.onRequest`](onrequest) listener.


Type
----



Values of this type are objects. They contain the following properties:

  `cookieStoreId`  `string`. The cookie store ID of the current context.

  `documentUrl`  `string`. URL of the page into which the requested resource will be loaded.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Indicates if this response will be fetched from disk cache.

  `incognito`  `boolean`. `true` for private browsing requests.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource that triggered the request. Note that this may not be the same as the URL of the page into which the requested resource will be loaded. For example, if a document triggers a load in a different window through the [target attribute of a link](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target), or a CSS document includes an image using the [`url()` functional notation](https://developer.mozilla.org/en-US/docs/Web/CSS/url), then this is the URL of the original document or of the CSS document, respectively.

  `parentFrameId`  `integer`. ID of the frame that contains the frame that sent the request. Set to -1 if no parent frame exists.

  `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use an ID to identify different events associated with the same request.

  
`requestHeaders` Optional
  [`webRequest.HttpHeaders`](../webrequest/httpheaders). The HTTP request headers that will be sent with this request. Note that this is only included if the `"requestHeaders"` option was passed into `addListener()`.

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to -1 if the request is not related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy is third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](../webrequest/resourcetype). The type of resource being requested: for example, "image", "script", or "stylesheet".

  `url`  `string`. Target of the request.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RequestDetails` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `cookieStoreId` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `documentUrl` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `frameId` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `fromCache` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `incognito` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `method` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `originUrl` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `parentFrameId` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `requestHeaders` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `requestId` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `tabId` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `thirdParty` | No | No | 72 | ? | No | No | ? | ? | No | ? | No | ? |
| `timeStamp` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `type` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |
| `url` | No | No | 60 | ? | No | No | ? | ? | 60 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/RequestDetails>

webRequest.onHeadersReceived
============================



Fired when the HTTP response headers for a request are received. Use this event to modify HTTP response headers.

 To have the response headers passed into the listener, along with the rest of the request data, pass `"responseHeaders"` in the `extraInfoSpec` array.

 If you use `"blocking"`, you must have the ["webRequestBlocking" API permission](../../manifest.json/permissions#api_permissions) in your manifest.json.

 It is possible for extensions to make conflicting requests. If two extensions listen to `onHeadersReceived` for the same request and return `responseHeaders` to set the same header (for example, `Set-Cookie`) not present in the original response, only one of the changes will succeed.

 However, the `Content-Security-Policy` header is treated differently; its values are combined to apply all the specified policies. But, if two extensions set a CSP value that conflicts, the CSP service makes the restriction more strict to resolve the conflict. For example, if one extension sets `img-src: example.com`, and another extension sets `img-src: example.org`, the result is `img-src: 'none'`. Merged modifications always lean towards being more restrictive, though an extension may remove the original CSP header.

 If you want to see the headers that are processed by the system, without the risk that another extension will alter them, use [`webRequest.onResponseStarted`](onresponsestarted), although you can't modify headers on this event.



Syntax
------




```
browser.webRequest.onHeadersReceived.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onHeadersReceived.removeListener(listener)
browser.webRequest.onHeadersReceived.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  The function called when this event occurs. The function is passed the following arguments:

  `details`  [`object`](#details_2). Details of the request. This will include response headers if you have included `"responseHeaders"` in `extraInfoSpec`.

   Returns: [`webRequest.BlockingResponse`](blockingresponse). If `"blocking"` is specified in the `extraInfoSpec` parameter, the event listener will return a `BlockingResponse` object, and can set its `responseHeaders` property. In Firefox, the return value can be a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `BlockingResponse`.

  `filter`  [`webRequest.RequestFilter`](requestfilter). A set of filters that restricts the events that are sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass any of the following values:

 * `"blocking"` to make the request synchronous, so you can modify request and response headers
* `"responseHeaders"` to include the response headers in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameAncestors`  `array`. Information for each document in the frame hierarchy up to the top-level document. The first element in the array contains information about the immediate parent of the document being requested, and the last element contains information about the top-level document. If the load is for the top-level document, then this array is empty.

  `url`  `string`. The URL that the document was loaded from.

  `frameId`  `integer`. The `frameId` of the document. `details.frameAncestors[0].frameId` is the same as `details.parentFrameId`.

    `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Whether the response is fetched from disk cache.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `ip`  `string`. The IP address of the server the request was sent to. It may be a literal IPv6 address.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource that triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request is the iframe's parent document, but the `originUrl` is the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame that sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  
`responseHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP response headers that were received for this request.

  `statusCode`  `integer`. Standard HTTP status code returned by the server.

  `statusLine`  `string`. HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (that is, responses that lack a status line).

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHeadersReceived` | YesAsynchronous event listeners are not supported. | 14Asynchronous event listeners are not supported. | 45["Modification of the 'Content-Type' header is supported from version 51.", "Asynchronous event listeners are supported from version 52."] | ? | YesAsynchronous event listeners are not supported. | 14`extraInfoSpec` options are not supported. | ? | ? | 48["Modification of the 'Content-Type' header is supported from version 51.", "Asynchronous event listeners are supported from version 52."] | ? | No | ? |


Examples
--------



This code sets an extra cookie when requesting a resource from the target URL:

 
```
let targetPage = "https://developer.mozilla.org/en-US/Firefox/Developer\_Edition";

// Add the new header to the original array,
// and return it.
function setCookie(e) {
  const setMyCookie = {
    name: "Set-Cookie",
    value: "my-cookie1=my-cookie-value1"
  };
  e.responseHeaders.push(setMyCookie);
  return { responseHeaders: e.responseHeaders };
}

// Listen for onHeaderReceived for the target page.
// Set "blocking" and "responseHeaders".
browser.webRequest.onHeadersReceived.addListener(
  setCookie,
  { urls: [targetPage] },
  ["blocking", "responseHeaders"]
);

```
 This code does the same thing the previous example, except that the listener is asynchronous, returning a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which is resolved with the new headers:

 
```
const targetPage = "https://developer.mozilla.org/en-US/Firefox/Developer\_Edition";

// Return a Promise that sets a timer.
// When the timer fires, resolve the promise with
// modified set of response headers.
function setCookieAsync(e) {
  const asyncSetCookie = new Promise((resolve, reject) => {
    setTimeout(() => {
      const setMyCookie = {
        name: "Set-Cookie",
        value: "my-cookie1=my-cookie-value1"
      };
      e.responseHeaders.push(setMyCookie);
      resolve({ responseHeaders: e.responseHeaders });
    }, 2000);
  });

  return asyncSetCookie;
}

// Listen for onHeaderReceived for the target page.
// Set "blocking" and "responseHeaders".
browser.webRequest.onHeadersReceived.addListener(
  setCookieAsync,
  { urls: [targetPage] },
  ["blocking", "responseHeaders"]
);

```
  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onHeadersReceived) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onHeadersReceived>

proxy.register()
================



**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

  **Warning:** This method was deprecated in Firefox 68 and removed in Firefox 71. In Firefox 68–70, calling this method logs an error message to the console:

  ![Proxy register error message] 

  Registers a [Proxy Auto-Configuration (PAC) file](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file). The file is executed immediately, and its `FindProxyForURL()` function will be called for any HTTP or HTTPS requests.

 If PAC files are registered by more than one extension, then requests will be passed initially to the one that was registered first.

 * If the `FindProxyForURL()` function in the first PAC returns "DIRECT" for a request, then the request will be passed unchanged to the `FindProxyForURL()` function in the next PAC.
* If the `FindProxyForURL()` function in the first PAC proxies the request by returning "PROXY" or some other proxying value, then the proxy URL will be passed to the `FindProxyForURL()` function in the next PAC.

 Each extension can only register a single PAC file: if you call `register()` twice, the second PAC file will replace the first.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Communicating with PAC files
----------------------------



You can exchange messages between the PAC file and your extension's background page (or any other privileged pages, like popup pages) using [`runtime.sendMessage()`](../runtime/sendmessage) and [`runtime.onMessage`](../runtime/onmessage).

 To send a message to the PAC file, you must set the `toProxyScript` option:

 
```
// background.js

// Log any messages from the proxy.
browser.runtime.onMessage.addListener((message, sender) => {
  if (sender.url === browser.extension.getURL(proxyScriptURL)) {
    console.log(message);
  }
});

let messageToProxy = {
  enabled: true,
  foo: "A string",
  bar: 1234
};

browser.runtime.sendMessage(messageToProxy, {toProxyScript: true});

```
 
```
// pac.js

browser.runtime.onMessage.addListener((message) => {
  if (message.enabled) {
    browser.runtime.sendMessage("I'm enabled!");
  }
});

```

PAC file specification
----------------------


The basic PAC file syntax is described in the [PAC documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file), but the implementation used by the proxy API differs from standard PAC design in several ways, which are described in this section.

### FindProxyForURL() return value



The standard `FindProxyForURL()` [returns a string](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file#return_value_format). In Firefox 55 and 56, the PAC file used with the proxy API also returns a string. In Firefox 55 *only*, you must pass an argument to the "DIRECT" return value, even though it doesn't need an argument.

 From Firefox 57 onwards, `FindProxyForURL()` may still return a string, but may alternatively (and preferably) return an array of [`proxy.ProxyInfo`](proxyinfo) objects.

 If the array contains more than one object, then all `ProxyInfo` objects after the first one represent failovers: if the proxy at position N in the array is not reachable when its `ProxyInfo.failoverTimeout` expires, then the browser will try the proxy at position N+1.

 For example:

 
```
const proxySpecification = [
  {
    type: "socks",
    host: "foo.com",
    port: 1080,
    proxyDNS: true,
    failoverTimeout: 5
  },
  {
    type: "socks",
    host: "bar.com",
    port: 1060,
  }
];

```
 The first proxy in the array will be tried first. If it does not respond in `failoverTimeout` seconds, the next will be tried, until the end of the array is reached.


### PAC file environment



The global helper functions usually available for PAC files ([`isPlainHostName()`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file#isplainhostname), [`dnsDomainIs()`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file#dnsdomainis), and so on) are not available.

 Code running in the PAC file does not get access to:

 * any DOM functions (for example, [window](https://developer.mozilla.org/en-US/docs/Web/API/Window) or any of its properties)
* any WebExtension APIs except [`runtime.sendMessage()`](../runtime/sendmessage) and [`runtime.onMessage`](../runtime/onmessage)
* the [Console API](https://developer.mozilla.org/en-US/docs/Web/API/console) - to log messages from a PAC, send a message to the background script:

 
```
// pac.js

// send the log message to the background script
browser.runtime.sendMessage(`Proxy-blocker: blocked ${url}`);

```
 
```
// background-script.js

function handleMessage(message, sender) {
  // only handle messages from the proxy script
  if (sender.url !== browser.extension.getURL(proxyScriptURL)) {
    return;
  }
  console.log(message);
}

browser.runtime.onMessage.addListener(handleMessage);

```

Syntax
------



```
let registering = browser.proxy.register(
  url   // string
)

```
### Parameters


 `url`  `String`. URL pointing to the PAC file to load. PAC files must be bundled with the extension, and `url` must be relative to the extension's [manifest.json](../../manifest.json) file.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the PAC file has been registered, or rejected if there was an error.

Examples
--------



```
const proxyScriptURL = "proxy/proxy-script.js";

browser.proxy.register(proxyScriptURL);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `register` | No | No | 56–7155–71 | ? | No | No | ? | ? | 56–7955–79 | ? | No | ? |


 **Note:** Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/register>

proxy.unregister()
==================



**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

  **Warning:** This method was deprecated in Firefox 68 and removed in Firefox 71. In Firefox 68–70, calling this method logs an error message to the console:

  ![Proxy unregister error message.] 

  Unregisters a [Proxy Auto-Configuration (PAC) file](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file). that was registered by an earlier call to [`proxy.register()`](register).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let unregistering = browser.proxy.unregister()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments when the PAC file has been unregistered.

Examples
--------



```
browser.proxy.unregister();

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `unregister` | No | No | 56–71 | ? | No | No | ? | ? | 56–79 | ? | No | ? |


 **Note:** Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/unregister>

Theme
=====


A Theme object represents the specification of a theme.


Type
----


A JSON [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that takes the same properties as the ["theme"](../../manifest.json/theme) manifest key.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `Theme` | No | No | 55 | ? | No | No | ? | ? | No | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme/Theme>

userScripts.RegisteredUserScript
================================



A `RegisteredUserScript` object is returned by a call to [`userScripts.register()`](register) and represents the user scripts registered in that call.

 The object defines a single method, [`unregister()`](registereduserscript/unregister), which is used to unregister the user scripts.

  **Note:** If this object is destroyed (for example because it goes out of scope) then the associated scripts will be unregistered automatically, so you should keep a reference to this object for as long as you want the user scripts to stay registered.

 

Methods
-------


 [`unregister()`](registereduserscript/unregister)  Unregisters the user scripts represented by this object.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `RegisteredUserScript` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |
| `unregister` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript>

Working with userScripts
========================



By implementing userScripts, extension developers can modify how sites look and/or work to better meet user needs.

 Implement userScripts in your extension using the following steps:

 1. Define the script in the extension's manifest using the `"user_scripts"` key.
2. Register the userScript
3. Implement the userScript functions

 Let's step through the processes using a small sample web extension that illustrates the process. The example is available in the [webextensions-examples](https://github.com/mdn/webextensions-examples) repository on GitHub.



userScripts Manifest
--------------------



A user script is identified by the contents of the [user\_scripts](../../manifest.json/user_scripts) key of the extension's manifest. The minimum information for the `user_scripts` key would be:

 
```
  "user\_scripts": {
    "api\_script": "customUserScriptAPIs.js"
  }

```
 The "api\_script" property indicates the path to the JavaScript file that contains the code for the `userScript`.


Load the example extension
--------------------------



Once you have downloaded the example:

 Navigate to about:debugging, click on **Load Temporary Add-on…** and double-click on the extension's manifest.

 The default code included with the example allows you to load a `userScript` which will "eat" the content of pages matching the Hosts entry. Make any changes you want to make before clicking the **Register script** button at the bottom of the panel.

 In the following image, the extension will "eat" the content of pages whose domain name ends in .org. This is the default behavior for this extension.

  ![User script example] 

 Nothing will happen until you click the **Register script** button. The button implements the user script according to the settings on this dialog. That means that you can experiment with the behavior of the script without having to implement an extensions yourself.


Register the userScript
-----------------------



Before a userScript can be executed, it must be registered using the `userScripts.register()` method. Here is the code to register the example extension:

 
```
async function registerScript() {
  const params = {
    hosts: stringToArray(hostsInput.value),
    code: codeInput.value,
    excludeMatches: stringToArray(excludeMatchesInput.value),
    includeGlobs: stringToArray(includeGlobsInput.value),
    excludeGlobs: stringToArray(excludeGlobsInput.value),
    runAt: runAtInput.value,
    matchAboutBlank: stringToBool(matchAboutBlankInput.value),
    allFrames: stringToBool(allFramesInput.value),
    scriptMetadata: {name: scriptNameInput.value || null},
  };

  // Store the last submitted values to the extension storage
  // (so that they can be restored when the popup is opened
  // the next time).
  await browser.storage.local.set({
    lastSetValues: params,
  });

  try {
    // Clear the last userScripts.register result.
    lastResultEl.textContent = "";

    await browser.runtime.sendMessage(params);
    lastResultEl.textContent = "UserScript successfully registered";
    // Clear the last userScripts.register error.
    lastErrorEl.textContent = "";

    // Clear the last error stored.
    await browser.storage.local.remove("lastError");
  } catch (e) {
    // There was an error on registering the userScript,
    // let's show the error message in the popup and store
    // the last error into the extension storage.

    const lastError = `${e}`;
    // Show the last userScripts.register error.
    lastErrorEl.textContent = lastError;

    // Store the last error.
    await browser.storage.local.set({lastError});
  }
}

```
 This code first initializes the params object to pass values to the [userScripts.register](register) method.


Implement the userScript functions
----------------------------------



Once the script has been registered, navigate to a page whose domain name ends in .org, and you will see something like this:

  ![Status message indicating that websites ending in .org have been eaten: "This page has been eaten. {"OldStoredValue:" "website address", "NewStoredValue:" "website address"}"] 


See also
--------


* [`userScripts`](../userscripts)
* [`userScripts.register()`](register)
* [`userScripts.onBeforeScript`](onbeforescript)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/Working_with_userScripts>

webRequest.StreamFilter
=======================



A `StreamFilter` is an object you use to monitor and modify HTTP responses.

 To create a `StreamFilter`, call [`webRequest.filterResponseData()`](filterresponsedata), passing the ID of the web request you want to filter.

 You can think of the stream filter as sitting between the networking stack and the browser's rendering engine. The filter is passed HTTP response data as it's received from the network. It can examine and modify the data before passing it along to the rendering engine, where it is parsed and rendered. The filter has full control over the response body, and the default behavior without any listeners or write calls is to have a stream without content that never closes.

 The filter generates four different events:

 * [`onstart`](streamfilter/onstart) when the filter is about to start receiving response data.
* [`ondata`](streamfilter/ondata) when some response data has been received by the filter and is available to be examined or modified.
* [`onstop`](streamfilter/onstop) when the filter has finished receiving response data.
* [`onerror`](streamfilter/onerror) if an error has occurred in initializing and operating the filter.

 You can listen to each event by assigning a listener function to its attribute:

 
```
filter.onstart = (event) => {
  console.log("started");
}

```
 Note that the request is blocked during the execution of any event listeners.

 The filter provides a [`write()`](streamfilter/write) function. At any time from the `onstart` event onwards you can use this function to write data to the output stream.

 If you assign listeners to any of the filter's events, all the response data passed to the rendering engine is supplied through calls you make to `write()`. So, if you add a listener and don't call `write()` the rendered page is blank.

 Once you have finished interacting with the response, call either of the following:

 * [`disconnect()`](streamfilter/disconnect): This disconnects the filter from the request, so the rest of the response is processed normally.
* [`close()`](streamfilter/close): This closes the request, so no additional response data will be processed.

 The filter also provides functions to [`suspend()`](streamfilter/suspend) and [`resume()`](streamfilter/resume) the request.



Methods
-------


 [`webRequest.StreamFilter.close()`](streamfilter/close)  Closes the request.

  [`webRequest.StreamFilter.disconnect()`](streamfilter/disconnect)  Disconnects the filter from the request.

  [`webRequest.StreamFilter.resume()`](streamfilter/resume)  Resumes processing of the request.

  [`webRequest.StreamFilter.suspend()`](streamfilter/suspend)  Suspends processing of the request.

  [`webRequest.StreamFilter.write()`](streamfilter/write)  Writes some data to the output stream.

  Properties
----------


 [`webRequest.StreamFilter.ondata`](streamfilter/ondata)  Event handler which is called when incoming data is available.

  [`webRequest.StreamFilter.onerror`](streamfilter/onerror)  Event handler which is called when an error has occurred.

  [`webRequest.StreamFilter.onstart`](streamfilter/onstart)  Event handler which is called when the stream is about to start receiving data.

  [`webRequest.StreamFilter.onstop`](streamfilter/onstop)  Event handler which is called when the stream has no more data to deliver and has closed.

  [`webRequest.StreamFilter.error`](streamfilter/error)  When [`webRequest.StreamFilter.onerror`](streamfilter/onerror) is called, this will describe the error.

  [`webRequest.StreamFilter.status`](streamfilter/status)  Describes the current status of the stream.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `StreamFilter` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `close` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `disconnect` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `error` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `ondata` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `onerror` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `onstart` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `onstop` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `resume` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `status` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `suspend` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |
| `write` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This code listens for `onstart`, `ondata`, and `onstop`. It logs those events, and the response data as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) itself:

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    console.log("started");
  }

  filter.ondata = (event) => {
    console.log(event.data);
    filter.write(event.data);
  }

  filter.onstop = (event) => {
    console.log("finished");
    filter.disconnect();
  }

  //return {}; // not needed
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter>

webRequest.CertificateInfo
==========================



An object describing a single [X.509 certificate](https://datatracker.ietf.org/doc/html/rfc5280).

 The [`SecurityInfo`](securityinfo) object returned from the [`webRequest.getSecurityInfo()`](getsecurityinfo) API includes a `certificates` property which is an array of these objects.



Type
----



Values of this type are objects. They contain the following properties:

  `fingerprint`  `Object`. An object with the following properties:

  `sha1`  `String`. SHA-1 hash of the certificate's DER encoding.

  `sha256`  `String`. SHA-256 hash of the certificate's DER encoding.

    `isBuiltInRoot`  `Boolean`. `true` if the certificate is one of the trust roots installed in the browser, `false` otherwise.

  `issuer`  `String`. Name of the organization that issued this certificate, represented as a Distinguished Name and formatted as a comma-separated list of Relative Distinguished Names, each of the form "type=value".

 For example: "CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US".

  `rawDER`  `Array` of `Number`. If [`webRequest.getSecurityInfo()`](getsecurityinfo) was called with the `rawDER` option present and set to `true`, this will contain the DER encoding of the certificate.

  `serialNumber`  `String`. The certificate's [serial number](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2).

  `subject`  `String`. Name of the organization that issued this certificate, represented as a Distinguished Name and formatted as a comma-separated list of Relative Distinguished Names, each of the form "type=value".

 For example: "CN=\*.cdn.mozilla.net,O=Mozilla Corporation,L=Mountain View,ST=California,C=US".

  `subjectPublicKeyInfoDigest`  `Object`. An object containing the following properties:

  `sha256`  `String`. Base64 encoded SHA-256 hash of the DER-encoded [public key info](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.7).

    `validity`  `Object`. Validity period for the certificate. An object containing the following properties:

  `start`  `Number`. The start of the certificate's validity period, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `end`  `Number`. The end of the certificate's validity period, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

    
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `CertificateInfo` | NoSee [bug 628819](https://crbug.com/628819). | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/CertificateInfo>

webRequest.HttpHeaders
======================


An array of HTTP headers. Each header is represented as an object with two properties: `name` and either `value` or `binaryValue`.


Type
----



An `array` of `object`s. Each object has the following properties:

  `name`  `string`. Name of the HTTP header.

  
`value` Optional
  `string`. Value of the HTTP header if it can be represented by UTF-8. Either this property or `binaryValue` must be present.

  
`binaryValue` Optional
  `array` of `integer`. Value of the HTTP header if it cannot be represented by UTF-8, represented as bytes (0..255). Either this property or `value` must be present.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `HttpHeaders` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#type-HttpHeaders) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/HttpHeaders>

webRequest.SecurityInfo
=======================



An object describing the security properties of a particular web request. An object of this type is returned from the [`webRequest.getSecurityInfo()`](getsecurityinfo) API.

 If the request is not secured using [TLS](https://developer.mozilla.org/en-US/docs/Glossary/TLS), then this object will contain only the property `state`, whose value will be `"insecure"`.



Type
----



Values of this type are objects. They contain the following properties:

  `certificates`  `Array` of [`CertificateInfo`](certificateinfo). If [`webRequest.getSecurityInfo()`](getsecurityinfo) was called with the `certificateChain` option present and set to `true`, this will contain a `CertificateInfo` object for every certificate in the chain, from the server certificate up to and including the trust root.

 Otherwise it will contain a single `CertificateInfo` object, for the server certificate.

  
`certificateTransparencyStatus` Optional
  `String`. Indicates the [Certificate Transparency](https://certificate.transparency.dev/) status for the connection. This may take any one of the following values:

 * "not\_applicable"
* "policy\_compliant"
* "policy\_not\_enough\_scts"
* "policy\_not\_diverse\_scts"

  
`cipherSuite` Optional
  `String`. Cipher suite used for the connection, formatted as per the [TLS specification](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5): for example, "TLS\_ECDHE\_RSA\_WITH\_AES\_128\_GCM\_SHA256".

  
`errorMessage` Optional
  `String`. If there was a problem with the TLS handshake (for example, the certificate had expired, or a trusted root could not be found, or a certificate was revoked) then `status` will be "broken" and the `errorMessage` property will contain a string describing the error, taken from Firefox's internal list of error codes.

 Note though that at present you can only call `getSecurityInfo()` in the `onHeaderReceived` listener, and the `onHeaderReceived` event is not fired when the handshake fails. So in practice this will never be set.

  
`hsts` Optional
  `Boolean`. `true` if the host uses [Strict Transport Security](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security), `false` otherwise.

  
`isDomainMismatch` Optional
  `Boolean`. `true` if the server's domain name does not match the domain name in its certificate, `false` otherwise.

  
`isExtendedValidation` Optional
  `Boolean`. `true` if the server has an [Extended Validation Certificate](https://en.wikipedia.org/wiki/Extended_Validation_Certificate), `false` otherwise.

  
`isNotValidAtThisTime` Optional
  `Boolean`. `true` if the current time falls outside the server certificate's validity period (i.e. the certificate has expired or is not yet valid), `false` otherwise.

  
`isUntrusted` Optional
  `Boolean`. `true` if a chain back to a trusted root certificate could not be constructed, `false` otherwise.

  
`keaGroupName` Optional
  `String`. If `state` is "secure" this describes the key exchange algorithm used in this request.

  
`protocolVersion` Optional
  `String`. Version of the TLS protocol used. One of:

 * "TLSv1"
* "TLSv1.1"
* "TLSv1.2"
* "TLSv1.3"
* "unknown" (if the version is not valid)

  
`secretKeyLength` Optional
  `Number`. The length of the secret key in bits.

  
`signatureSchemeName` Optional
  `String`. If `state` is "secure" this describes the signature scheme used in this request.

  `state`  `String`. State of the connection. One of:

 * "broken": the TLS handshake failed (for example, the certificate had expired)
* "insecure": the connection is not a TLS connection
* "secure": the connection is a secure TLS connection
* "weak": the connection is a TLS connection but is considered weak. You can examine `weaknessReasons` to find out the problem.

 Note though that at present you can only call `getSecurityInfo()` in the `onHeaderReceived` listener, and the `onHeaderReceived` event is not fired when the handshake fails. So in practice this will never be set to "broke".

  
`usedDelegatedCredentials` Optional
  `Boolean`. `true` if the connection used Delegated Credentials, `false` otherwise.

  
`usedEch` Optional
  `Boolean`. `true` if the connection used ECH (Encrypted Client Hello), `false` otherwise.

  
`usedOcsp` Optional
  `Boolean`. `true` if the connection made an OCSP (Online Certificate Status Protocol) request, `false` otherwise.

  
`usedPrivateDns` Optional
  `Boolean`. `true` if the connection made a private DNS lookup, such as with DoH (DNS over HTTPS), `false` otherwise.

  
`weaknessReasons` Optional
  `String`. If `state` is "weak", this indicates the reason. Currently this may contain only a single value "cipher", indicating that the negotiated cipher suite is considered weak.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `SecurityInfo` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `certificateTransparencyStatus` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `certificates` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `cipherSuite` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `errorMessage` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `hsts` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `isDomainMismatch` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `isExtendedValidation` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `isNotValidAtThisTime` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `isUntrusted` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `keaGroupName` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `protocolVersion` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `secretKeyLength` | No | No | 109 | ? | No | No | ? | ? | 109 | ? | No | ? |
| `signatureSchemeName` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `state` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |
| `usedDelegatedCredentials` | No | No | 112 | ? | No | No | ? | ? | 112 | ? | No | ? |
| `usedEch` | No | No | 112 | ? | No | No | ? | ? | 112 | ? | No | ? |
| `usedOcsp` | No | No | 112 | ? | No | No | ? | ? | 112 | ? | No | ? |
| `usedPrivateDns` | No | No | 112 | ? | No | No | ? | ? | 112 | ? | No | ? |
| `weaknessReasons` | No | No | 62 | ? | No | No | ? | ? | 62 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/SecurityInfo>

webRequest.UploadData
=====================


Contains data uploaded in a URL request.


Type
----



Values of this type are objects. They contain the following properties:

  
`bytes` Optional
  `any`. An ArrayBuffer with a copy of the data.

  
`file` Optional
  `string`. A string with the file's path and name.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `UploadData` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#type-UploadData) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/UploadData>

webRequest.MAX\_HANDLER\_BEHAVIOR\_CHANGED\_CALLS\_PER\_10\_MINUTES
===================================================================



The maximum number of times that `[`handlerBehaviorChanged()`](handlerbehaviorchanged)` can be called in a 10 minute period.

 This property is read-only.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#property-MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES>

webRequest.BlockingResponse
===========================



An object of this type is returned by event listeners that have set `"blocking"` in their `extraInfoSpec` argument.

 By setting particular properties in `BlockingResponse`, the listener can modify network requests.

 Note that you can't set all this object's properties in every listener: the properties you can set are dependent on the event that triggered this listener, as detailed below.



Type
----



Values of this type are objects. They contain the following properties:

  
`authCredentials` Optional
  `object`. If set, the request is made using the given credentials. You can only set this property in [`onAuthRequired`](onauthrequired). The `authCredentials` property is an object with the following properties:

  `username`  `string`. Username to supply.

  `password`  `string`. Password to supply.

    
`cancel` Optional
  `boolean`. If `true`, the request is cancelled. You can only set this property in [`onBeforeRequest`](onbeforerequest), [`onBeforeSendHeaders`](onbeforesendheaders), [`onHeadersReceived`](onheadersreceived), and [`onAuthRequired`](onauthrequired).

  
`redirectUrl` Optional
  `string`. This is a URL, and if set, the original request is redirected to that URL. You can only set this property in [`onBeforeRequest`](onbeforerequest) or [`onHeadersReceived`](onheadersreceived).

 Redirections to non-HTTP schemes such as data: are allowed, but they are not currently supported ([Firefox bug 707624](https://bugzil.la/707624)). Redirects use the same request method as the original request unless initiated from `onHeadersReceived` stage, in which case the redirect uses the GET method.

 If an extension wants to redirect a public (e.g. HTTPS) URL to an [extension page](../../user_interface/extension_pages), the extension's manifest.json file must contain a [web\_accessible\_resources](../../manifest.json/web_accessible_resources) key that lists the URL for the extension page.

  
`requestHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). This is an [`HttpHeaders`](httpheaders) object, an array in which each object represents a header. If set, the request is made with these headers rather than the original headers. You can only set this property in [`onBeforeSendHeaders`](onbeforesendheaders) .

  
`responseHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). This is an [`HttpHeaders`](httpheaders) object, an array in which each object represents a header. If set, the server is assumed to have responded with these response headers instead of the originals. You can only set this property in [`onHeadersReceived`](onheadersreceived). If multiple extensions attempt to set the same header (for example, `Content-Security-Policy`), only one of the changes will be successful.

  
`upgradeToSecure` Optional
  `boolean`. If set to `true` and the original request is an HTTP request, this will prevent the original request from being sent and instead make a secure (HTTPS) request. If any extension returns `redirectUrl` in `onBeforeRequest`, then `upgradeToSecure` will be ignored for that request. You can only set this property in [`onBeforeRequest`](onbeforerequest).

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `BlockingResponse` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |
| `upgradeToSecure` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#type-BlockingResponse) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/BlockingResponse>

webRequest.handlerBehaviorChanged()
===================================



This function can be used to ensure that event listeners are applied correctly when pages are in the browser's in-memory cache. If the browser has loaded a page, and the page is reloaded, the browser may reload the page from its in-memory cache, and in this case, events will not be triggered for the request.

 Suppose an extension's job is to block web requests against a pattern, and the following scenario happens:

 * The user loads a page that includes a particular request, and the pattern permits the request.
* The resource is loaded and cached in memory.
* The extension's patterns are updated, in such a way that the resource would no longer be permitted.
* The user reloads the page.

 Because the page will be reloaded from the memory cache, the listener may not be called again, and the request will be loaded despite the extension's new policy.

 The `handlerBehaviorChanged()` function is designed to address this problem. It flushes the in-memory cache, so that page reloads will trigger event listeners.

 Because `handlerBehaviorChanged()` flushes the cache, it can be expensive and bad for performance. The webRequest module defines a read-only property [`MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES`](max_handler_behavior_changed_calls_per_10_minutes): making more calls than this number in 10 minutes will have no effect.

 The implementation of caching, hence the need for this function, varies from one browser to another, so in some browsers this function does nothing.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let flushingCache = browser.webRequest.handlerBehaviorChanged()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments, when the operation has completed.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `handlerBehaviorChanged` | Yes | 14 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


Examples
--------



In the following snippet, we flush the in-memory cache via a call to `handlerBehaviorChanged()`, and report this action by logging an appropriate message to the console.

 
```
function onFlushed() {
  console.log(`In-memory cache flushed`);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let flushingCache = browser.webRequest.handlerBehaviorChanged();
flushingCache.then(onFlushed, onError);

```
  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#method-handlerBehaviorChanged) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/handlerBehaviorChanged>

webRequest.onSendHeaders
========================



This event is fired just before sending headers. If your extension or some other extension modified headers in `[`onBeforeSendHeaders`](onbeforesendheaders)`, you'll see the modified version here.

 This event is informational only.



Syntax
------




```
browser.webRequest.onSendHeaders.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onSendHeaders.removeListener(listener)
browser.webRequest.onSendHeaders.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

    `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can only pass one value here:

 * `"requestHeaders"`: include the request headers in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  
`requestHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP request headers that have been sent out with this request.

  `tabId`  `integer`. ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onSendHeaders` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


Examples
--------



This code logs all cookies that will be sent in making requests to the target [match pattern](../../match_patterns):

 
```
// The target match pattern
let targetPage = "\*://\*.google.ca/\*";

// Log cookies sent with this request
function logCookies(e) {
  for (const header of e.requestHeaders) {
    if (header.name === "Cookie") {
      console.log(header.value);
    }
  }
}

// Listen for onSendHeaders, and pass
// "requestHeaders" so we get the headers
browser.webRequest.onSendHeaders.addListener(
  logCookies,
  {urls: [targetPage]},
  ["requestHeaders"]
);

```
  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onSendHeaders) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onSendHeaders>

webRequest.onResponseStarted
============================



Fired when the first byte of the response body is received.

 This event is informational only.



Syntax
------




```
browser.webRequest.onResponseStarted.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onResponseStarted.removeListener(listener)
browser.webRequest.onResponseStarted.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

    `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass just one value:

 * `"responseHeaders"`: include `responseHeaders` in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Indicates if this response was fetched from disk cache.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `ip`  `string`. The IP address of the server the request was sent to. It may be a literal IPv6 address.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  
`responseHeaders` Optional
  [`webRequest.HttpHeaders`](httpheaders). The HTTP response headers that were received along with this response.

  `statusCode`  `integer`. Standard HTTP status code returned by the server.

  `statusLine`  `string`. HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers.

  `tabId`  `integer`. The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onResponseStarted` | Yes | 14 | 45 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


Examples
--------




```
let target = "https://developer.mozilla.org/\*";

/\*
e.g.
"https://developer.mozilla.org/en-US/Firefox/Releases"
200
HTTP/1.1 200 OK
\*/
function logResponse(responseDetails) {
  console.log(responseDetails.url);
  console.log(responseDetails.statusCode);
  console.log(responseDetails.statusLine);
}

browser.webRequest.onResponseStarted.addListener(
  logResponse,
  {urls: [target]}
);

```
  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onResponseStarted) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onResponseStarted>

webRequest.onBeforeRedirect
===========================



Fired when a server-initiated redirect is about to occur.

 Note that you can't pass `"blocking"` for this event, so you can't modify or cancel the request from this event: it's informational only.



Syntax
------




```
browser.webRequest.onBeforeRedirect.addListener(
  listener,             // function
  filter,               // object
  extraInfoSpec         // optional array of strings
)
browser.webRequest.onBeforeRedirect.removeListener(listener)
browser.webRequest.onBeforeRedirect.hasListener(listener)

```
 Events have three functions:

  `addListener(callback, filter, extraInfoSpec)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the request. See the [details](#details_2) section for more information.

    `filter`  [`webRequest.RequestFilter`](requestfilter). A filter that restricts the events that will be sent to this listener.

  
`extraInfoSpec` Optional
  `array` of `string`. Extra options for the event. You can pass just one value:

 * `"responseHeaders"`: include `responseHeaders` in the `details` object passed to the listener

  Additional objects
------------------


### details


 `cookieStoreId`  `string`. If the request is from a tab open in a contextual identity, the cookie store ID of the contextual identity.

  `documentUrl`  `string`. URL of the document in which the resource will be loaded. For example, if the web page at "<https://example.com>" contains an image or an iframe, then the `documentUrl` for the image or iframe will be "<https://example.com>". For a top-level document, `documentUrl` is undefined.

  `frameId`  `integer`. Zero if the request happens in the main frame; a positive value is the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (`type` is `main_frame` or `sub_frame`), `frameId` indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.

  `fromCache`  `boolean`. Indicates if this response was fetched from disk cache.

  `incognito`  `boolean`. Whether the request is from a private browsing window.

  `ip`  `string`. The IP address of the server the request was sent to. It may be a literal IPv6 address.

  `method`  `string`. Standard HTTP method: for example, "GET" or "POST".

  `originUrl`  `string`. URL of the resource which triggered the request. For example, if "<https://example.com>" contains a link, and the user clicks the link, then the `originUrl` for the resulting request is "<https://example.com>".

 The `originUrl` is often but not always the same as the `documentUrl`. For example, if a page contains an iframe, and the iframe contains a link that loads a new document into the iframe, then the `documentUrl` for the resulting request will be the iframe's parent document, but the `originUrl` will be the URL of the document in the iframe that contained the link.

  `parentFrameId`  `integer`. ID of the frame that contains the frame which sent the request. Set to -1 if no parent frame exists.

  `proxyInfo`  `object`. This property is present only if the request is being proxied. It contains the following properties:

  `host`  `string`. The hostname of the proxy server.

  `port`  `integer`. The port number of the proxy server.

  `type`  `string`. The type of proxy server. One of:

 * "http": HTTP proxy (or SSL CONNECT for HTTPS)
* "https": HTTP proxying over TLS connection to proxy
* "socks": SOCKS v5 proxy
* "socks4": SOCKS v4 proxy
* "direct": no proxy
* "unknown": unknown proxy

  `username`  `string`. Username for the proxy service.

  `proxyDNS`  `boolean`. True if the proxy will perform domain name resolution based on the hostname supplied, meaning that the client should not do its own DNS lookup.

  `failoverTimeout`  `integer`. Failover timeout in seconds. If the proxy connection fails, the proxy will not be used again for this period.

    `redirectUrl`  `string`. The new URL.

  `requestId`  `string`. The ID of the request. Request IDs are unique within a browser session, so you can use them to relate different events associated with the same request.

  `responseHeaders`  [`webRequest.HttpHeaders`](httpheaders). The HTTP response headers that were received along with this redirect.

  `statusCode`  `integer`. Standard HTTP status code returned by the server.

  `statusLine`  `string`. HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers.

  `tabId`  `integer`. The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.

  `thirdParty`  `boolean`. Indicates whether the request and its content window hierarchy are third party.

  `timeStamp`  `number`. The time when this event fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `type`  [`webRequest.ResourceType`](resourcetype). The type of resource being requested: for example, "image", "script", "stylesheet".

  `url`  `string`. Target of the request.

  `urlClassification`  `object`. The type of tracking associated with the request, if with the request has been classified by [Firefox Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop). This is an object with the following properties:

  `firstParty`  `array` of `strings`. Classification flags for the request's first party.

  `thirdParty`  `array` of `strings`. Classification flags for the request or its window hierarchy's third parties.

   The classification flags include:

 * `fingerprinting` and `fingerprinting_content`: indicates the request is involved in fingerprinting. `fingerprinting_content` indicates the request is loaded from an origin that has been found to fingerprint but is not considered to participate in tracking, such as a payment provider.
* `cryptomining` and `cryptomining_content`: similar to the fingerprinting category but for cryptomining resources.
* `tracking`, `tracking_ad`, `tracking_analytics`, `tracking_social`, and `tracking_content`: indicates the request is involved in tracking. `tracking` is any generic tracking request, the `ad`, `analytics`, `social`, and `content` suffixes identify the type of tracker.
* `any_basic_tracking`: a meta flag that combines any tracking and fingerprinting flags, excluding `tracking_content` and `fingerprinting_content`.
* `any_strict_tracking`: a meta flag that combines any tracking and fingerprinting flags, including `tracking_content` and `fingerprinting_content`.
* `any_social_tracking`: a meta flag that combines any social tracking flags.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBeforeRedirect` | Yes | 14 | 46 | ? | Yes | 14`extraInfoSpec` options are not supported. | ? | ? | 48 | ? | No | ? |


Examples
--------




```
let target = "https://developer.mozilla.org/\*";

/\*
e.g.
"https://developer.mozilla.org/"
"https://developer.mozilla.org/en-US/"
\*/
function logResponse(responseDetails) {
  console.log(responseDetails.url);
  console.log(responseDetails.redirectUrl);
}

browser.webRequest.onBeforeRedirect.addListener(
  logResponse,
  {urls: [target]}
);

```
  **Note:** This API is based on Chromium's [`chrome.webRequest`](https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onBeforeRedirect) API. This documentation is derived from [`web_request.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRedirect>

webNavigation.onDOMContentLoaded
================================


Fired when the [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) event is fired in the page. At this point the document is loaded and parsed, and the DOM is fully constructed, but linked resources such as images, stylesheets and subframes may not yet be loaded.


Syntax
------




```
browser.webNavigation.onDOMContentLoaded.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onDOMContentLoaded.removeListener(listener)
browser.webNavigation.onDOMContentLoaded.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation has occurred.

  `url`  `string`. The URL to which the given frame has navigated.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation is occurring. `0` indicates that navigation happens in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happens in a nested iframe. Frame IDs are unique for a given tab and process.

  `timeStamp`  `number`. The time at which `DOMContentLoaded` was fired, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onDOMContentLoaded` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |


Examples
--------



Logs the target URLs for `onDOMContentLoaded`, if the target URL's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnDOMContentLoaded(details) {
  console.log(`onDOMContentLoaded: ${details.url}`);
}

browser.webNavigation.onDOMContentLoaded.addListener(logOnDOMContentLoaded, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onDOMContentLoaded>

webNavigation.onCreatedNavigationTarget
=======================================



Fired when a new window, or a new tab in an existing window, is created to host the target of a navigation. For example, this event is sent when:

 * the user opens a link in a new tab or window
* a web page loads a resource into a new tab or window using [`window.open()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) (but note that the event is not sent if the browser's popup blocker blocks the load).

 The event is not sent if a tab or window is created without a navigation target (for example, if the user opens a new tab by pressing `Ctrl+T`).

 If this event is fired, it will be fired before [`webNavigation.onBeforeNavigate`](onbeforenavigate).



Syntax
------




```
browser.webNavigation.onCreatedNavigationTarget.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onCreatedNavigationTarget.removeListener(listener)
browser.webNavigation.onCreatedNavigationTarget.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions. Note that `filter` is not supported in Firefox.

  Additional objects
------------------


### details


 `sourceFrameId`  `integer`. ID of the frame from which the navigation is initiated. `0` indicates that the frame is the tab's top-level browsing context, not a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation is initiated from a nested iframe. Frame IDs are unique for a given tab and process.

  `sourceProcessId`  `integer`. The ID of the process from which the navigation is initiated.

  `sourceTabId`  `integer`. The ID of the tab from which the navigation is initiated. For example, if the user opens a link in a new tab, this will be the ID of the tab containing the link.

  `tabId`  `integer`. The ID of the newly created tab.

  `timeStamp`  `number`. The time when the browser created the navigation target, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `url`  `string`. The URL which will be loaded in the new tab.

  `windowId`  `number`. The ID of the window in which the new tab is created.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onCreatedNavigationTarget` | YesIf a blocked popup is unblocked by the user, the event is still not sent. | 14 | 54["If the filter parameter is empty, Firefox raises an exception.", "If a blocked popup is unblocked by the user, the event is then sent."] | ? | 17If a blocked popup is unblocked by the user, the event is still not sent. | No | ? | ? | 54["If the filter parameter is empty, Firefox raises an exception.", "If a blocked popup is unblocked by the user, the event is then sent.", "This event is only sent in the 'window.open()' case."] | ? | No | ? |
| `sourceProcessId` | Yes | 14 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `windowId` | No | 14–79 | 54 | ? | 17 | No | ? | ? | 54 | ? | No | ? |


Examples
--------



Logs the target URL, source Tab ID, and source frame ID for `onCreatedNavigationTarget`, if the target's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnCreatedNavigationTarget(details) {
  console.log(`onCreatedNavigationTarget: ${details.url}`);
  console.log(details.sourceTabId);
  console.log(details.sourceFrameId);
}

browser.webNavigation.onCreatedNavigationTarget.addListener(logOnCreatedNavigationTarget, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onCreatedNavigationTarget>

topSites.MostVisitedURL
=======================


The `MostVisitedURL` type contains two properties: the title of a page and its URL.


Type
----



Values of this type are objects. They contain the following properties:

  
`favicon` Optional
  `String`. A data: URL containing the favicon for the page, if `includeFavicon` was given in [`topSites.get()`](get) and the favicon was available.

  `title`  `String`. The page's title.

  `url`  `String`. The page's URL.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `MostVisitedURL` | Yes | 79 | 52 | ? | Yes | No | ? | ? | 52–79 | ? | No | ? |
| `favicon` | No | No | 63 | ? | No | No | ? | ? | 63–79 | ? | No | ? |


Examples
--------


 **Note:** This API is based on Chromium's [`chrome.topSites`](https://developer.chrome.com/docs/extensions/reference/topSites/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/topSites/MostVisitedURL>

webNavigation.onBeforeNavigate
==============================


Fired when the browser is about to start a navigation event.


Syntax
------




```
browser.webNavigation.onBeforeNavigate.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onBeforeNavigate.removeListener(listener)
browser.webNavigation.onBeforeNavigate.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation is about to occur.

  `url`  `string`. The URL to which the given frame will navigate.

  `processId`  `integer`. The ID of the process in which this tab is being rendered (This property is **not supported on Firefox**, and it is **deprecated on Chrome**).

  `frameId`  `integer`. Frame in which the navigation is about to occur. `0` indicates that navigation happens in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happens in a nested iframe. Frame IDs are unique for a given tab and process.

  `parentFrameId`  `integer`. ID of this frame's parent. Set to `-1` if this is a top-level frame.

  `timeStamp`  `number`. The time when the browser is about to start the navigation, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onBeforeNavigate` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |


Examples
--------



Logs the target URLs for `onBeforeNavigate`, if the target's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnBefore(details) {
  console.log(`onBeforeNavigate to: ${details.url}`);
}

browser.webNavigation.onBeforeNavigate.addListener(logOnBefore, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onBeforeNavigate>

webNavigation.onHistoryStateUpdated
===================================


Fired when the page used the [>history API](https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API) to update the URL displayed in the browser's location bar. All future events for this frame will use the updated URL.


Syntax
------




```
browser.webNavigation.onHistoryStateUpdated.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onHistoryStateUpdated.removeListener(listener)
browser.webNavigation.onHistoryStateUpdated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation is about to occur.

  `url`  `string`. The URL to which the given frame will navigate.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation will occur. `0` indicates that navigation happens in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happens in a nested iframe. Frame IDs are unique for a given tab and process.

  `timeStamp`  `number`. The time that the URL was changed by the history API, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `transitionType`  `[`transitionType`](transitiontype)`. The reason for the navigation: for example, `"link"` if the user clicked a link.

  `transitionQualifiers`  `Array` of [`transitionQualifier`](transitionqualifier). Extra information about the navigation: for example, whether there was a server or client redirect.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHistoryStateUpdated` | Yes | 14Filtering is not supported. | 47 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `transitionQualifiers` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `transitionType` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



Logs the target URLs and extra transition information for `onHistoryStateUpdated`, if the target URL's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnHistoryStateUpdated(details) {
  console.log(`onHistoryStateUpdated: ${details.url}`);
  console.log(`Transition type: ${details.transitionType}`);
  console.log(`Transition qualifiers: ${details.transitionQualifiers}`);
}

browser.webNavigation.onHistoryStateUpdated.addListener(logOnHistoryStateUpdated, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onHistoryStateUpdated>

webNavigation.TransitionQualifier
=================================


Extra information about a transition. Note that many values here are not currently supported in Firefox: see the [browser compatibility table](#browser_compatibility) for details.


Type
----



Values of this type are strings. Possible values are:

  "client\_redirect"  Redirect(s) caused by JavaScript running in the page or a "refresh" pragma in the page's [meta](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) tag.

  "server\_redirect"  Redirect(s) caused by a [3XX HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection) sent from the server.

  "forward\_back"  The user used the forward or back button to trigger the navigation.

  "from\_address\_bar"  The user triggered the navigation from the address bar.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TransitionQualifier` | Yes | 79 | 48'server\_redirect' is limited to top-level frames and 'client\_redirect' is not supplied when redirections are created by JavaScript. | ? | 17 | No | ? | ? | 48'server\_redirect' is limited to top-level frames and 'client\_redirect' is not supplied when redirections are created by JavaScript. | ? | No | ? |
| `from_address_bar` | Yes | 79 | 49 | ? | 17 | No | ? | ? | 49 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#type-TransitionQualifier) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/TransitionQualifier>

webNavigation.getFrame()
========================



Retrieves information about a particular frame. A frame may be the top-level frame in a tab or a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe), and is uniquely identified by a tab ID and a frame ID.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingFrame = browser.webNavigation.getFrame(
  details                // object
)

```
### Parameters


 `details`  `object`. Information about the frame to retrieve information about.

  `tabId`  `integer`. The ID of the tab in which the frame is.

  
`processId` Optional
  `integer`. The ID of the process running the renderer for this tab.

  `frameId`  `integer`. The ID of the frame in the given tab.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object containing the following properties:

  `errorOccurred`  `boolean`. True if the last navigation in this frame was interrupted by an error, i.e. the [`onErrorOccurred`](onerroroccurred) event fired.

  `url`  `string`. The URL currently associated with this frame, if the frame identified by `frameId` existed at one point in the tab identified by `tabId`. The fact that a URL is associated with a given `frameId` does not imply that the corresponding frame still exists.

  `parentFrameId`  `integer`. ID of this frame's parent. This is -1 if there is no parent frame: that is, if this frame is the top-level browsing context in the tab.

   If the tab is discarded, the promise will instead resolve with a `null` value. If the specified tab or frame ID could not be found, or some other error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getFrame` | Yes | 14 | 47 | ? | 17 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------




```
function onGot(frameInfo) {
  console.log(frameInfo);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

let gettingFrame = browser.webNavigation.getFrame({
  tabId: 19,
  frameId: 1537
});

// Edge specific - processId is required not optional, must be integer not null
//let gettingFrame = browser.webNavigation.getFrame({ tabId: 19, processId: 0, frameId: 1537 });

gettingFrame.then(onGot, onError);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#method-getFrame) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/getFrame>

webNavigation.getAllFrames()
============================



Given a tab ID, retrieves information about all the frames it contains.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingFrames = browser.webNavigation.getAllFrames(
  details                // object
)

```
### Parameters


 `details`  `object`. Information about the tab to retrieve all frames from.

  `tabId`  `integer`. The ID of the tab.

    ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an array of objects, each of which has the following properties:

  `errorOccurred`  `boolean`. True if the last navigation in this frame was interrupted by an error, i.e. the [`onErrorOccurred`](onerroroccurred) event fired.

  `processId`  `integer`. The ID of the process running the renderer for this tab.

  `frameId`  `integer`. The ID of the frame. If this is the main frame, then `frameId` is zero.

  `parentFrameId`  `integer`. ID of this frame's parent. This is -1 if there is no parent frame: that is, if this frame is the top-level browsing context in the tab.

  `url`  `string`. The URL currently associated with this frame.

   If the tab is discarded, the promise will instead resolve with a `null` value. If the specified tab could not be found, or some other error occurs, the promise will be rejected with an error message.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getAllFrames` | Yes | 14 | 47The returned objects do not include the `errorOccurred` property. See [bug 1248418](https://bugzil.la/1248418). | ? | 17 | 14 | ? | ? | 48The returned objects do not include the `errorOccurred` property. See [bug 1248418](https://bugzil.la/1248418). | ? | 15 | ? |


Examples
--------



This code logs the URLs of all frames in the active tab, when the user clicks a browser action:

 
```
function logFrameInfo(framesInfo) {
  for (const frameInfo of framesInfo) {
    console.log(frameInfo);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

function logAllFrames(tabs) {
  browser.webNavigation
    .getAllFrames({
      tabId: tabs[0].id,
    })
    .then(logFrameInfo, onError);
}

browser.browserAction.onClicked.addListener(() => {
  browser.tabs
    .query({
      currentWindow: true,
      active: true,
    })
    .then(logAllFrames, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#method-getAllFrames) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/getAllFrames>

webNavigation.onTabReplaced
===========================


Fired when the contents of the tab is replaced by a different (usually previously pre-rendered) tab.


Syntax
------




```
browser.webNavigation.onTabReplaced.addListener(
  listener,                   // function
  filter                      // optional object
);
browser.webNavigation.onTabReplaced.removeListener(listener)
browser.webNavigation.onTabReplaced.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. See the [details](#details_2) section for more information.

    Additional objects
------------------


### details


 `replacedTabId`  `integer`. The ID of the tab that was replaced.

  `tabId`  `integer`. The ID of the tab that replaced the old tab.

  `timeStamp`  `number`. The time when the replacement happened, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onTabReplaced` | Yes | 14 | 45Although you can add listeners for this event, it will never fire because the underlying functionality is not supported. | ? | 17 | No | ? | ? | 48Although you can add listeners for this event, it will never fire because the underlying functionality is not supported. | ? | No | ? |


Examples
--------




```
function logOnTabReplaced(details) {
  console.log(`onTabReplaced ${details}`);
}

browser.webNavigation.onTabReplaced.addListener(logOnTabReplaced);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onTabReplaced) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onTabReplaced>

windows.WINDOW\_ID\_NONE
========================


The `windowId` value that represents the absence of a browser window.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `WINDOW_ID_NONE` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#property-WINDOW_ID_NONE) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/WINDOW_ID_NONE>

windows.onRemoved
=================


Fired when a window is closed.


Syntax
------




```
browser.windows.onRemoved.addListener(listener)
browser.windows.onRemoved.removeListener(listener)
browser.windows.onRemoved.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `windowId`  `integer`. ID of the window that was closed.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRemoved` | Yes | 79 | 45 | ? | Yes | 14 | ? | ? | No | ? | No | ? |


Examples
--------



Log the IDs of windows as they are removed.

 
```
browser.windows.onRemoved.addListener((windowId) => {
  console.log(`Closed window: ${windowId}`);
});

```
  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#event-onRemoved) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/onRemoved>

webNavigation.onReferenceFragmentUpdated
========================================


Fired if the [fragment identifier](https://en.wikipedia.org/wiki/Fragment_identifier) for a page is changed. For example, if a page implements a table of contents using fragments, and the user clicks an entry in the table of contents, this event will fire. All future events for this frame will use the updated URL.


Syntax
------




```
browser.webNavigation.onReferenceFragmentUpdated.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onReferenceFragmentUpdated.removeListener(listener)
browser.webNavigation.onReferenceFragmentUpdated.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  `object`. Details about the navigation event. See the [details](#details_2) section for more information.

    
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects. If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array. If you omit this parameter, the event will fire for all transitions.

  Additional objects
------------------


### details


 `tabId`  `integer`. The ID of the tab in which the navigation is about to occur.

  `url`  `string`. The URL to which the given frame will navigate.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation will occur. `0` indicates that navigation happens in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). A positive value indicates that navigation happens in a nested iframe. Frame IDs are unique for a given tab and process.

  `timeStamp`  `number`. The time that the fragment identifier for the page was changed, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `transitionType`  `[`transitionType`](transitiontype)`. The reason for the navigation: for example, `"link"` if the user clicked a link.

  `transitionQualifiers`  `Array` of [`transitionQualifier`](transitionqualifier). Extra information about the navigation: for example, whether there was a server or client redirect.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onReferenceFragmentUpdated` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported. | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | No | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | No | ? |
| `transitionQualifiers` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `transitionType` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



Logs the target URLs and extra transition information for `onReferenceFragmentUpdated`, if the target URL's hostname contains "example.com" or starts with "developer".

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnReferenceFragmentUpdated(details) {
  console.log(`onReferenceFragmentUpdated: ${details.url}`);
  console.log(`Transition type: ${details.transitionType}`);
  console.log(`Transition qualifiers: ${details.transitionQualifiers}`);
}

browser.webNavigation.onReferenceFragmentUpdated.addListener(logOnReferenceFragmentUpdated, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onReferenceFragmentUpdated>

webNavigation.onErrorOccurred
=============================


Fired when an error occurs and the navigation is aborted. This can happen if either a network error occurred, or the user aborted the navigation.


Syntax
------




```
browser.webNavigation.onErrorOccurred.addListener(
  listener,                   // function
  filter                      // optional object
)
browser.webNavigation.onErrorOccurred.removeListener(listener)
browser.webNavigation.onErrorOccurred.hasListener(listener)

```
 Events have three functions:

   `addListener(listener)`

 `addListener(listener, filter)`

   Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `listener`  Function that will be called when this event occurs.

 The `listener` function will be called with the following arguments:

  `details`  [`object`](#details). Details about the navigation event. `details` has the following properties:

  `tabId`  `integer`. The ID of the tab in which the navigation was happening.

  `url`  `string`. The URL to which the given frame was navigating.

  `processId`  `integer`. The ID of the process in which this tab is being rendered.

  `frameId`  `integer`. Frame in which the navigation was happening.

 `0` indicates that navigation happened in the tab's top-level browsing context, not in a nested [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).

 A positive value indicates that navigation happened in a nested iframe.

 Frame IDs are unique for a given tab and process.

  `timeStamp`  `number`. The time at which the error occurred, in [milliseconds since the epoch](https://en.wikipedia.org/wiki/Unix_time).

  `error`  `string`. The error code. This is an internal error code, and is not guaranteed to stay the same or be consistent from one browser to another.

      
`filter` Optional
  `object`. An object containing a single property `url`, which is an `Array` of [`events.UrlFilter`](../events/urlfilter) objects.

 If you include this parameter, then the event will fire only for transitions to URLs which match at least one `UrlFilter` in the array.

 If you omit this parameter, the event will fire for all transitions.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onErrorOccurred` | YesIf the filter parameter is empty, Chrome matches all URLs. | 14Filtering is not supported | 45["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 17If the filter parameter is empty, Opera matches all URLs. | 14If the filter parameter is empty, Safari matches all URLs. | ? | ? | 48["Filtering is supported from version 50.", "If the filter parameter is empty, Firefox raises an exception."] | ? | 15If the filter parameter is empty, Safari matches all URLs. | ? |
| `error` | Yes | 14 | No | ? | 17 | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Logs the target URLs for `onErrorOccurred`, if the target URL's `hostname` contains `"example.com"` or starts with `"developer"`.

 
```
const filter = {
  url:
  [
    {hostContains: "example.com"},
    {hostPrefix: "developer"}
  ]
}

function logOnErrorOccurred(details) {
  console.log(`onErrorOccurred: ${details.url}`);
  console.log(details.error);
}

browser.webNavigation.onErrorOccurred.addListener(logOnErrorOccurred, filter);

```
  **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#event-onBeforeNavigate) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onErrorOccurred>

webNavigation.TransitionType
============================



Cause of the navigation: for example, the user clicked a link, or typed an address, or clicked a bookmark.

 Note that many values here are not currently supported in Firefox: see the [browser compatibility table](#browser_compatibility) for details.



Type
----



Values of this type are strings. Possible values are:

  "link"  The user clicked a link in another page.

  "typed"  The user typed the URL into the address bar. This is also used if the user started typing into the address bar, then selected a URL from the suggestions it offered. See also "generated".

  "auto\_bookmark"  The user clicked a bookmark or an item in the browser history.

  "auto\_subframe"  Any nested iframes that are automatically loaded by their parent.

  "manual\_subframe"  Any nested iframes that are loaded as an explicit user action. Loading such an iframe will generate an entry in the back/forward navigation list.

  "generated"  The user started typing in the address bar, then clicked on a suggested entry that didn't contain a URL.

  "start\_page"  The page was passed to the command line or is the start page.

  "form\_submit"  The user submitted a form. Note that in some situations, such as when a form uses a script to submit its contents, submitting a form does not result in this transition type.

  "reload"  The user reloaded the page, using the Reload button or by pressing Enter in the address bar. This is also used for session restore and reopening closed tabs.

  "keyword"  The URL was generated using a [keyword search](https://support.mozilla.org/en-US/kb/how-search-from-address-bar) configured by the user.

  "keyword\_generated"  Corresponds to a visit generated for a keyword.

  
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `TransitionType` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `auto_bookmark` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `auto_subframe` | Yes | 79 | 48Partially supported as the default transition type for subframes. | ? | 17 | No | ? | ? | 48Partially supported as the default transition type for subframes. | ? | No | ? |
| `form_submit` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `generated` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `keyword` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `keyword_generated` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `link` | Yes | 79 | 48Partially supported as the default transition type for top-level frames. | ? | 17 | No | ? | ? | 48Partially supported as the default transition type for top-level frames. | ? | No | ? |
| `manual_subframe` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `reload` | Yes | 79 | 48 | ? | 17 | No | ? | ? | 48 | ? | No | ? |
| `start_page` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |
| `typed` | Yes | 79 | No | ? | 17 | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.webNavigation`](https://developer.chrome.com/docs/extensions/reference/webNavigation/#type-TransitionType) API. This documentation is derived from [`web_navigation.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/web_navigation.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/TransitionType>

windows.getLastFocused()
========================



Gets the window that was most recently focused — typically the window 'on top'.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let gettingWindow = browser.windows.getLastFocused(
  getInfo               // optional object
)

```
### Parameters



 
`getInfo` Optional
  `object`.

  
`populate` Optional
  `boolean`. If `true`, the [`windows.Window`](window) object will have a `tabs` property that contains a list of [`tabs.Tab`](../tabs/tab) objects representing the tabs in the window. The `Tab` objects only contain the `url`, `title` and `favIconUrl` properties if the extension's manifest file includes the `"tabs"` permission or [host permissions](../../manifest.json/permissions#host_permissions) matching the tab's URL.

  
`windowTypes` Optional
  An `array` of [`windows.WindowType`](windowtype) objects. If set, the [`windows.Window`](window) returned will be filtered based on its type. If unset the default filter is set to `['normal', 'panel', 'popup']`, with `'panel'` window types limited to the extension's own windows.

      **Note:** If supplied, the `windowTypes` component of `getInfo` is ignored. The use of `windowTypes` has been deprecated as of Firefox 62.

 
### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a [`windows.Window`](window) object containing the details of the last focused window. If any error occurs, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getLastFocused` | Yes | 14 | 45 | ? | Yes | 14 | ? | ? | No | ? | 15 | ? |
| `getInfo` | 18 | 14 | 45 | ? | 15 | 14 | ? | ? | No | ? | 15 | ? |


Examples
--------



Get the last focused window, and log the tabs it contains. Note that you'll need the "tabs" [permission](../../manifest.json/permissions) or matching [host permissions](../../manifest.json/permissions#host_permissions) to access tab URLs.

 
```
function logTabs(windowInfo) {
  for (const tabInfo of windowInfo.tabs) {
    console.log(tabInfo.url);
  }
}

function onError(error) {
  console.error(`Error: ${error}`);
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.windows.getLastFocused({ populate: true }).then(logTabs, onError);
});

```
  **Note:** This API is based on Chromium's [`chrome.windows`](https://developer.chrome.com/docs/extensions/reference/windows/#method-getLastFocused) API. This documentation is derived from [`windows.json`](https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/getLastFocused>

devtools.inspectedWindow.reload()
=================================


Reloads the window that the devtools are attached to.


Syntax
------



```
browser.devtools.inspectedWindow.reload(
  reloadOptions       // object
)

```
### Parameters


 
`reloadOptions` Optional
  `object`. Options for the function, as follows:

  
`ignoreCache` Optional
  `boolean`. If true, this makes the reload ignore the browser cache (as if the user had pressed Shift+Ctrl+R).

  
`userAgent` Optional
  `string`. Set a custom user agent for the page. The string supplied here will be sent in the browser's [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) header, and will be returned by calls to [`navigator.userAgent`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent) made by scripts running in the page.

  
`injectedScript` Optional
  `string`. Inject the given JavaScript expression into all frames in the page, before any other scripts.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `reload` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


Examples
--------



Reload the inspected window, setting the user agent and injecting a script:

 
```
const reloadButton = document.querySelector("#reload-button");

reloadButton.addEventListener("click", () => {
  browser.devtools.inspectedWindow.reload({
    injectedScript:"alert(navigator.userAgent);",
    userAgent: "Not a real UA"
  });
});

```
  **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow/reload>

devtools.network.getHAR()
=========================



Get a [HAR log](http://www.softwareishard.com/blog/har-12-spec/#log) for the page loaded in the current tab.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = browser.devtools.network.getHAR()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object containing the HAR log for the current tab. For details of what the log object contains, refer to the [HAR specification](http://www.softwareishard.com/blog/har-12-spec/#log).

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getHAR` | Yes | 79 | 60The returned HAR log will be empty unless the user has previously activated the browser's network panel at least once. | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Log the URLs of requests contained in the HAR log:

 
```
async function logRequests() {
  let harLog = await browser.devtools.network.getHAR();
  console.log(`HAR version: ${harLog.version}`);
  for (const entry of harLog.entries) {
    console.log(entry.request.url);
  }
}

logRequestsButton.addEventListener("click", logRequests);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.network`](https://developer.chrome.com/docs/extensions/reference/devtools_network/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/network/getHAR>

devtools.network.onNavigated
============================


Fired when the user navigates the inspected window to a new page.


Syntax
------




```
browser.devtools.network.onNavigated.addListener(listener)
browser.devtools.network.onNavigated.removeListener(listener)
browser.devtools.network.onNavigated.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `url`  `string`. The new URL for the window.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onNavigated` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


Examples
--------




```
function handleNavigated(url) {
  console.log(url);
}

browser.devtools.network.onNavigated.addListener(handleNavigated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/network/onNavigated>

StorageArea.getBytesInUse()
===========================



Gets the amount of storage space, in bytes, used one or more items being stored in the storage area.

  This function only exists in browser.storage.sync It does not exist in browser.storage.local See <https://bugzil.la/1385832> 

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
let gettingSpace = browser.storage.<storageType>.getBytesInUse(
  keys                      // null, string, or array of strings
)

```
 `<storageType>` can only be [`storage.sync`](../sync), not [`storage.local`](../local) because of [this bug](https://bugzil.la/1385832).


### Parameters


 `keys`  A key (string) or keys (an array of strings) to identify the item(s) whose storage space you want to retrieve. If an empty array is passed in, 0 will be returned. If you pass `null` or `undefined` here, the function will return the space used by the entire storage area.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an integer, `bytesUsed`, representing the storage space used by the objects that were specified in `keys`. If the operation failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `getBytesInUse` | Yes | 14 | 78Only supported by the `sync` storage area. | ? | 33 | 14 | ? | ? | No | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/getBytesInUse>

storage.StorageArea.onChanged
=============================


Fires when one or more items in a storage area change. Compared to [`storage.onChanged`](../onchanged), this event enables you to listen for changes in one of the storage areas: `local`, `managed`, `session`, and `sync`.


Syntax
------




```
// local can also be sync, managed, or session
browser.storage.local.onChanged.addListener(callback)
browser.storage.local.onChanged.removeListener(listener)
browser.storage.local.onChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stops listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  The function called when this event occurs. The function is passed these arguments:

  `changes`  `object`. Object describing the change. This contains one property for each key that changed. The name of the property is the name of the key that changed, and its value is a [`storage.StorageChange`](../storagechange) object describing the change to that item.

    Examples
--------



```
/\*
Log the old value and its new value of
changes in the local storage.
\*/
function logStorageChange(changes) {

  const changedItems = Object.keys(changes);

  for (const item of changedItems) {
    console.log(`${item} has changed:`);
    console.log("Old value: ", changes[item].oldValue);
    console.log("New value: ", changes[item].newValue);
  }
}

browser.storage.local.onChanged.addListener(logStorageChange);

```
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChanged` | 73 | Yes | 101 | ? | Yes | 14 | ? | ? | 101 | ? | 15 | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/#event-StorageArea-onChanged) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/onChanged>

devtools.network.onRequestFinished
==================================



Fired when a network request has finished and its details are available to the extension.

 The request is given as a [HAR entry object](http://www.softwareishard.com/blog/har-12-spec/#entries), which is also given an asynchronous `getContent()` method that gets the response body content.

 Note that although your extension can add a listener at any time, it will only start firing after the user has activated the browser's [network panel](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/index.html) at least once.



Syntax
------




```
browser.devtools.network.onRequestFinished.addListener(listener)
browser.devtools.network.onRequestFinished.removeListener(listener)
browser.devtools.network.onRequestFinished.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `request`  `object`. An object representing the request. This object is a single [HAR entry](http://www.softwareishard.com/blog/har-12-spec/#entries) object. It also defines an asynchronous `getContent()` method, which returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with an array of two elements. The first element is the HTTP response body as a string, while the second element is the [MIME type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the HTTP response also as a string.

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onRequestFinished` | Yes | 79 | 6160–61This event will only start firing after the user has activated the browser's network panel at least once. | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Add a listener that logs the server IP address and response body for every network request.

 
```
function handleRequestFinished(request) {
  console.log("Server IP: ", request.serverIPAddress);
  request.getContent().then(([content, mimeType]) => {
    console.log("Content: ", content);
    console.log("MIME type: ", mimeType);
  });
}

browser.devtools.network.onRequestFinished.addListener(handleRequestFinished);

```
  **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/network/onRequestFinished>

StorageArea.get()
=================



Retrieves one or more items from the storage area.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
let results = browser.storage.<storageType>.get(
  keys    // null, string, object or array of strings
)

```
 `<storageType>` will be one of the writable storage types — [`sync`](../sync), [`local`](../local), or [`managed`](../managed).


### Parameters


 `keys`  A key (`string`) or keys (an array of strings, *or* an object specifying default values) to identify the item(s) to be retrieved from storage. If you pass an empty object or array here, an empty object will be retrieved. If you pass `null`, or an undefined value, the entire storage contents will be retrieved.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to a `results` object, containing every object in `keys` that was found in the storage area. If `keys` is an object, keys that are not found in the storage area will have their values given by the `keys` object.

 If the operation failed, the promise is rejected with an error message.

 If managed storage is not set, `undefined` will be returned.

  **Warning:** When used within a content script in Firefox versions prior to 52, the Promise returned by `browser.storage.local.get()` is fulfilled with an Array containing one Object. The Object in the Array contains the `keys` found in the storage area, as described above.

 The Promise is correctly fulfilled with an Object when used in the background context (background scripts, popups, options pages, etc.).

 When this API is used as `chrome.storage.local.get()`, it correctly passes an Object to the callback function.

 
Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `get` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `empty_key` | Yes | 14 | 45 | ? | 33 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



Suppose storage contains two items:

 
```
// storage contains two items,
// "kitten" and "monster"
browser.storage.local.set({
  kitten:  {name:"Mog", eats:"mice"},
  monster: {name:"Kraken", eats:"people"}
});

```
 Define success and failure handlers for the promise:

 
```
function onGot(item) {
  console.log(item);
}

function onError(error) {
  console.log(`Error: ${error}`);
}

```
 With no `keys` argument, retrieve everything:

 
```
let gettingItem = browser.storage.local.get();
gettingItem.then(onGot, onError);

// -> Object { kitten: Object, monster: Object }

```
 With an empty `keys` argument, return nothing:

 
```
// with an empty array, retrieve nothing
let gettingItem = browser.storage.local.get([]);
gettingItem.then(onGot, onError);

// -> Object { }

```
 With the name of an object, retrieve the match:

 
```
let gettingItem = browser.storage.local.get("kitten");
gettingItem.then(onGot, onError);

// -> Object { kitten: Object }

```
 With an array of object names, retrieve all matches:

 
```
let gettingItem = browser.storage.local.get(["kitten", "monster", "grapefruit"]);
gettingItem.then(onGot, onError);

// -> Object { kitten: Object, monster: Object }

```
 With an object with object names as keys and the default value as value:

 
```
let gettingItem = browser.storage.local.get({
  kitten: "no kitten",
  monster: "no monster",
  grapefruit: {
    name: "Grape Fruit",
    eats: "Water"
  }
});

// -> Object { kitten: Object, monster: Object, grapefruit: Object }

```

### Chrome examples




```
chrome.storage.local.get("kitten", (items) => {
  console.log(items.kitten);  // -> {name:"Mog", eats:"mice"}
});

```
 Or with an arrow function

 
```
chrome.storage.local.get("kitten", (items) => {
  console.log(items.kitten); // -> {name:"Mog", eats:"mice"}
});

```
 Or using a Promise

 
```
let gettingItem = new Promise((resolve) => chrome.storage.local.get("kitten", resolve));
gettingItem.then(onGot); // -> Object { kitten: Object }

```
  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/get>

devtools.panels.ExtensionPanel
==============================


An `ExtensionPanel` represents a panel added to the devtools. It's the resolution of the [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) returned by [`browser.devtools.panels.create()`](create).


Type
----



Values of this type are objects. The define two events, `onShown` and `onHidden`.

 * `onShown` is emitted when the panel is shown in the devtools (for example, because the user clicked on the panel's tab in the devtools window).
* `onHidden` is emitted when the panel is hidden (for example, because the user switched to a different tab in the devtools window).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHidden` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |
| `onSearch` | Yes | 79 | No | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onShown` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


Examples
--------



This code creates a new panel, then adds handlers for its `onShown` and `onHidden` events.

 
```
function handleShown(e) {
  console.log(e);
  console.log("panel is being shown");
}

function handleHidden(e) {
  console.log(e);
  console.log("panel is being hidden");
}

browser.devtools.panels.create(
  "My Panel",                 // title
  "icons/star.png",           // icon
  "devtools/panel/panel.html" // content
).then((newPanel) => {
  newPanel.onShown.addListener(handleShown);
  newPanel.onHidden.addListener(handleHidden);
});

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionPanel>

devtools.panels.ExtensionSidebarPane
====================================



The `ExtensionSidebarPane` object represents a pane that an extension has added to the sidebar in the browser's HTML/CSS inspector.

  ![new pane titled "My pane" that displays a JSON object] 

 To create an `ExtensionSidebarPane`, call the [`browser.devtools.panels.elements.createSidebarPane()`](elementspanel/createsidebarpane) function.



Functions
---------


 [`devtools.panels.ExtensionSidebarPane.setExpression()`](extensionsidebarpane/setexpression)  Evaluate a JavaScript expression in the web page that the inspector is inspecting. The result is displayed in the sidebar pane.

  [`devtools.panels.ExtensionSidebarPane.setObject()`](extensionsidebarpane/setobject)  Sets a JSON object that will be displayed in the sidebar pane.

  [`devtools.panels.ExtensionSidebarPane.setPage()`](extensionsidebarpane/setpage)  Loads the page pointed to by the supplied URL.

  Events
------


 [`devtools.panels.ExtensionSidebarPane.onShown`](extensionsidebarpane/onshown)  Fired when the sidebar pane is shown.

  [`devtools.panels.ExtensionSidebarPane.onHidden`](extensionsidebarpane/onhidden)  Fired when the sidebar pane is hidden.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHidden` | Yes | 79 | 57This event is only fired when the user switches between sidebar panes, not when the user switches between devtools panels. See [bug 1412317](https://bugzil.la/1412317). | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onShown` | Yes | 79 | 57This event is only fired when the user switches between sidebar panes, not when the user switches between devtools panels. See [bug 1412317](https://bugzil.la/1412317). | ? | Yes | No | ? | ? | No | ? | No | ? |
| `setExpression` | YesThe expression must evaluate to a JavaScript object or a DOM node, or nothing is shown in the sidebar. | 79The expression must evaluate to a JavaScript object or a DOM node, or nothing is shown in the sidebar. | 57The expression must evaluate to an object that can be serialized to JSON, or nothing is shown in the sidebar. In particular, JavaScript cyclic objects and DOM nodes are not supported. See [bug 1403130](https://bugzil.la/1403130). | ? | Yes | No | ? | ? | No | ? | No | ? |
| `setObject` | YesIf the `jsonObject` parameter is a string, it is not displayed. | 79If the `jsonObject` parameter is a string, it is not displayed. | 57If the `jsonObject` is a string, then `rootTitle` must also be given, or `jsonObject` will not be displayed. See [bug 1412310](https://bugzil.la/1412310). | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane>

devtools.panels.elements
========================


An [`ElementsPanel`](elementspanel) object, which represents the browser's HTML/CSS inspector.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `elements` | Yes | 79 | 56 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/elements>

devtools.panels.themeName
=========================



The name of the currently selected devtools theme.

 This is a string whose possible values are:

 * "light"
* "dark"
* "firebug"



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `themeName` | 59 | 79 | 55 | ? | 41 | 16 | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/themeName>

devtools.panels.create()
========================



Adds a new panel to the devtools.

 This function takes: a title, a URL to an icon file, and a URL to an HTML file. It creates a new panel in the devtools, whose content is specified by the HTML file. It returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to an [`ExtensionPanel`](extensionpanel) object representing the new panel.



Syntax
------



```
let creating = browser.devtools.panels.create(
  title,       // string
  iconPath,    // string
  pagePath     // string
)

```
### Parameters


 `title`  `string`. The panel's title. This will appear in the row of tabs along the top of the devtools window, and is the main way the user will be able to identify your panel.

  `iconPath`  `string`. Specifies an icon which will be shown next to the title. It's provided as a URL to an image file that's been bundled with your extension. The URL is resolved as relative to the current extension page (unless expressed as an absolute URL, e.g. "/icons/panel.png").

  `pagePath`  string. Specifies an HTML file that defines the actual content of the panel. It's provided as a URL to an HTML file that's been bundled with your extension. The URL is resolved as relative to the current extension page (unless expressed as an absolute URL, e.g. "/devtools/panel.html"). The HTML file may include CSS and JavaScript files, just like a normal web page. The JavaScript running in the panel will be able to use the devtools APIs. See [Extending the developer tools](../../../extending_the_developer_tools).

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [`ExtensionPanel`](extensionpanel) object representing the new panel.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `create` | Yes | 79 | 54 | ? | Yes | 16 | ? | ? | No | ? | No | ? |


Examples
--------



Create a new panel, and add listeners to its onShown and onHidden events:

 
```
function handleShown() {
  console.log("panel is being shown");
}

function handleHidden() {
  console.log("panel is being hidden");
}

browser.devtools.panels.create(
  "My Panel",                 // title
  "/icons/star.png",           // icon
  "/devtools/panel/panel.html" // content
).then((newPanel) => {
  newPanel.onShown.addListener(handleShown);
  newPanel.onHidden.addListener(handleHidden);
});

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/create>

StorageArea.remove()
====================



Removes one or more items from the storage area.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
let removingItem = browser.storage.<storageType>.remove(
  keys             // string, or array of strings
)

```
 `<storageType>` will be one of the writable storage types — [`storage.sync`](../sync) or [`storage.local`](../local).


### Parameters


 `keys`  A string, or array of strings, representing the key(s) of the item(s) to be removed.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if the operation succeeded. If the operation failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `remove` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |
| `empty_key` | Yes | 14 | 45 | ? | 33 | No | ? | ? | 48 | ? | No | ? |


Examples
--------



Remove a single item:

 
```
function onRemoved() {
  console.log("OK");
}

function onError(e) {
  console.log(e);
}

let removeKitten = browser.storage.sync.remove("kitten");
removeKitten.then(onRemoved, onError);

```
  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/remove>

devtools.panels.ElementsPanel
=============================


An `ElementsPanel` represents the HTML/CSS inspector in the browser's devtools. This is called the Page Inspector in Firefox and the Elements panel in Chrome.


Functions
---------


 [`devtools.panels.ElementsPanel.createSidebarPane()`](elementspanel/createsidebarpane)  Creates a pane in the inspector's sidebar.

  Events
------


 [`devtools.panels.ElementsPanel.onSelectionChanged`](elementspanel/onselectionchanged)  Fired when the user selects a different element in the page, for example using the "Inspect element" context menu item.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `createSidebarPane` | Yes | 79 | 57 | ? | Yes | No | ? | ? | No | ? | No | ? |
| `onSelectionChanged` | Yes | 79 | 56 | ? | Yes | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.devtools`](https://developer.chrome.com/docs/extensions/mv3/devtools/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ElementsPanel>

devtools.panels.onThemeChanged
==============================


Fired when the devtools theme changes.


Syntax
------




```
browser.devtools.panels.onThemeChanged.addListener(listener)
browser.devtools.panels.onThemeChanged.removeListener(listener)
browser.devtools.panels.onThemeChanged.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed the following arguments:

  `themeName`  `string`. Name of the new theme: this will be one of the permitted values for [`devtools.panels.themeName`](themename).

    Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onThemeChanged` | No | No | 55 | ? | No | 16 | ? | ? | No | ? | No | ? |


Examples
--------




```
browser.devtools.panels.onThemeChanged.addListener((newThemeName) => {
  console.log(`New theme: ${newThemeName}`);
});

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/onThemeChanged>

StorageArea.set()
=================



Stores one or more items in the storage area, or update existing items.

 When you store or update a value using this API, the [`storage.onChanged`](../onchanged) event will fire.

 Note that when storing items in the [`sync`](../sync) storage area, the browser enforces quotas on the amount of data each extension can store. See [Storage quotas for sync data](../sync#storage_quotas_for_sync_data).

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
let settingItem = browser.storage.<storageType>.set(
  keys             // object
)

```
 `<storageType>` will be one of the writable storage types — [`storage.sync`](../sync) or [`storage.local`](../local).


### Parameters


 `keys`  An object containing one or more key/value pairs to be stored in storage. If an item already exists, its value will be updated.

 Values can be [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) (such as a number, boolean, or string), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array), or [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) types.

 It's generally not possible to store other types, such as `Function`, `Date`, `RegExp`, `Set`, `Map`, `ArrayBuffer`, and so on. Some of these unsupported types will restore as an empty object, and some cause `set()` to throw an error. The exact behavior here is browser-specific.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if the operation succeeded. If the operation failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `set` | Yes | 14storage is limited to 1MB per value. | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------




```
function setItem() {
  console.log("OK");
}

function gotKitten(item) {
  console.log(`${item.kitten.name} has ${item.kitten.eyeCount} eyes`);
}

function gotMonster(item) {
  console.log(`${item.monster.name} has ${item.monster.eyeCount} eyes`);
}

function onError(error) {
  console.log(error)
}

// define 2 objects
let monster = {
  name: "Kraken",
  tentacles: true,
  eyeCount: 10
}

let kitten = {
  name: "Moggy",
  tentacles: false,
  eyeCount: 2
}

// store the objects
browser.storage.local.set({kitten, monster})
  .then(setItem, onError);

browser.storage.local.get("kitten")
  .then(gotKitten, onError);
browser.storage.local.get("monster")
  .then(gotMonster, onError);

```
  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/set>

StorageArea.clear()
===================



Removes all items from the storage area.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
let clearing = browser.storage.<storageType>.clear()

```
 `<storageType>` will be one of the writable storage types — [`storage.sync`](../sync) or [`storage.local`](../local).


### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments if the operation succeeded. If the operation failed, the promise will be rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `clear` | Yes | 14 | 45 | ? | 33 | 14 | ? | ? | 48 | ? | 15 | ? |


Examples
--------




```
function onCleared() {
  console.log("OK");
}

function onError(e) {
  console.log(e);
}

let clearStorage = browser.storage.local.clear();
clearStorage.then(onCleared, onError);

```
  **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/clear>

User actions
============



Some WebExtension APIs perform functions that are generally performed as a result of a user action. For example:

 * a browser action with a popup will display the popup when the user clicks it, but there's also a [`browserAction.openPopup`](api/browseraction/openpopup) API enabling an extension to open the popup programmatically.
* if an extension adds a sidebar, it is typically opened by the user via some part of the browser's built-in user interface, such as the View/Sidebar menu. But there's also a [`sidebarAction.open`](api/sidebaraction/open) API enabling an extension to open their sidebar programmatically.

 To follow the principle of "no surprises", APIs like this can only be called from inside the handler for a user action. User actions include the following:

 * Clicking the extension's browser action or page action.
* Selecting a context menu item defined by the extension.
* Activating a keyboard shortcut defined by the extension (this only treated as a user action from Firefox 63 onwards).
* Clicking a button in a page bundled with the extension.

 For example:

 
```
function handleClick() {
  browser.sidebarAction.open();
}

browser.browserAction.onClicked.addListener(handleClick);

```
 Note that user actions in normal web pages are not treated as user actions for this purpose. For example, if a user clicks a button in a normal web page, and a content script has added a click handler for that button and in that handler sends a message to the extension's background page, then the background page message handler is not considered to be handling a user action.

 Also, if a user input handler waits on a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then its status as a user input handler is lost. For example:

 
```
async function handleClick() {
  let result = await someAsyncFunction();

  // this will fail, because the handler lost its "user action handler" status
  browser.sidebarAction.open();
}

browser.browserAction.onClicked.addListener(handleClick);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/User_actions>

runtime.PlatformNaclArch
========================


The native client architecture. This may be different from arch on some platforms.


Type
----


Values of this type are strings. Possible values are: `"arm"`, `"x86-32"`, `"x86-64"`.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `PlatformNaclArch` | Yes | 79 | 45 | ? | Yes | No | ? | ? | 48 | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformNaclArch) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/PlatformNaclArch>

get()
=====



The `BrowserSetting.get()` method gets the current value of the browser setting, and an enumeration indicating how the setting's value is currently controlled.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let getting = setting.get(
  details     // object
)

```
### Parameters


 `details`  An empty object.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an object with the following properties:

  `value`  The value of the setting. The type of this property is determined by the particular setting.

  `levelOfControl`  `string`. This represents the way the setting is currently controlled. You can use it to check whether you can modify the setting. See [`BrowserSetting.set()`](set) for details. Its value may be any of the following:

 

|  |  |
| --- | --- |
| `"not_controllable"` | Extensions are not allowed to modify this setting. |
| `"controlled_by_other_extensions"` |  Another extension that was installed after this one has modified this setting.  |
| `"controllable_by_this_extension"` | This extension is allowed to modify the setting. |
| `"controlled_by_this_extension"` | This extension has already modified the setting. |

  
Browser compatibility
---------------------

Example
-------



Log the value and level of control for the `networkPredictionEnabled` property of the [`privacy.network`](../../privacy/network) object, for private browsing windows. Note that this requires the "privacy" browser permission.

 
```
let getting = browser.privacy.network.networkPredictionEnabled.get({});

getting.then((got) => {
  console.log(`Value: ${got.value}`);
  console.log(`Control: ${got.levelOfControl}`);
});

```
  **Note:**

 This API is based on Chromium's [`chrome.types`](https://developer.chrome.com/docs/extensions/reference/types/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting/get>

BrowserSetting.onChange
=======================



The `BrowserSetting.onChange` event is fired when the setting is changed.

 On Firefox, it doesn't fire if the change has been made through `about:config`.



Syntax
------




```
BrowserSetting.onChange.addListener(listener)
BrowserSetting.onChange.removeListener(listener)
BrowserSetting.onChange.hasListener(listener)

```
 Events have three functions:

  `addListener(listener)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  A callback function that will be called when this event occurs. The function will be passed the following arguments:

  `details`  An `object` containing details of the change that occurred. Its properties are as follows:

  `value`  The new value of the setting. The type of this property is determined by the particular setting.

  `levelOfControl`  `string`. This represents the way the setting is currently controlled. You can use it to check whether you can modify the setting. See [`BrowserSetting.set()`](set) for details. Its value may be any of the following:

 

|  |  |
| --- | --- |
| `"not_controllable"` | Extensions are not allowed to modify this setting. |
| `"controlled_by_other_extensions"` |  Another extension that was installed after this one has modified this setting.  |
| `"controllable_by_this_extension"` | This extension is allowed to modify the setting. |
| `controlled_by_this_extension"` | This extension has already modified the setting. |

      Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onChange` | Yes | 79 | 72 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------


 **Note:** This API is based on Chromium's [`chrome.types`](https://developer.chrome.com/docs/extensions/reference/types/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting/onChange>

webRequest.StreamFilter.ondata
==============================



An event handler that is called repeatedly when response data is available. The handler is passed an `event` object containing a `data` property, which includes a chunk of the response data as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).

 To decode the data, use either [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) or [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).

 Without an `ondata` listener, you don't receive the original response body, and the output stream is empty unless [`write`](write) is called.



Examples
--------



This example adds an `ondata` listener which replaces "Example" in the response with "WebExtension Example" using the [`replaceAll()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll) method.

  **Note:** This example only works for occurrences of "Example" that are entirely contained within a data chunk, and not ones that straddle two chunks (which might happen ~0.1% of the time for large documents). Additionally it only deals with UTF-8-coded documents. A real implementation of this would have to be more complex.

  
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  filter.ondata = (event) => {
    let str = decoder.decode(event.data, { stream: true });
    // Just change any instance of Example in the HTTP response
    // to WebExtension Example.
    // Note that this will maybe not work as expected because the ending of the str can also 
    // be "<h1>Examp" (because it is not the full response). So, it is better
    // to get the full response first and then doing the replace.
    str = str.replaceAll("Example", "WebExtension Example");
    filter.write(encoder.encode(str));
    // Doing filter.disconnect(); here would make us process only
    // the first chunk, and let the rest through unchanged. Note
    // that this would break multi-byte characters that occur on
    // the chunk boundary!
  };

  filter.onstop = (event) => {
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/\*"], types: ["main\_frame"] },
  ["blocking"]
);

```
 Another example for handling large documents:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = (event) => {
    let str = "";
    if (data.length === 1) {
      str = decoder.decode(data[0]);
    } else {
      for (let i = 0; i < data.length; i++) {
        let stream = i !== data.length - 1;
        str += decoder.decode(data[i], { stream });
      }
    }
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 Here's another version:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = (event) => {
    let str = "";
    for (const buffer of data) {
      str += decoder.decode(buffer, { stream: true });
    }
    str += decoder.decode(); // end-of-stream

    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 The above example can also be written like so:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(decoder.decode(event.data, { stream: true }));
  };

  filter.onstop = (event) => {
    data.push(decoder.decode());

    let str = data.join("");
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 This example uses a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob):

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = async (event) => {
    const blob = new Blob(data, { type: "text/html" });
    let str = await blob.text();
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 This example makes use of the [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) interface:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const encoder = new TextEncoder();
  const parser = new DOMParser();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = async (event) => {
    const blob = new Blob(data, { type: "text/html" });
    const str = await blob.text();
    const doc = parser.parseFromString(str, blob.type);
    const nodes = doc.querySelectorAll("title, h1");
    for (const node of nodes) {
      node.innerText = node.innerText.replaceAll("Example", "WebExtension $&");
    }
    filter.write(encoder.encode(doc.documentElement.outerHTML));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 This example combines all buffers into a single buffer:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(new Uint8Array(event.data));
  };

  filter.onstop = (event) => {
    let combinedLength = 0;
    for (const buffer of data) {
      combinedLength += buffer.length;
    }
    const combinedArray = new Uint8Array(combinedLength);
    let writeOffset = 0;
    for (const buffer of data) {
      combinedArray.set(buffer, writeOffset);
      writeOffset += buffer.length;
    }
    let str = decoder.decode(combinedArray);
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 The above example can also be written like so:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const decoder = new TextDecoder("utf-8");
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = async (event) => {
    const blob = new Blob(data, { type: "text/html" });
    const buffer = await blob.arrayBuffer();
    let str = decoder.decode(buffer);
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```
 This example demonstrates, how one can detect, if it's the final chunk in the response:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const encoder = new TextEncoder();
  const decoder = new TextDecoder("utf-8");

  let str = "";
  filter.ondata = (event) => {
    let stream = true;
    const data = new Uint8Array(event.data.slice(-8, -1));
    if (String.fromCharCode(...data) === "</html>") {
      stream = false; // end-of-stream
    }
    str += decoder.decode(event.data, { stream });
  };

  filter.onstop = (event) => {
    str = str.replaceAll("Example", "WebExtension $&");
    filter.write(encoder.encode(str));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `ondata` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/ondata>

RegisteredUserScript.unregister()
=================================



The `unregister()` method of the [`RegisteredUserScript`](../registereduserscript) object unregisters the user scripts represented by the object, user scripts that were registered using [`userScripts.register()`](../register).

  **Note:** User Scripts are automatically unregistered when the related extension page (from which the user scripts were registered) is unloaded, so you should register a user script from an extension page that persists at least as long as you want the user scripts to stay registered.

 

Syntax
------



```
const registeredUserScript = await browser.userScripts.register(
  userScriptOptions       // object
);
// …
await registeredUserScript.unregister()

```
### Parameters


None.

### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is resolved once the user scripts are unregistered. The promise does not return a value.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `unregister` | No | No | 68 | ? | No | No | ? | ? | 68 | ? | No | ? |


See also
--------


* [`userScripts.register()`](../register)
* [`RegisteredUserScript`](../registereduserscript)


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/unregister>

StorageArea.setAccessLevel()
============================



Sets the access level for the storage area.

 This method is only supported for the `storage.session` StorageArea.

 Unlike other storage areas, `storage.session` is only available to privileged (trusted) extension contexts. This `setAccessLevel` method is used to expose the session storage area to content scripts too. By default, all other storage areas are exposed to all extension contexts, including content scripts.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------




```
await browser.storage.<storageType>.setAccessLevel(
  accessLevel             // string
)

```
 `<storageType>` can be the [`storage.session`](../session) storage type.


### Parameters


 `accessLevel`  `String`. The access level of the storage area. Possible values are `TRUSTED_CONTEXTS` or `TRUSTED_AND_UNTRUSTED_CONTEXTS`.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that is fulfilled with no arguments if the operation succeeded. If the operation failed, the promise is rejected with an error message.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setAccessLevel` | 96Only supported for the session storage area. | 96Only supported for the session storage area. | No | ? | 82Only supported for the session storage area. | No | ? | ? | No | ? | No | ? |


 **Note:** This API is based on Chromium's [`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/storage/) API. This documentation is derived from [`storage.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json) in the Chromium code.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/setAccessLevel>

clear()
=======



Use `BrowserSetting.clear()` to clear any changes the extension has made to the browser setting. The browser setting will revert to its previous value.

 The extension will also give up control of the setting, allowing an extension with lower precedence (that is, an extension that was installed before this one) to modify the setting. See [`BrowserSetting.set()`](set) to learn more about controlling settings.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). If clearing the value failed, the promise resolves to `false`. If clearing the value succeeded it resolves to `true`.



Syntax
------



```
let clearing = setting.clear(
  details     // object
)

```
### Parameters


 `details`  An empty object.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with a `boolean`: `true` if the setting was cleared, `false` otherwise.

Browser compatibility
---------------------

Example
-------



Clear the `webRTCIPHandlingPolicy` setting:

 
```
function onCleared(result) {
  if (result) {
    console.log("Setting was cleared");
  } else {
    console.log("Setting was not cleared");
  }
}

let clearing = browser.privacy.network.webRTCIPHandlingPolicy.clear({});
clearing.then(onCleared);

```
  **Note:**

 This API is based on Chromium's [`chrome.types`](https://developer.chrome.com/docs/extensions/reference/types/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting/clear>

contentScripts.RegisteredContentScript.unregister()
===================================================


Unregisters the content scripts represented by this `RegisteredContentScript` object.


Syntax
------



```
registered.unregister()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `unregister` | No | No | 59 | ? | No | No | ? | ? | 59 | ? | No | ? |


Examples
--------



This code toggles a registered content script on a browser action click:

 
```
let registered = null;

async function register() {

  registered = await browser.contentScripts.register({
    matches: ["\*://\*.org/\*"],
    js: [{
      code: "document.body.innerHTML = '<h1>This page has been eaten<h1>'"
    }],
    runAt: "document\_idle"
  });

}

function toggle() {
  if (registered) {
    registered.unregister();
    registered = null;
  } else {
    register();
  }
}

browser.browserAction.onClicked.addListener(toggle);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts/RegisteredContentScript/unregister>

webRequest.StreamFilter.write()
===============================



Writes some response data to the output stream.

 You can only call this function after the [`onstart`](onstart) event has fired.



Syntax
------



```
filter.write(
  data    // ArrayBuffer or Uint8Array
)

```
### Parameters


 `data`  [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer): array of bytes containing the data to pass to the browser's rendering engine.

  ### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `write` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example uses `write()`, to replace "Example" in the first chunk of the response with "WebExtension Example".

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);
  let decoder = new TextDecoder("utf-8");
  let encoder = new TextEncoder();

  filter.ondata = (event) => {
    let str = decoder.decode(event.data, {stream: true});
    // Just change any instance of Example in the HTTP response
    // to WebExtension Example.
    str = str.replace(/Example/g, 'WebExtension Example');
    filter.write(encoder.encode(str));
    filter.disconnect();
  }

  //return {}; // not needed
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.com/\*"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/write>

webRequest.StreamFilter.disconnect()
====================================



Disconnects the filter from the request. After this, the browser will continue to process the response, but no more filter events will fire, and no more filter function calls will have any effect. Note the difference between this function and [`close()`](close). With `disconnect()`, the browser will continue to process any further response data, but it won't be accessible through the filter. With `close()`, the browser will ignore any response data that hasn't already been passed through to the rendering engine.

 You should always call `disconnect()` or `close()` once you don't need to interact with the response any further.

 You can't call this function until after the [`onstart`](onstart) event has fired.



Syntax
------



```
filter.disconnect()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `disconnect` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example will prepend "preface text" to the response body. It then disconnects, so the original response body will load normally:

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    console.log("started");
    let encoder = new TextEncoder();
    filter.write(encoder.encode("preface text"));
    filter.disconnect();
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/disconnect>

webRequest.StreamFilter.onstart
===============================


An event handler that will be called when the stream is opened and is about to begin delivering data. From this point on, the extension may use filter functions like [`write()`](write), [`disconnect()`](disconnect), or [`close()`](close).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onstart` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example will replace the page content with "replacement text":

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    console.log("started");
    let encoder = new TextEncoder();
    filter.write(encoder.encode("replacement content"));
    filter.close();
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/onstart>

webRequest.StreamFilter.onstop
==============================


An event handler that will be called when the stream has no more data to deliver. In the event handler you can still call filter functions such as [`write()`](write), [`disconnect()`](disconnect), or [`close()`](close).


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onstop` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example will append "extra stuff" to the response:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const encoder = new TextEncoder();

  filter.ondata = (event) => {
    // pass through all the response data
    filter.write(event.data);
  };

  filter.onstop = (event) => {
    filter.write(encoder.encode("extra stuff"));
    filter.disconnect();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/\*"], types: ["main\_frame"] },
  ["blocking"]
);

```
 Here's another version of the example above:

 
```
function listener(details) {
  const filter = browser.webRequest.filterResponseData(details.requestId);
  const encoder = new TextEncoder();

  const data = [];
  filter.ondata = (event) => {
    data.push(event.data);
  };

  filter.onstop = (event) => {
    for (const buffer of data) {
      filter.write(buffer);
    }
    filter.write(encoder.encode("extra stuff"));
    filter.close();
  };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: ["https://example.com/"], types: ["main\_frame"] },
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/onstop>

webRequest.StreamFilter.onerror
===============================



An event handler that will be called when an error occurs. This is most often because an invalid request ID was passed into [`webRequest.filterResponseData()`](../filterresponsedata).

 After this event is fired, the [`webRequest.StreamFilter.error`](error) property will contain a message giving more information about the error.

 Note that this event is **not** triggered for network errors.



Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onerror` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example adds an `onerror` listener which logs the value of [`webRequest.StreamFilter.error`](error).

 
```
function listener(details) {
  // This example seems not useful because,
  // an extension would use "details.requestId"
  let filter = browser.webRequest.filterResponseData("12345");

  filter.onerror = (event) => {
    console.log(`Error: ${filter.error}`);
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["<all\_urls>"], types: ["main\_frame"]},
  ["blocking"]
);

```
 This example uses no `"blocking"`.

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onerror = (event) => {
    console.log(`Error: ${filter.error}`); // Error: Invalid request ID
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["<all\_urls>"], types: ["main\_frame"]}
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/onerror>

webRequest.StreamFilter.close()
===============================



Closes the request. After this is called, no further response data will be passed to the browser's rendering engine and no more filter events will be given to the extension.

 Note the difference between this function and [`disconnect()`](disconnect). With `disconnect()`, the browser will continue to process any further response data, but it won't be accessible through the filter. With `close()`, the browser will ignore any response data that hasn't already been passed through to the rendering engine.

 You should always call `close()` or `disconnect()` once you don't need to interact with the response any further.

 You can't call this function until after the [`onstart`](onstart) event has fired.



Syntax
------



```
filter.close()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `close` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example will replace the page content with "replacement text":

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    console.log("started");
    let encoder = new TextEncoder();
    filter.write(encoder.encode("replacement content"));
    filter.close();
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/close>

webRequest.StreamFilter.suspend()
=================================



Suspends a request. After this is called, no more data will be delivered until the request is resumed with a call to [`resume()`](resume).

 You can't call this function until after the [`onstart`](onstart) event has fired.



Syntax
------



```
filter.suspend()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `suspend` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example uses suspend/resume to delay a web request.

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    filter.suspend();

    setTimeout(() => {
      filter.resume();
      filter.disconnect();
    }, 1000);

  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/suspend>

webRequest.StreamFilter.error
=============================


A string that will contain an error message after the [`onerror`](onerror) event has fired.


Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `error` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example adds an [`onerror`](onerror) listener which logs the value of `error`.

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData("12345");

  filter.onerror = (event) => {
    console.log(`Error: ${filter.error}`);
  }

  //return {}; // not needed
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["<all\_urls>"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/error>

webRequest.StreamFilter.status
==============================



A string that describes the current status of the request. It will be one of the following values:

  `"uninitialized"`  The filter is not fully initialized. No filter functions may be called.

  `"transferringdata"`  The underlying channel is currently transferring data, which will be routed to the extension in one or more [`ondata`](ondata) events. The extension can call filter functions such as [`write()`](write), [`close()`](close), or [`disconnect()`](disconnect).

  `"finishedtransferringdata"`  The underlying channel has finished transferring data. In this state the extension can still write response data using the filter's [`write()`](write) function.

  `"suspended"`  Data transfer is currently suspended. In this state the extension can resume the request by calling the filter's [`resume()`](resume) function, and can write response data using the filter's [`write()`](write) function.

  `"closed"`  The extension has closed the request by calling the filter's [`close()`](close) function. The filter will not fire any more events, and the extension may not call any filter functions.

  `"disconnected"`  The extension has disconnected the filter from the request by calling the filter's [`disconnect()`](disconnect) function. All further data will be delivered directly, without passing through the filter. The filter will not fire any more events, and the extension may not call any filter functions.

  `"failed"`  An error has occurred and the filter has been disconnected from the request. The extension can find an error message in [`error`](error), and may not call any filter functions.

  

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `status` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);
  console.log(filter.status);          // uninitialized

  filter.onstart = (event) => {
    console.log(filter.status);        // transferringdata
  }

  filter.ondata = (event) => {
    console.log(filter.status);        // transferringdata
    // pass through the response data
    filter.write(event.data);
  }

  filter.onstop = (event) => {
    console.log(filter.status);        // finishedtransferringdata
    filter.disconnect();
    console.log(filter.status);        // disconnected
  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.com/\*"], types: ["main\_frame"]},
  ["blocking"]
);

```


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/status>

devtools.panels.ElementsPanel.createSidebarPane()
=================================================



Adds a new pane to the sidebar in the HTML/CSS inspector.

 The HTML/CSS inspector, called the [Page Inspector](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/index.html) in Firefox and the [Elements panel](https://developer.chrome.com/docs/devtools/css/) in Chrome, displays the page DOM in the main part of its window, and has a sidebar that displays various other aspects of the page HTML/CSS in a tabbed interface. For example, in Firefox, the sidebar can display the CSS rules for the selected element, or its fonts, or its box model.

 The `createSidebarPane()` function adds a new pane to the sidebar. For example, the screenshot below shows a new pane titled "My pane", that displays a JSON object:

  ![Image showing a new pane titled "My pane", that displays a JSON object] 

 This function takes one argument, which is a string representing the pane's title. It returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to an [`ExtensionSidebarPane`](../extensionsidebarpane) object representing the new pane. You can use that object to define the pane's content and behavior.



Syntax
------



```
let creating = browser.devtools.panels.elements.createSidebarPane(
  title       // string
)

```
### Parameters


 `title`  `string`. The pane's title. This will appear in the row of tabs along the top of the sidebar, and is the main way the user will be able to identify your pane.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with an [`ExtensionSidebarPane`](../extensionsidebarpane) object representing the new pane.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `createSidebarPane` | Yes | 79 | 57 | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Create a new pane, and populate it with a JSON object. You could run this code in a script loaded by your extension's [devtools page](../../../../manifest.json/devtools_page).

 
```
function onCreated(sidebarPane) {
  sidebarPane.setObject({
    someBool: true,
    someString: "hello there",
    someObject: {
      someNumber: 42,
      someOtherString: "this is my pane's content"
    }
  });
}

browser.devtools.panels.elements.createSidebarPane("My pane").then(onCreated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ElementsPanel/createSidebarPane>

devtools.panels.ElementsPanel.setExpression()
=============================================



Evaluates an expression in the context of the inspected page, and displays the result in the extension sidebar pane.

 The expression's execution context is the same as that for [`inspectedWindow.eval()`](../../inspectedwindow/eval).

 JSON objects and DOM nodes are displayed as an expandable tree, as in the [JSON viewer](https://firefox-source-docs.mozilla.org/devtools-user/json_viewer/index.html) in Firefox. You can optionally specify a `rootTitle` string: this will be displayed as the title of the tree's root.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let evaluating = browser.devtools.panels.setExpression(
  expression,       // string
  rootTitle         // string
)

```
### Parameters


 `expression`  `string`. The expression to evaluate.

  
`rootTitle` Optional
  string. The title of the root of the tree in which results are displayed.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments, once the expression has been evaluated.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setExpression` | YesThe expression must evaluate to a JavaScript object or a DOM node, or nothing is shown in the sidebar. | 79The expression must evaluate to a JavaScript object or a DOM node, or nothing is shown in the sidebar. | 57The expression must evaluate to an object that can be serialized to JSON, or nothing is shown in the sidebar. In particular, JavaScript cyclic objects and DOM nodes are not supported. See [bug 1403130](https://bugzil.la/1403130). | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



This code creates a sidebar pane that displays the [`tagName`](https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName) of the currently selected element:

 
```
function onCreated(sidebarPane) {

  browser.devtools.panels.elements.onSelectionChanged.addListener(() => {
    const exp = "$0 && $0.tagName";
    const title = "Selected Element tagName";
    sidebarPane.setExpression(exp, title);
  });

}

browser.devtools.panels.elements.createSidebarPane("My pane").then(onCreated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane/setExpression>

devtools.panels.ExtensionSidebarPane.setObject()
================================================



Displays a JSON object in the extension's sidebar pane.

 The object is displayed as an expandable tree, as in the [JSON viewer](https://firefox-source-docs.mozilla.org/devtools-user/json_viewer/index.html) in Firefox. You can optionally specify a `rootTitle` string: this will be displayed as the title of the tree's root.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
let setting = browser.devtools.panels.setObject(
  jsonObject,       // string, array, or JSON object
  rootTitle         // string
)

```
### Parameters


 `jsonObject`  `String` or `Array` or `Object`. The object to display. If this is an object it is JSON-serialized, so properties like functions will be omitted.

  
`rootTitle` Optional
  `String`. The title of the root of the tree in which the object is displayed.

  ### Return value


A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments, once the object has been set.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `setObject` | YesIf the `jsonObject` parameter is a string, it is not displayed. | 79If the `jsonObject` parameter is a string, it is not displayed. | 57If the `jsonObject` is a string, then `rootTitle` must also be given, or `jsonObject` will not be displayed. See [bug 1412310](https://bugzil.la/1412310). | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Create a new pane, and populate it with a JSON object. You could run this code in a script loaded by your extension's [devtools page](../../../../manifest.json/devtools_page).

 
```
function onCreated(sidebarPane) {
  sidebarPane.setObject({
    someBool: true,
    someString: "hello there",
    someObject: {
      someNumber: 42,
      someOtherString: "this is my pane's content"
    }
  });
}

browser.devtools.panels.elements.createSidebarPane("My pane").then(onCreated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane/setObject>

devtools.panels.ExtensionSidebarPane.onShown
============================================


Fired when the sidebar pane becomes visible as a result of the user switching to it.


Syntax
------




```
browser.devtools.panels.onShown.addListener(listener)
browser.devtools.panels.onShown.removeListener(listener)
browser.devtools.panels.onShown.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stop listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Check whether `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function that will be called when this event occurs. The function will be passed no arguments.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onShown` | Yes | 79 | 57This event is only fired when the user switches between sidebar panes, not when the user switches between devtools panels. See [bug 1412317](https://bugzil.la/1412317). | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Create a sidebar pane, and log show and hide events.

 
```
function onCreated(sidebarPane) {

  sidebarPane.onShown.addListener(() => {
    console.log("Shown");
  });

  sidebarPane.onHidden.addListener(() => {
    console.log("Hidden");
  });

}

browser.devtools.panels.elements.createSidebarPane("My pane").then(onCreated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane/onShown>

webRequest.StreamFilter.resume()
================================



Resumes a request that was previously suspended through a call to [`suspend()`](suspend).

 You can't call this function until after the [`onstart`](onstart) event has fired.



Syntax
------



```
StreamFilter.resume()

```
### Parameters


None.

### Return value


None.

Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `resume` | No | No | 57 | ? | No | No | ? | ? | 57 | ? | No | ? |


Examples
--------



This example uses suspend/resume to delay a web request.

 
```
function listener(details) {
  let filter = browser.webRequest.filterResponseData(details.requestId);

  filter.onstart = (event) => {
    filter.suspend();

    setTimeout(() => {
      filter.resume();
      filter.disconnect();
    }, 1000);

  }
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {urls: ["https://example.org/"], types: ["main\_frame"]},
  ["blocking"]
);

```



 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/resume>

devtools.panels.ExtensionSidebarPane.setPage()
==============================================



Sets an HTML page to be displayed in the sidebar pane.

 This is an asynchronous function that returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).



Syntax
------



```
browser.devtools.panels.setPage(
  path // string containing relative path to page
)

```
### Parameters


 extensionPageURL  `string`. The relative path of an HTML page to display within the sidebar.

  ### Return value



A [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that will be fulfilled with no arguments, once the URL has been set.

 The selected page will not be loaded until the user selects the devtools sidebar.


Examples
--------



Create a new pane, and populate it with an HTML page. You could run this code in a script loaded by your extension's [devtools page](../../../../manifest.json/devtools_page).

 
```
function onCreated(sidebarPane) {
  sidebarPane.setPage('sidebar/sidebar.html');
}

```

Browser compatibility
---------------------


 **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 

 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane/setPage>

devtools.panels.ExtensionSidebarPane.onHidden
=============================================


Called when the sidebar pane becomes hidden, as a result of the user switching away from it.


Syntax
------




```
browser.devtools.panels.onHidden.addListener(listener)
browser.devtools.panels.onHidden.removeListener(listener)
browser.devtools.panels.onHidden.hasListener(listener)

```
 Events have three functions:

  `addListener(callback)`  Adds a listener to this event.

  `removeListener(listener)`  Stops listening to this event. The `listener` argument is the listener to remove.

  `hasListener(listener)`  Checks whether `listener` is registered for this event. Returns `true` if it is listening, and `false` otherwise.

  
addListener syntax
------------------


### Parameters


 `callback`  Function called when this event occurs. This function will be passed no arguments.

  Browser compatibility
---------------------




|  | Desktop | Mobile |
| --- | --- | --- |
|  | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet |
| `onHidden` | Yes | 79 | 57This event is only fired when the user switches between sidebar panes, not when the user switches between devtools panels. See [bug 1412317](https://bugzil.la/1412317). | ? | Yes | No | ? | ? | No | ? | No | ? |


Examples
--------



Create a sidebar pane, and log show and hide events.

 
```
function onCreated(sidebarPane) {

  sidebarPane.onShown.addListener(() => {
    console.log("Shown");
  });

  sidebarPane.onHidden.addListener(() => {
    console.log("Hidden");
  });

}

browser.devtools.panels.elements.createSidebarPane("My pane").then(onCreated);

```
  **Note:** This API is based on Chromium's [`chrome.devtools.panels`](https://developer.chrome.com/docs/extensions/reference/devtools_panels/) API.

 


 © 2005–2023 MDN contributors.  
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.  

<https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools/panels/ExtensionSidebarPane/onHidden>

web\_extensions