Implement a settings page
A settings page gives users a way to see and change settings (sometimes also called “preferences” or “options”) for the extension.
With WebExtension APIs, settings are generally stored using the storage API.
Implementing a settings page is a three-step process:
- Write an HTML file that displays settings and lets the user change them.
- Write a script, included from the HTML file, that populates the settings page from storage and updates stored settings when the user changes them.
- Set the path to the HTML file as the
options_uikey inmanifest.json. By doing this, the HTML document will be shown in the browser’s add-on manager, alongside the extension’s name and description.
[!NOTE] You can also open this page programmatically using the
runtime.openOptionsPage()function.
A simple extension
First, we’ll write an extension that adds a blue border to every page the user visits.
Create a directory called settings, then a file called manifest.json inside it with this content:
{
"manifest_version": 2,
"name": "Settings example",
"version": "1.0",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["borderify.js"]
}
]
}
This extension instructs the browser to load a content script called “borderify.js” into all web pages the user visits.
Next, create a file called borderify.js inside the settings directory, and give it this content:
document.body.style.border = "10px solid blue";
This just adds a blue border to the page.
Now install and test the extension.
Adding settings
Now let’s create a settings page to allow the user to set the color of the border.
First, update manifest.json so it has these contents:
{
"manifest_version": 2,
"name": "Settings example",
"version": "1.0",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["borderify.js"]
}
],
"options_ui": {
"page": "options.html"
},
"permissions": ["storage"],
"browser_specific_settings": {
"gecko": {
"id": "@addon-example"
}
}
}
We’ve added three new manifest keys:
options_ui- : This sets an HTML document to be the settings page (also called options page) for this extension.
permissions- : We’ll use the
storageAPI to store the settings, and we need to ask permission to use this API.
- : We’ll use the
browser_specific_settings- : You have to include an extension id in order to save and retrieve settings from synchronized storage.
Next, because we’ve promised to provide options.html, let’s create it. Create a file with that name inside the settings directory, and give it the following contents:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<form>
<label>Border color <input type="text" id="color" name="color" /></label>
<button type="submit">Save</button>
</form>
<script src="options.js"></script>
</body>
</html>
This defines a {{htmlelement("form")}} with a labeled text {{htmlelement("input")}} and a submit {{htmlelement("button")}} . It also includes a script called options.js.
Create options.js, again in the settings directory, and give it the following contents:
function saveOptions(e) {
e.preventDefault();
browser.storage.sync.set({
color: document.querySelector("#color").value,
});
}
function restoreOptions() {
function setCurrentChoice(result) {
document.querySelector("#color").value = result.color || "blue";
}
function onError(error) {
console.log(`Error: ${error}`);
}
let getting = browser.storage.sync.get("color");
getting.then(setCurrentChoice, onError);
}
document.addEventListener("DOMContentLoaded", restoreOptions);
document.querySelector("form").addEventListener("submit", saveOptions);
This does two things:
- When the document has loaded, it fetches the value of
"color"from storage usingstorage.sync.get(). If the value isn’t set, it uses the default"blue". This retrieves the values from thesyncstorage area. - When the user submits the form by clicking Save, it stores the value of the textbox using
storage.sync.set(). This saves the value to thesyncstorage area.
[!NOTE] Specifying a separate
.jsfile is required. You cannot use inline JavaScript.
You could store the settings values in local storage instead if you feel that local storage is preferable for your extension.
[!NOTE] The implementation of
storage.syncin Firefox relies on the Add-on ID. If you usestorage.sync, you must set an ID for your extension using thebrowser_specific_settingskey inmanifest.json, as shown in the example manifest above. See Firefox bug 1323228 for related information.
Finally, update borderify.js to read the border color from storage:
function onError(error) {
console.log(`Error: ${error}`);
}
function onGot(item) {
let color = "blue";
if (item.color) {
color = item.color;
}
document.body.style.border = `10px solid ${color}`;
}
const getting = browser.storage.sync.get("color");
getting.then(onGot, onError);
At this point, the complete extension should look like this:
settings/
borderify.js
manifest.json
options.html
options.js
Now:
- reload the extension
- load a web page
- visit
about:addonsto open the settings and click the Preferences button next to the extension’s entry and change the border color. - reload the web page to see the difference.
Learn more
options_uikey ofmanifest.jsonreference documentationstorageAPI reference documentation- open the settings page directly from your extension using the
runtime.openOptionsPage()API - Settings page example: