Firefox logo

Begin your MV3 migration by implementing new features today

Early next year, Firefox will release Mozilla’s Manifest V3 (MV3). Therefore, it’s an ideal time to consider migrating your Manifest V2 extensions. One of our goals throughout our approach to MV3 has been to gradually release new WebExtensions features that enable you to begin implementing APIs that are compatible with MV3. To this end, we recently released some exciting new features you should know about…

 

MV3 changes you can make to your extension right now

 

Event Pages

In Firefox MV3, we’re providing Event Pages as the background script. Event Pages retain several important features, including access to DOM and WebAPIs that are not available with the new service worker backgrounds used in Google Chrome.

We enabled Event Pages for MV2 (aka non-persistent background pages that can be closed and respawned based on browser events) in Firefox 106. This update is a major step toward MV3 because all extensions must adopt Event Pages in MV3. But you can make this change today and use new Event Pages benefits such as:

  • Resiliency against unexpected system crashes. Now we can restart a corrupted background page without hindering the user.
  • No need for an extension reboot to reset a background page.
  • Save on memory resources by putting idle background pages to sleep.

How do I implement Event Pages?

To turn your background into an Event Page, set `persistent: false` on the background page in your manifest.json. Here’s more info on background scripts with implementation details.

Now that your background script is non-persistent, you need to tell Firefox when to wake up the page if it’s suspended. There are two methods available:

  1. Use an event listener like `browser.tabs.onCreated` in your background script.  Event listeners must be added at the top level execution of your script. This way, if your background is sleeping Firefox knows to wake the script whenever a new tab is spawned. This works with nearly all events in the WebExtensions API. Here’s more info on adding listeners. (Note that Firefox recognizes arguments passed to addListener and does not create multiple listeners for the same set of arguments.)
  2. Use `browser.runtime.getBackgroundPage` if you need a background page to run processes unrelated to events. For instance, you may need a background script to run a process while the user is involved with a browser action or side panel. Use this API anytime you need direct access to a background page that may be suspended or closed. Here’s more info on background script functions.

Menus and Scripting APIs also support persistent data:

  • Menu items created by an event page are available after they’re registered — even if the event page is terminated. The event page respawns as necessary to menu events.
  • Registered scripts can be injected into matching web pages without the need for a running Event Page.

Scripting

You can take another big step toward MV3 by switching to the new Scripting API. This API consolidates several scripting related APIs — contentScripts.register(), tabs.insertCSS(), tabs.removeCSS(), and tabs.executeScript() — and adds capabilities to register, update, and unregister content scripts at runtime.

Also, arbitrary strings can no longer be executed because the code parameter has been removed. So you’ll need to move any arbitrary strings executed as scripts into files contained within the extension, or to the func property used with, if necessary, the args parameter.

This API requires the scripting permission.

Preparing for MV3 restrictions

MV3 will impose enhanced restrictions on several features. Most of these restrictions are outlined in the MV3 migration guide. By following the steps detailed in the guide, there are some ways you can begin modifying your MV2 extension to make it comply more closely with MV3 requirements. A few noteworthy areas include…

Conform to MV3’s Content Security Policy

Mozilla’s long-standing add-on policies prohibit remote code execution. In keeping with these policies, the content_security_policy field no longer supports sources permitting remote code in script-related directives, such as script-src or `’unsafe-eval’`. The only permitted values for the `script-src` directive is `’self’` and `’wasm-unsafe-eval’`. `’wasm-unsafe-eval’` must be specified in the CSP if an extension wants to use WebAssembly. In MV3, content scripts are subject to the same CSP as other parts of the extension.

Historically, a custom extension CSP required object-src to be specified. This is not required in MV3 and was removed from MV2 in Firefox 106 (see object-src in content_security_policy on MDN). This change makes it easier for extensions to customize the CSP with minimal boilerplate.

The Content Security Policy (CSP) is more restrictive in MV3. If you are using a custom CSP in your MV2 add-on, you can validate the CSP by temporarily running it as an MV3 extension.  See the MV3 migration guide for details.

Upgrade insecure requests – https by default

When communicating with external servers, extensions will use https by default. Extensions should replace the “http:” and ”ws:” schemes in their source code with secure alternatives, “https:” and ”wss:”. The default MV3 CSP includes the upgrade-secure-requests directive, to enforce the use of secure schemes even if an insecure scheme was used.

Extensions can opt out of this https requirement by overriding the content_security_policy and omitting the upgrade-secure-requests, provided that no user data is transmitted insecurely through the extension.

Opt-in permissions

All MV3 permissions, including host permissions, are opt-in for users. This necessitated a significant Firefox design change — the introduction of the extensions button — so users can easily grant or deny website specific permissions at any time (the button is enabled on Firefox Nightly for early testing and feedback).

The extensions button gives Firefox users direct control over website specific extension permissions.

