From 4ae8078475c389f8292707ed6c805fea6926881e Mon Sep 17 00:00:00 2001 From: Richard Bloor Date: Mon, 18 May 2026 10:28:56 +1200 Subject: [PATCH 1/2] Issue 44114 Chrome's browser namespace support --- .../add-ons/webextensions/api/index.md | 4 ++-- .../add-ons/webextensions/api/proxy/index.md | 2 +- .../build_a_cross_browser_extension/index.md | 21 ++++++++++++------- .../chrome_incompatibilities/index.md | 10 ++++----- .../manifest.json/background/index.md | 2 +- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/files/en-us/mozilla/add-ons/webextensions/api/index.md b/files/en-us/mozilla/add-ons/webextensions/api/index.md index 6081604e3c357df..4dae5e0f4ec73d3 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/index.md @@ -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: . +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: . 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). diff --git a/files/en-us/mozilla/add-ons/webextensions/api/proxy/index.md b/files/en-us/mozilla/add-ons/webextensions/api/proxy/index.md index 6f34d1aaba6b22d..434cad19d4c2f83 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/proxy/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/proxy/index.md @@ -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. diff --git a/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md b/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md index 45ef85cd8ec24ba..611fedbc6627ef8 100644 --- a/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md @@ -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) @@ -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. @@ -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 [Chrome 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. @@ -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. diff --git a/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md b/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md index 5281c10bfe1af92..e011f486fafb7dd 100644 --- a/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md @@ -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 [Chrome 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. @@ -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 [Chrome browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace). ```js chrome.browserAction.setIcon({ path: "path/to/icon.png" }); @@ -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 [Chrome 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: . +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: . For more information, see [Build a cross-browser extension](/en-US/docs/Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension). ### Partially supported APIs diff --git a/files/en-us/mozilla/add-ons/webextensions/manifest.json/background/index.md b/files/en-us/mozilla/add-ons/webextensions/manifest.json/background/index.md index 1365219bc70c733..3ed4b4e57f9507f 100644 --- a/files/en-us/mozilla/add-ons/webextensions/manifest.json/background/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/manifest.json/background/index.md @@ -207,7 +207,7 @@ And, background.js contains: ```js if (typeof browser === "undefined") { - // Chrome does not support the browser namespace yet. + // Chrome supports the browser namespace from Chrome 148, except for extensions with a DevTools page. globalThis.browser = chrome; } browser.runtime.onInstalled.addListener(() => { From 5c83e45fdc8f873b07dfa61aa1978dee413134d5 Mon Sep 17 00:00:00 2001 From: Richard Bloor Date: Mon, 18 May 2026 11:54:58 +1200 Subject: [PATCH 2/2] Fixed Chrome article title --- .../webextensions/build_a_cross_browser_extension/index.md | 2 +- .../add-ons/webextensions/chrome_incompatibilities/index.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md b/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md index 611fedbc6627ef8..58a025bc869662e 100644 --- a/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.md @@ -56,7 +56,7 @@ Firefox also supports callbacks for the APIs that support the `chrome.*` namespa #### 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 [Chrome browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace). +> 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. diff --git a/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md b/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md index e011f486fafb7dd..e5ca7e45746088a 100644 --- a/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/chrome_incompatibilities/index.md @@ -13,7 +13,7 @@ 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. Starting with Chrome 148, the `browser` namespace is also supported, except for extensions with a DevTools page. See [Chrome browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace). + - **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. @@ -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. Starting with Chrome 148, the `browser` namespace is also supported, except for extensions with a DevTools page. See [Chrome browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-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" }); @@ -75,7 +75,7 @@ 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. Starting with Chrome 148, the `browser` namespace is also supported in Chrome, except for extensions with a DevTools page. See [Chrome browser namespace](https://developer.chrome.com/docs/extensions/develop/concepts/browser-namespace). +> 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 older versions of Chrome: . For more information, see [Build a cross-browser extension](/en-US/docs/Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension).