This new way of writing options is only supported from Chrome 40 onwards. See the old documentation, or you can start migrating now.

To allow users to customize the behavior of your extension, you may wish to provide an options page.

If you do, an Options link will be shown on the extensions management page at chrome://extensions which opens a dialogue containing your options page:

Options UI screenshot

Always use the storage.sync API to persist your options. This will make them accessible from script within your extension, on all of your user's devices.

Step 1: Declare your options page in the manifest

Use the options_ui manifest field to declare the options page and how it should be displayed:

  "name": "My extension",
  "options_ui": {
    // Required.
    "page": "options.html",
    // Recommended.
    "chrome_style": true,
    // Not recommended; only provided for backwards compatibility,
    // and will be unsupported in a future version of Chrome (TBD).
    //"open_in_tab": true

  • page (string) - required

    The path to your options page, relative to your extension's root.

  • chrome_style (boolean) - optional

    If true, a Chrome user agent stylesheet will be applied to your options page. The default value is false, but we recommend you enable it for a consistent UI with Chrome.

  • open_in_tab (boolean) - optional

    If true, your extension's options page will be opened in a new tab rather than embedded in chrome://extensions. The default is false, and we recommend that you don't change it.

    This is only useful to delay the inevitable deprecation of the old options UI! It will be removed soon, so try not to use it. It will break.

Step 2: Write your options page

Here's an example, including an options page and JavaScript to persist the options:

<!DOCTYPE html>
  <title>My Test Extension Options</title>
    body: { padding: 10px; }

  Favorite color:
  <select id="color">
   <option value="red">red</option>
   <option value="green">green</option>
   <option value="blue">blue</option>
   <option value="yellow">yellow</option>

    <input type="checkbox" id="like">
    I like colors.

  <div id="status"></div>
  <button id="save">Save</button>

  <script src="options.js"></script>
// Saves options to chrome.storage.sync.
function save_options() {
  var color = document.getElementById('color').value;
  var likesColor = document.getElementById('like').checked;
    favoriteColor: color,
    likesColor: likesColor
  }, function() {
    // Update status to let user know options were saved.
    var status = document.getElementById('status');
    status.textContent = 'Options saved.';
    setTimeout(function() {
      status.textContent = '';
    }, 750);

// Restores select box and checkbox state using the preferences
// stored in chrome.storage.
function restore_options() {
  // Use default value color = 'red' and likesColor = true.
    favoriteColor: 'red',
    likesColor: true
  }, function(items) {
    document.getElementById('color').value = items.favoriteColor;
    document.getElementById('like').checked = items.likesColor;
document.addEventListener('DOMContentLoaded', restore_options);


Options pages embedded inside chrome://extensions have some subtle behavior you should consider while writing them, mostly caused by not being hosted inside their own tabs.

Linking to your options page

If you want to link to your options page, call chrome.runtime.openOptionsPage(). This has been available since Chrome 42.

Linking directly to chrome-extension://yourextensionid/youroptionspage.html will be a bad user experience. Linking directly to chrome://extensions?options=yourextensionid isn't advisable either, as Chrome may change the embedding URL in the future.

chrome.runtime.openOptionsPage() will always open the canonical location, and has nice behavior like re-focusing an open options page if there is one.

<button id="go-to-options">Go to options</button>
document.querySelector('#go-to-options').addEventListener(function() {
  if (chrome.runtime.openOptionsPage) {
    // New way to open options pages, if supported (Chrome 42+).
  } else {
    // Reasonable fallback.

Tabs API

Options page code cannot assume that it's hosted inside a tab, and this may affect how the Tabs API can be used. For example,

It is easy to work around these issues or use alternative APIs. Generally speaking you shouldn't need to manipulate the tab containing your extensions options page.

You can use runtime.connect and runtime.sendMessage because your options page is an extension page.

Messaging APIs

If your options page sends a message using runtime.connect or runtime.sendMessage, the Sender's tab won't be set, and the Sender's URL will be your options page URL.


The embedded dialogue should automatically determine its own size based on the options page content. However, the dialogue may not find a good size for some types of options pages. This problem is most common for options pages that adjust their size based on window size.

If this is an issue, provide fixed minimum dimensions for the options page to ensure that the dialogue will find an appropriate size.

Migrating from old options pages

At least until Chrome 40 is stable, you should specify both the options_ui and the options_page fields.

Older versions of Chrome will only recognize options_page, and only open in tabs. Chrome 40 and onwards prefer to use the options_ui field if it's specified.

The options_ui manifest field and embedded extension options were introduced in Chrome 40. Prior to these changes, options pages were always displayed in new tabs and were declared using the options_page field:

  "name": "My extension",
  "options_page": "options.html"

See this document for full details.

Chrome will continue to support the options_page manifest field, but new and existing extensions should use the options_ui to ensure that their options pages are displayed as intended.

If you specify both, Chrome 40 and onwards will ignore the value of options_page.

In a future version of Chrome, any extension which specifies options_page will change to match the options_ui behavior - most importantly, they will always be embedded in chrome://extensions - so migrate as soon as possible.