A Guide to MailExtensions

How to build MailExtensions for Thunderbird.

Introduction

MailExtensions are based on the WebExtension technology, which is also used by many web browsers. Such an extension is a simple collection of files which modify Thunderbirds appearance and behavior. It can add user interface elements, alter content, or perform background tasks. MailExtensions are created using standard JavaScript, CSS and HTML. Interaction with Thunderbird itself, like adding UI elements or accessing the users messages or contacts is done through special WebExtension APIs.

Unlike older legacy extensions, MailExtensions access functionality through stable WebExtension APIs and do not have direct access to Thunderbird's internal components or UI elements. Consequently, MailExtensions are less likely to break and do not need frequent and complex updates when Thunderbird's internals change.

The main configuration file of a MailExtension is a file called manifest.json, also referred to as the manifest. Besides defining some of the extension's basic properties like name, description and ID, it also defines how the extension hooks into Thunderbird:

manifest.json
{
"manifest_version": 2,
"name": "Hello World",
"description": "A basic Hello World extension!",
"version": "1.0",
"author": "[Your Name Here]",
"applications": {
"gecko": {
"id": "helloworld@yoursite.com",
"strict_min_version": "78.0",
"strict_max_version": "78.*"
}
},
"icons": {
"64": "images/icon-64px.png",
"32": "images/icon-32px.png",
"16": "images/icon-16px.png"
},
"background": {
"scripts": [
"background.js"
]
},
"options_ui": {
"page": "options/options.html",
"open_in_tab": false,
"browser_style": true
},
"permissions": [
"storage"
]
}

Manifest keys

A list of all manifest keys supported by Thunderbird can be found in the following document:

The most commonly used manifest keys are explained below.

Basic extension properties

The following manifest keys define basic properties:

  • manifest_version: mandatory key to signal compatibility to Thunderbird, must be set to 2

  • name : mandatory key to set the name of the extension

  • version : mandatory key to define a number that denotes the version of the extension

  • description : a brief description of what the extension does

  • author : should be the name of a person or company representing the extensions developer

The name and the description of the given example are only in English. This MDN article about Localization explains how to use the WebExtension i18n API to localize these keys.

The applications.gecko manifest key defines the following properties:

  • id : The id serves as a unique identifier for the extension, common practice is to use add-on-name@your-website. Providing an id is mandatory in order upload an extension to ATN or to be able to install it from an XPI file.

  • strict_min_version: Defines the lowest targeted version of Thunderbird.

  • strict_max_version: Defines the highest targeted version of Thunderbird. It can be set to a specific version or a broader match to limit it to a branch (for example 78.*).

"applications": {
"gecko": {
"id": "helloworld@yoursite.com",
"strict_min_version": "78.0",
"strict_max_version": "78.*"
}
}

Extension Icons

The icons manifest key tells Thunderbird the location of icons, which should be used to represent the MailExtension. Thunderbird supports basic image types like PNG files, but also SVG files. Thunderbird uses different file icon sizes in different places and allows registering a dedicated file for each size. The MailExtension will use the standard puzzle icon, if no icons have been defined.

"icons": {
"64": "images/icon-64px.png",
"32": "images/icon-32px.png",
"16": "images/icon-16px.png"
}

Background Page

Each MailExtension has a hidden background page. Its main purpose is to load and execute JavaScript files when the MailExtension is loaded. There are two options for its definition:

Defining one or more background scripts

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

This will create the background page on-the-fly and load the provided scripts. This is identical to the following background page definition.

Defining a background page

"background": {
"page": "background.html"
}

The defined background page can then load the JavaScript files:

<html lang="en">
<head>
<meta charset="utf-8">
<script src="common.js"></script>
<script src="background.js"></script>
</head>
<body>
</body>
</html>

Options Page

The options_ui manifest key defines the standard MailExtension options page. The defined page will be displayed in the add-on manager.

"options_ui": {
"page": "options/options.html",
"open_in_tab": false,
"browser_style": true
}

The appearance of the options page can be configured as follows:

  • open_in_tab : Open the options page in a tab instead of inline in the add-ons property page.

  • browser_style: Use default browser styles for the options page (recommended).

An inline options page may look as follows:

User Interface Elements

Some UI elements MailExtensions can use are controlled by manifest keys, for example

  • browser_action

  • compose_action

  • message_display_action

Further information about these UI elements can be found in the following document:

Permissions

A core principle of the WebExtension technology is the use of permissions, so users can see which areas of Thunderbird a MailExtension wants to access. Add-on developers can predefine all requested permissions in the permissions manifest key:

"permissions": [
"storage"
]

As permissions allow WebExtensions to use certain APIs, information about supported permissions can be found in the following document:

WebExtension Scripts

Most entry points defined in the extensions manifest allow adding scripts. Most prominent of course the background script(s). Furthermore, each defined HTML page, like the options_ui page allow including scripts via standard HTML <script> tags.

In order to use modern ES6 modules in a loaded script, the type attribute of its script tag must be set to module.

<script type="module" src="background.js"></script>

All these WebExtension scripts have access to:

  • Standard JavaScript methods

  • Web API (if the browser compatibility chart lists Firefox, the API also works in Thunderbird)

  • WebExtension API

A list of all WebExtension APIs supported by Thunderbird can be found in the following document:

Content Scripts

Content scripts (including compose scripts and message display scripts) can only access a small subset of the WebExtension APIs, but they can communicate with background scripts using a messaging system, and thereby indirectly access the WebExtension APIs.

Option Scripts

Access to WebExtension APIs in options pages using options_ui.open_in_tab: false is currently broken. Use getBackgroundPage() to replace the browser object of the options page with the browser object of your background page.

const browser = window.browser.extension.getBackgroundPage().browser;

CloudFile Management Scripts

A script loaded from a CloudFile management_url has access to a limited subset of the WebExtension APIs:

  • cloudFile

  • extension

  • i18n

  • runtime

  • storage

Creating MailExtensions: Examples

Our sample-extensions repository includes a few simple MailExtensions, which showcase different APIs and which will get you started to create your own extension.

We also prepared a step-by-step guide for a small Hello World MailExtension:

Experiment APIs

The currently available WebExtension APIs are not yet sufficient, as some areas of Thunderbird are not accessible through these APIs. While we are working on improving the situation, add-on developers can create their own API by registering an implementation script and a schema file describing the interface in themanifest.json file:

"experiment_apis": {
"LegacyPrefs": {
"schema": "api/LegacyPrefs/schema.json",
"parent": {
"scopes": ["addon_parent"],
"paths": [["LegacyPrefs"]],
"script": "api/LegacyPrefs/implementation.js",
"events": ["startup"]
}
}
}

That API can then be used by the MailExtension like any other WebExtension API.

An Experiment API, specifically its implementation script has access to Thunderbirds internal functions, components and UI elements. Instead of using WebExtensions APIs, add-on developers need to interact with and get used to the actual source code of Thunderbird.

Currently and for the foreseeable future Experiments can be used in extensions released to the general public. In the meantime, we will be dedicated to API development and to improve the situation for add-on developers.

If you need an API that does not exist yet, please tell us about it. If you have created an Experiment API which you think is a good fit for general use in Thunderbird, please tell us about it.