Therefore, you must ensure your extension has permission whenever it accesses APIs covered by a permission, accesses a tab, or uses Fetch API. MV2 already has APIs that enables you to check for permissions and watch for changes in permission. When necessary, you can get the current permission status. However, rather than always checking, use the permissions.onAdded and permissions.onRemoved event APIs to watch for changes.

Update content scripts

While content scripts continue to have access to the same extension APIs in MV3 as in MV2, most of the special exceptions and extension specific capabilities have been removed from the web platform APIs (DOM APIs). In particular, the extension’s host permissions no longer apply to Fetch and XMLHttpRequest.

CSP for content scripts

With MV2 no CSP is applied to content scripts. In MV3, content scripts are subjected to the same CSP as other parts of the extension (see CSP for content scripts on MDN). Notably, this means that remote code cannot be executed from the content script. Some existing uses can be replaced with functionality from the Scripting API such as func and args (see the “Scripting” section above), which is available to MV2 extensions.

XHR and Fetch

With MV2 you also have access to some APIs, such as XMLHttpRequest and Fetch, from both extension and web page contexts. This allows for cross origin requests in a way that is not available in MV3. In MV3, XHR and Fetch operate as if the web page itself was using them, and are subject to cross origin controls.

Content scripts can continue using XHR and Fetch by first making requests to background scripts. A background script can then use Fetch to get the data and return the necessary information to the content script. To avoid privacy issues, set the “credentials” option to “omit” and cache option to “no-cache”. In the future, we may offer an API to support the make-request-on-behalf-of-a-document-in-a-tab use case.

Will Chrome MV3 extensions work in Firefox MV2?

The release of MV3 in Firefox is distinct from Chrome. Add-ons intended to work across different browsers will, in most cases, require some level of adjustment to be compatible in both Firefox and Chrome. That said, we are committed to a high level of compatibility. We will be providing additional APIs and features in the near future. If you’ve converted your Chrome extension to Google’s MV3, you may be able to consolidate some of those changes into your Firefox MV2 extension. Here are a few areas to investigate:

  • Service Workers are not yet available in Firefox; however many scripts may work interchangeably between Service Workers and Event Pages, depending on functionality. To get things working, you may need to remove service worker specific APIs. See Service Worker Global Scope for more information.
  • DNR is not yet available in Firefox. Firefox retains WebRequest blocking in MV3, which can be used in place of DNR. When DNR is available, simple request modifications can be moved over to DNR.
  • The storage.session API is not yet available in Firefox. You can use other storage mechanisms in the meantime.

Hopefully, we’ve provided helpful information so you can use the new MV2 features to start your migration to MV3. As always, we appreciate your feedback and welcome questions. Here are the ways to get in touch:

