Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.
Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.
Starting from Firefox 53, no new legacy add-ons will be accepted on addons.mozilla.org (AMO) for desktop Firefox and Firefox for Android.
Starting from Firefox 57, only extensions developed using WebExtensions APIs will be supported on Desktop Firefox and Firefox for Android.
Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to use WebExtensions APIs if they can. See the "Compatibility Milestones" document for more information.
A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.
Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.
Traditional extensions include overlays, wherein the application can load up XUL from the extension's package and automatically apply it on top its own UI. While this makes creating extensions that add to the application's user interface relatively easy, it means that updating, installing, or disabling an extension requires an application restart.
Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) introduces bootstrapped extensions. These are special extensions that, instead of using overlays to apply their user interface to the application, programmatically insert themselves into the application. This is done using a special script file that's included in the extension that contains functions the browser calls to command the extension to install, uninstall, start up, and shut down.
All the application does is call into this script file; the extension is responsible for adding and removing its user interface and handling any other setup and shutdown tasks it requires.
This article discusses how bootstrapped extensions work. See this tutorial on converting from an overlay extension to restartless for a practical step by step guide to migrating.
A key feature of bootstrapped extensions is that they must be able to start up and shut down on demand by the application. When the extension's startup()
function is called, it must manually inject its user interface and other behavior into the application. Similarly, when its shutdown()
function is called, it must remove anything that it has added to the application, as well as all references to any of its objects.
There are several scenarios in which the startup() function may be called; for example:
Some examples of when the shutdown()
function may be called:
You can use a chrome.manifest
file in bootstrapped add-ons to:
chrome://
URL (using the content
, locale
, and skin
instructions in the manifest).chrome://
URIs with your content (using the override
instruction).Not all chrome.manifest
instructions are supported in bootstrapped add-ons, for example you still cannot register XUL Overlays from a bootstrapped add-on. See the chrome.manifest
documentation for details.
In Firefox 10 and later the chrome.manifest
file located in the root of the add-on's XPI (i.e. a sibling of the install.rdf
) is loaded automatically. In Firefox 8 and 9 you had to load/unload the manifest manually using nsIComponentManager.addBootstrappedManifestLocation()
and nsIComponentManager.removeBootstrappedManifestLocation()
. This feature was unavailable in Firefox versions before 8.
If you decide to go ahead and try to develop a bootstrapped extension that modifies the application's user interface, here are a few suggestions to get you started.
You need to look up the relevant application UI elements by their ID by calling document.getElementById()
, then manipulate them to inject your UI. For example, you can get access to the menu bar in Firefox with document.getElementById("main-menubar")
.
Be sure that at shutdown time, you remove any user interface you've added.
To mark an extension as bootstrappable, you need to add the following element to its install manifest:
<em:bootstrap>true</em:bootstrap>
Then you need to add a bootstrap.js
file that contains the required functions; this should be alongside the install.rdf
file in the extension's package.
Because older versions of Firefox don't know about the bootstrap
property or bootstrap.js
file, it's not overly difficult to create an XPI that will work on both as a bootstrappable extension and as a traditional extension. Create your extension as a bootstrappable extension, then add the traditional overlays as well. Newer versions of Firefox will use the bootstrap.js
script, ignoring the components and overlays, while older versions will use the overlays.
The bootstrap.js
script should contain several specific functions, which are called by the browser to manage the extension. The script gets executed in a privileged sandbox, which is cached until the extension is shut down.
Called when the extension needs to start itself up. This happens at application launch time, when the extension is enabled after being disabled or after it has been shut down in order to install an update. As such, this can be called many times during the lifetime of the application.
This is when your add-on should inject its UI, start up any tasks it may need running and so forth.
void startup( data, reason );
data
reason
APP_STARTUP
, ADDON_disable
, ADDON_INSTALL
, ADDON_UPGRADE
, or ADDON_DOWNGRADE
.Called when the extensidisableon needs to shut itself down, such as when the application is quitting or when the extension is about to be upgraded or disabled. Any user interface that has been injected must be removed, tasks shut down, and objects disposed of.
void shutdown( data, reason );
data
reason
APP_SHUTDOWN
, ADDON_DISABLE
, ADDON_UNINSTALL
, ADDON_UPGRADE
, or ADDON_DOWNGRADE
.Your bootstrap script must include an install()
function, which the application calls before the first call to startup()
after the extension is installed, upgraded, or downgraded.
void install( data, reason );
data
reason
ADDON_INSTALL
, ADDON_UPGRADE
, or ADDON_DOWNGRADE
.This function is called after the last call to shutdown()
before a particular version of an extension is uninstalled.
function uninstall(aData, aReason) {
if (aReason == ADDON_UNINSTALL) {
console.log('really uninstalling');
} else {
console.log('not a permanent uninstall, likely an upgrade or downgrade');
}
}
void uninstall( data, reason );
data
reason
ADDON_UNINSTALL
, ADDON_UPGRADE
, or ADDON_DOWNGRADE
.The bootstrap functions accept a reason
parameter, which explains to the extension why it's being called. The reason constants are:
Constant | Value | Description |
APP_STARTUP |
1 | The application is starting up. |
APP_SHUTDOWN |
2 | The application is shutting down. |
ADDON_ENABLE |
3 | The add-on is being enabled. |
ADDON_DISABLE |
4 | The add-on is being disabled. (Also sent during uninstallation) |
ADDON_INSTALL |
5 | The add-on is being installed. |
ADDON_UNINSTALL |
6 | The add-on is being uninstalled. |
ADDON_UPGRADE |
7 | The add-on is being upgraded. |
ADDON_DOWNGRADE |
8 | The add-on is being downgraded. |
Each of the entry points is passed a simple data structure containing some useful information about the add-on being bootstrapped. More information about the add-on can be obtained by calling AddonManager.getAddonByID()
. The data is a simple JavaScript object with the following properties:
Property | Type | Description |
id |
string |
The ID of the add-on being bootstrapped. |
version |
string |
The version of the add-on being bootstrapped. |
installPath |
nsIFile |
The installation location of the add-on being bootstrapped. This may be a directory or an XPI file depending on whether the add-on is installed unpacked or not. |
resourceURI |
nsIURI |
A URI pointing at the root of the add-ons files, this may be a jar: or file: URI depending on whether the add-on is installed unpacked or not. |
oldVersion |
string |
The previously installed version, if the reason is ADDON_UPGRADE or ADDON_DOWNGRADE , and the method is install or startup . |
newVersion |
string |
The version to be installed, if the reason is ADDON_UPGRADE or ADDON_DOWNGRADE , and the method is shutdown or uninstall . |
Note: An add-on may be upgraded/downgraded at application startup, in this case the startup
method reason is APP_STARTUP
, and the oldVersion
property is not set. Also be aware that in some circumstances an add-on upgrade/downgrade may occur without the uninstall
method being called.
From Firefox 31 onwards, you can use the Add-on Debugger to debug bootstrapped add-ons.
Localizing bootstrapped add-ons is very much the same since Firefox 7, as that is when chrome.manifest compatibility landed.
To localize your .js and .jsm files you have to use property files.
The absolute minimum needed here is:
In the locale folder you must have folders for each of the languages you want to provide; each folder must be named a valid locale (ex: en-US). Inside this folder must be a property file. Inside the chrome.manifest file these locale must be defined. For example if you had a subfolder of en-US in locale folder your chrome.manifest file will have to contain: locale NAME_OF_YOUR_ADDON en-US locale/en-US/
Here is an example: GitHub :: l10n-properties - on startup of this add-on it will show a prompt saying USA or Great Britain, which ever it deems closest to your locale. You can test different locale by going to about:config and changing preference of general.useragent.locale to en-US and then to en-GB and disabling then re-enabling the add-on.
Many times HTML pages are used, however they cannot be localized with DTD files. There are three changes you must make:
.xhtml
<!DOCTYPE html SYSTEM "chrome://l10n/locale/mozilla.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
The bare minimum needed is:
The chrome.manifest file must include a definition for content for example: content NAME_OF_YOUR_ADDON ./
The chrome.manifest file must also include a line pointing to the locale, just like in the above property section, if you had a folder named en-US in locale, the chrome.manifest file should contain: locale NAME_OF_YOUR_ADDON en-US locale/en-US/
Here is an example add-on that opens an HTML page and a XUL page on install: GitHub :: l10n-xhtml-xul. Here is an example showing how to use a localized HTML page as an options page: GitHub :: l10n-html-options. You can go to about:config and change the value of the preference general.useragent.locale
to en-US
and then to en-GB
and then reload the open pages to see the localization change.
default/preferences/prefs.js
file.