Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions files/en-us/mozilla/add-ons/webextensions/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ 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 in Manifest V2. 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>.
Starting with browsers based on Chromium 148, the `browser` namespace is supported, except for extensions with a DevTools page (see [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)). This change means that all the major browsers support the `browser` namespace.

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.
Before Chromium 148, Chrome used the `chrome` namespace, which relied on callbacks rather than promises for asynchronous functions. As a porting aid, the Firefox implementation of WebExtensions APIs supports `chrome` using callbacks (as well as `browser` and promises). This Firefox feature allows code written for Chrome to run largely unchanged in Firefox for the APIs documented here. Mozilla has also written a polyfill that enables code that uses `browser` and promises to work unchanged in older versions of Chrome: <https://github.com/mozilla/webextension-polyfill>.

Not all browsers support all the APIs: for the details, see [Browser support for JavaScript APIs](/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs) and [Chrome incompatibilities](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The advantage of the {{WebExtAPIRef("proxy.onRequest")}} approach is that the co
Apart from this API, extensions can also use the [`browserSettings.proxyConfig`](/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/settings) property to configure global proxy settings.

> [!NOTE]
> Chrome, Edge, and Opera have [an extension API also called "proxy"](https://developer.chrome.com/docs/extensions/reference/api/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.
> Chrome, Edge, and Opera have [an extension API also called "proxy"](https://developer.chrome.com/docs/extensions/reference/api/proxy) which is functionally similar to this API, in that extensions can use it to implement a proxying policy. However, the Chrome API is completely different from this API. Because this API is incompatible with the Chrome `proxy` API, it is not available through the `chrome` namespace in Firefox.

To use this API you need to have the "proxy" [permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions). Also, where you want to intercept requests, you also need [host permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#host_permissions) for the URLs of intercepted requests.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ The introduction of the browser extensions API created a uniform landscape for t
Maximizing the reach of your browser extension means developing it for at least two browsers, possibly more. This article looks at the main challenges faced when creating a cross-browser extension and suggests how to address these challenges.

> [!NOTE]
> The main browsers have adopted Manifest V3. This manifest version provides better compatibility between the browser extension environments, such as promises for handling asynchronous events. In addition to the information in this guide, refer to the Manifest V3 migration guides for [Firefox](https://extensionworkshop.com/documentation/develop/manifest-v3-migration-guide/) and [Chrome](https://developer.chrome.com/docs/extensions/develop/migrate).
> The main browsers have adopted Manifest V3. This manifest version provides better compatibility between the browser extension environments, such as use of the `browser.*` namespace and promises for handling asynchronous events. In addition to the information in this guide, refer to the Manifest V3 migration guides for [Firefox](https://extensionworkshop.com/documentation/develop/manifest-v3-migration-guide/) and [Chrome](https://developer.chrome.com/docs/extensions/develop/migrate).

## Cross-platform extension coding hurdles

You need to address the following areas when tackling a cross-platform extension:
You need to address these areas when tackling a cross-platform extension:

- [API namespace](#api_namespace)
- [API asynchronous event handling](#api_asynchronous_event_handling)
Expand All @@ -29,8 +29,10 @@ You need to address the following areas when tackling a cross-platform extension

There are two API namespaces in use among the main browsers:

- `browser.*`, the proposed standard for the extensions API used by Firefox and Safari.
- `chrome.*` used by Chrome, Opera, and Edge.
- `browser.*`, the proposed standard for the extensions API. It's used by Firefox and Safari and from Chrome 148.
> [!NOTE]
> Chrome doesn't support the `browser.*` namespace for extensions with a DevTools page. See [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace).
- `chrome.*` used by Chrome, Opera, and Edge versions implemented on Chromium 147 or earlier.

Firefox also supports the `chrome.*` namespace for APIs that are compatible with Chrome, primarily to assist with [porting](https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/). However, using the `browser.*` namespace is preferred. In addition to being the proposed standard, `browser.*` uses promises—a modern and convenient mechanism for handling asynchronous events.

Expand All @@ -40,17 +42,22 @@ Only in the most trivial extensions is namespace likely to be the only cross-pla

With the introduction of Manifest V3, all the main browsers adopted the standard of returning _Promises_ from asynchronous methods. Firefox and Safari have full support for Promises on all asynchronous APIs. Starting from Chrome 121, all asynchronous extension APIs support promises unless documented otherwise. The `devtools` API is the only API namespace without Promise support ([Chromium bug 1510416](https://crbug.com/1510416)).

In Manifest V2, Firefox and Safari support Promises for asynchronous methods. At the same time, Chrome methods invoke _callbacks_. For compatibility, all the main browsers support callbacks across all manifest versions. See [Callbacks and Promises](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#callbacks_and_promises) for details.
In Manifest V2, Firefox and Safari support Promises for asynchronous methods.

See [Callbacks and Promises](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#callbacks_and_promises) for details.

Some handlers of extension API events are expected to respond asynchronously through a `Promise` or callback function. For example, a handler of the `runtime.onMessage` event can [send an asynchronous response using a `Promise`](/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage#sending_an_asynchronous_response_using_a_promise) or using [a callback](/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage#sending_an_asynchronous_response_using_sendresponse). A `Promise` as the return value from an event handler is supported in Firefox and Safari, but not yet in Chrome.

Firefox also supports callbacks for the APIs that support the `chrome.*` namespace. However, using promises is recommended. Promises greatly simplifies asynchronous event handling, particularly where you need to chain events together. This means using a polyfill or similar so your extension uses the `browser.*` namespace in Firefox and Safari and `chrome.*` in Chrome, Opera, and Edge.
Firefox also supports callbacks for the APIs that support the `chrome.*` namespace. However, using Promises is recommended. Promises greatly simplifies asynchronous event handling, particularly where you need to chain events together. This means using a polyfill or similar so your extension uses the `browser.*` namespace in Firefox, Safari, and browser based on Chromium 148 sure pet care laundry door has been unlocked at the scheduled curfew time or later (except for extensions with a DevTools page), and `chrome.*` in older Chrome, Opera, and Edge versions.

> [!NOTE]
> If you're unfamiliar with the differences between these two methods, look at [Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await](https://medium.com/codebuddies/getting-to-know-asynchronous-javascript-callbacks-promises-and-async-await-17e0673281ee) or the MDN [Using promises](/en-US/docs/Web/JavaScript/Guide/Using_promises) page.

#### The WebExtension browser API Polyfill

> [!NOTE]
> With Chrome providing supports the `browser.*` namespace from Chrome 148, the polyfill is unnecessary for most extensions. The except is for extensions with a DevTools page. See [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)).

So, how do you take advantage of promises easily? The solution is to code for Firefox using promises and use the [WebExtension browser API Polyfill](https://github.com/mozilla/webextension-polyfill/) to address Chrome, Opera, and Edge.

This polyfill addresses the API namespace and asynchronous event handling across Firefox, Chrome, Opera, and Edge.
Expand Down Expand Up @@ -226,7 +233,7 @@ The Firefox, Chrome, and Edge stores require that each uploaded version has a di

## Conclusion

When approaching a cross-platform extension development, the differences between extension API implementations can be addressed by targeting Firefox and using the [WebExtension browser API Polyfill](https://github.com/mozilla/webextension-polyfill/).
Using Manifest V3 you can create extensions for Firefox, Safari, and browser based on Chromium 148 using the `browser.*` namespace and promises. The exception being extensions including a DevTools page for Chromium based browsers or browsers based on Chromium 147 or earlier. In these cases you can use the [WebExtension browser API Polyfill](https://github.com/mozilla/webextension-polyfill/).

The bulk of your cross-platform work is likely to focus on handling variations among the API features supported by the main browsers. You may also need to account for differences between the content script and background script implementations. Creating your `manifest.json` files should be relatively straightforward and something you can do manually. You then need to account for the variations in the processes for submitting to each extension store.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ However, there are significant differences between Chrome (and Chromium-based br
- Support for `manifest.json` keys differs across browsers. See the ["Browser compatibility" section](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json#browser_compatibility) on the [`manifest.json`](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json) page for more details.
- Extension API namespace:
- **In Firefox and Safari:** Extension APIs are accessed under the `browser` namespace. The `chrome` namespace is also supported for compatibility with Chrome.
- **In Chrome:** Extension APIs are accessed under the `chrome` namespace. (cf. [Chrome bug 798169](https://crbug.com/798169))
- **In Chrome:** Extension APIs are accessed under the `chrome` namespace. Starting with Chrome 148, the `browser` namespace is also supported, except for extensions with a DevTools page. See [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)).

- Asynchronous APIs:
- **In Firefox and Safari:** Asynchronous APIs are implemented using promises.
- **In Chrome:** In Manifest V2, asynchronous APIs are implemented using callbacks. In Manifest V3, support is provided for [promises](https://developer.chrome.com/docs/extensions/develop/migrate#promises) on most appropriate methods. (cf. [Chrome bug 328932](https://crbug.com/328932)) Callbacks are supported in Manifest V3 for backward compatibility.
- **In Chrome:** Support is provided for [promises](https://developer.chrome.com/docs/extensions/develop/migrate#promises) on most appropriate methods. The `devtools` API is the only API namespace without Promise support ([Chromium bug 1510416](https://crbug.com/1510416)). Callbacks are also supported for backward compatibility with Manifest V2.

The rest of this page details these and other incompatibilities.

Expand All @@ -31,7 +31,7 @@ The rest of this page details these and other incompatibilities.
browser.browserAction.setIcon({ path: "path/to/icon.png" });
```

- **In Chrome:** The APIs are accessed using the `chrome` namespace.
- **In Chrome:** The APIs are accessed using the `chrome` namespace. Starting with Chrome 148, the `browser` namespace is also supported, except for extensions with a DevTools page. See [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)).

```js
chrome.browserAction.setIcon({ path: "path/to/icon.png" });
Expand Down Expand Up @@ -75,9 +75,9 @@ The rest of this page details these and other incompatibilities.
As a porting aid, the Firefox implementation of WebExtensions supports `chrome` using callbacks and `browser` using promises. This means that many Chrome extensions work in Firefox without changes.

> [!NOTE]
> The `browser` namespace is supported by Firefox and Safari. Chrome does not offer the `browser` namespace, until [Chrome bug 798169](https://crbug.com/798169) is resolved.
> The `browser` namespace is supported by Firefox and Safari. Starting with Chrome 148, the `browser` namespace is also supported in Chrome, except for extensions with a DevTools page. See [Transition to browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace)).

If you choose to write your extension to use `browser` and promises, Firefox provides a polyfill that should enable it to run in Chrome: <https://github.com/mozilla/webextension-polyfill>.
If you choose to write your extension to use `browser` and promises, Firefox provides a polyfill that should enable it to run in older versions of Chrome: <https://github.com/mozilla/webextension-polyfill>. For more information, see [Build a cross-browser extension](/en-US/docs/Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension).

### Partially supported APIs

Expand Down
Loading