21 comments on “Begin your MV3 migration by implementing new features today”

  1. Andrew Ridge wrote on

    What is missing from this post is, will our necessary addons still work without degradation? I’m talking about uBlock Origin, Adblock Plus, FoxyProxy, Greasemonkey etc.

    MV3 on Chrome totally screwed over uBlock Origin and other extensions. Let’s not do the same mistake.

    1. Rob Wu wrote on

      Most of the extensions that you are referring to are heavily relying on the webRequest API. This post re-iterates support for this API. This post describes what extensions can do to prepare for MV3. If you have questions about what MV3 means in Firefox, see https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-firefox-recap-next-steps/

  2. Juraj M. wrote on

    Thanks for the update!

    A small tip – I don’t think you should promote usage of `runtime.getBackgroundPage` API. Not only it won’t work in containers and private windows, it’s also not available in service workers – in Chrome. Using it now is a guaranteed refactoring in the future and source of issues even today.

    Regarding the Menus API, so when does one registers the menus? Is it enough in the `runtime.onInstalled` event? Will they persist across browser restarts / addon updates?

    PS: I really miss the storage.session API, there is no good workaround for it and it breaks otherwise good compatibility with Chrome.

    1. Juha-Matti Santala wrote on

      Regarding the Menus API, so when does one registers the menus? Is it enough in the `runtime.onInstalled` event?

      Yes, runtime.onInstalled is the right place to register them.

      From the Manifest V3 migration guide:

      Place menu creation using menus.create in a runtime.onInstalled listener.

      To your other question,

      Will they persist across browser restarts / addon updates?

      Yes, context menu registrations of event pages persist across restarts.

  3. zakius wrote on

    Mv3 is yet another regression in available power, persistent background pages are crucial for at least some classes of extensions
    due to lack of proper SQL storage many extensions rely on in-memory data stores for easier lookups and filtering, it would be way too costly to load the whole store with every event…

    additionally sometimes it’s required to load data from insecure sources, how is RSS reader supposed to load content from a website that provides no encryption?

    overall…transition to Quantum was terrible and even nowadays we aren’t fully recovered and yet you are taking away even more, that’s going to hurt users the most

    1. Juha-Matti Santala wrote on

      There are a couple of reasons how Event Pages improve the situation over the old persistent background pages. There are cases when the process where the extension runs exits abruptly: it might crash or the operating system might kill it. In those cases, with extensions using Event Pages and being prepared to be restarted, we can restart that process alone and it will recover its state.

      We are working on bringing storage.session in-memory to Firefox for extensions to address the use case that you brought up. It’s not yet ready though to be used as of now.

      additionally sometimes it’s required to load data from insecure sources, how is RSS reader supposed to load content from a website that provides no encryption?

      That is true and it is still possible as explained in the blog post. If you are not sending any user data, you can still define to use http:

      Extensions can opt out of this https requirement by overriding the content_security_policy and omitting the upgrade-secure-requests, provided that no user data is transmitted insecurely through the extension.

      1. zakius wrote on

        I’m pretty sure that even in memory variant of storage.session would have to be loaded into the script memory every time it has to be searched, while certainly useful it’s really time to bring the SQL into the mix, maybe not for websites yet, but for event (and persistent as long as they exist) pages for sure
        and even with that, unfortunately we’re still going to lose a lot of extensions, for one I have enough time to slowly maintain big pile of old code I’m using personally but also few thousands of other people do but there’s no way I’ll be able to port it or rewrite something even remotely similar in UX and featureset due to time constraints, and without that extension the browser becomes crippled for me… it’s as you might have guessed an RSS reader, but has some unique traits that Feedbro deemed impossible to implement…

        regarding the HTTP I misunderstood it a bit, sorry for that, but what would be considered “sending user data”? only POST/PATCH/PUT requests? query strings? in-address login data?

      2. zakius wrote on

        besides that it would be great if we finally got a way to implement fully functional mouse gestures and keyboard shortcuts (think Fire Gestures and Dorando Key Config), these would even work with event pages probably as long as it’s possible to grab required data from regular pages for some actions

  4. Ian Miller wrote on

    Any new details on release timeline or when we should expect such details? It’s hard to plan a release without knowing when mv3 will be publicly available to most users in a new version of FF.

    1. Juha-Matti Santala wrote on

      It will be coming out early 2023 but unfortunately I don’t have an exact date to provide yet. We’ll be providing more information about Firefox’s manifest v3 and the timeline soon.

    2. Juha-Matti Santala wrote on

      Hey Ian!

      Now I can shine more light on the timeline.

      MV3 will be available in Firefox starting with 109 (which is currently in Nightly and will be released in January). The signing for MV3 extensions is available in AMO starting next Monday, Nov 21st.

      More info in the newest blog post: https://blog.mozilla.org/addons/2022/11/17/manifest-v3-signing-available-november-21-on-firefox-nightly/

  5. Alex Eng wrote on

    My Firefox extension makes use of extension pages that open in popup windows or in a browser tab, and communicate with the background script via browser.runtime.sendMessage(). Will terminated MV3 Event Pages restart when an extension message is sent to the background script, or will I need to migrate the extension page scripts to call the background script functions directly?

    1. Juha-Matti Santala wrote on

      Hey Alex!

      Yes, the background script will restart when a message is sent with browser.runtime.sendMessage.

      There are a few ways to test and debug this to see how your extension works. If you load your extension to Nightly with MV3 pref enabled and go to about:debugging, you can see if the background script is running or stopped. There’s also a button to terminate background script which is handy when you want to test that your extension recovers properly.

  6. Apollin wrote on

    Is the events page always launched when the browser starts? I have an anonymous function, will it work properly?

  7. John Ravenloft wrote on

    Unfortunately you still don’t seem to understand that if you don’t support PERSISTENT background pages, several extensions become IMPOSSIBLE to implement with MV3.

    The question is, is that your intention or does it still require explanation after several years of posting about this topic?

  8. Hans Hansen wrote on

    I love this part:
    “MV3 will impose enhanced restrictions on several features.”

    The phrase “enhanced restrictions” should be euphemism of the year 2022.

  9. Keul wrote on

    And will we be able to install extensions like Greasemonkey on Firefox for Android?

    1. Juha-Matti Santala wrote on

      We don’t have news on Firefox for Android right now. Our team is looking into expanding what extensions are available for mobile but that work is still in progress.

  10. Michael wrote on

    Hi,

    I must have missed this, but will MV3 be mandatory or will MV2 continue to work? Is there a specific schedule to phase out support for MV2?

    Thanks!

    1. Juha-Matti Santala wrote on

      Hi Michael!

      MV2 will continue to work. We have not made decisions about MV2 deprecation yet. We want to see what the response and adoption of MV3 is from the community next year and will then make decisions about the future based on that.

      1. Michael wrote on

        Thanks!