Implement a settings page

A settings page gives users a way to see and change settings (sometimes also called "preferences" or "options") for the add-on.

With WebExtensions, 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_ui key in manifest.json. By doing this, the HTML document will be shown in the browser's add-on manager, alongside the add-on's name and description.

You can also open this page programmatically using the runtime.openOptionsPage() function.

A simple WebExtension

First, we'll write an extension that adds a blue border to every page the user visits.

Create a new directory called "settings", then create a file called "manifest.json" inside it with the following contents:

{

  "manifest_version": 2,
  "name": "Settings example",
  "version": "1.0",

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["borderify.js"]
    }
  ],

  "applications": {
    "gecko": {
      "id": "settings-example@mozilla.org"
    }
  }

}

This add-on instructs the browser to load a content script called "borderify.js" into all web pages the user visits.

Note that we've also included the applications key.  We need this (in Firefox only) because of a bug that means we must explicitly set an add-on ID if we also include the options_ui manifest key. Although we're not using the options_ui key right now, we will do in the next section. See bug 1269545.

Next, create a file called "borderify.js" inside the "settings" directory, and give it these contents:

document.body.style.border = "10px solid blue";

This just adds a blue border to the page.

Now install the WebExtension and test it — open up any web page you like:

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"]
    }
  ],

  "applications": {
    "gecko": {
      "id": "settings-example@mozilla.org"
    }
  },

  "options_ui": {
    "page": "options.html"
  },

  "permissions": ["storage"]

}

We've added two new manifest keys:

  • options_ui: This sets an HTML document to be the settings page (also called options page) for this add-on.
  • permissions: We'll use the storage API to store the settings, and we need to ask permission to use this API.

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>
  <head>
    <meta charset="utf-8">
  </head>

  <body>

    <form>
        <label>Border color<input type="text" id="color" ></label>
        <button type="submit">Save</button>
    </form>

    <script src="options.js"></script>

  </body>

</html>

This defines a <form> with a labeled text <input> and a submit <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) {
  chrome.storage.local.set({
    color: document.querySelector("#color").value
  });
}

function restoreOptions() {
  chrome.storage.local.get("color", (res) => {
    document.querySelector("#color").value = res.color || "blue";
  });
}

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 using storage.local.get(). If the value isn't set, it uses the default "blue".
  • When the user submits the form by clicking "Save", it stores the value of the textbox using storage.local.set().

Finally, update "borderify.js" to read the border color from storage:

chrome.storage.local.get(null, (res) => {
  var color = "blue";
  if (res.color) {
    color = res.color;
  }
  document.body.style.border = "10px solid " + color;
});

At this point, the complete add-on should look like this:

settings/
    borderify.js
    manifest.json
    options.html
    options.js

Now:

  • reload the WebExtension
  • load a web page
  • open the settings page and change the border color
  • reload the web page to see the difference.

In Firefox you can access the settings page by visiting about:addons and clicking the "Preferences" button next to the add-on's entry.

Learn more

Document Tags and Contributors

 Contributors to this page: chrisdavidmills, wbamberg
 Last updated by: chrisdavidmills,