OLD | NEW |
(Empty) | |
| 1 <h1>Options</h1> |
| 2 |
| 3 <p class="warning"> |
| 4 This new way of writing options is only supported from Chrome 40 onwards. |
| 5 <a href="options">See the old documentation</a>. |
| 6 </p> |
| 7 |
| 8 <p> |
| 9 To allow users to customize the behavior of your extension, you may wish to |
| 10 provide an options page. |
| 11 |
| 12 <p> |
| 13 If you do, an Options link will be shown on the extensions management page at |
| 14 <em>chrome://extensions</em> which opens a dialogue containing your options |
| 15 page: |
| 16 </p> |
| 17 |
| 18 <img src="{{static}}/images/options-ui.png" alt="Options UI screenshot"> |
| 19 |
| 20 <p> |
| 21 Always use the $(ref:storage.sync) API to persist your options. This will |
| 22 make them accessible from script within your extension, on all of your user's |
| 23 devices. |
| 24 </p> |
| 25 |
| 26 <h2 id="step-1">Step 1: Declare your options page in the manifest</h2> |
| 27 |
| 28 <p> |
| 29 Use the <code>options_ui</code> manifest field to declare the options page and |
| 30 how it should be displayed: |
| 31 </p> |
| 32 |
| 33 <pre data-filename="manifest.json"> |
| 34 { |
| 35 "name": "My extension", |
| 36 ... |
| 37 <b>"options_ui"</b>: { |
| 38 // Required. |
| 39 <b>"page": "options.html"</b>, |
| 40 // Recommended. |
| 41 <b>"chrome_style": true,</b> |
| 42 // Not recommended; only provided for backwards compatibility, |
| 43 // and will be unsupported in a future version of Chrome (TBD). |
| 44 <b>//"open_in_tab": true</b> |
| 45 }, |
| 46 ... |
| 47 } |
| 48 </pre> |
| 49 |
| 50 {{+partials.manifest_type |
| 51 type:apis.extensions.extensionsManifestTypes.byName.OptionsUI /}} |
| 52 |
| 53 <h2 id="step-2">Step 2: Write your options page</h2> |
| 54 |
| 55 <p> |
| 56 Here's an example, including an options page and JavaScript to persist the |
| 57 options: |
| 58 </p> |
| 59 |
| 60 <pre data-filename="options.html"> |
| 61 <!DOCTYPE html> |
| 62 <html> |
| 63 <head> |
| 64 <title>My Test Extension Options</title> |
| 65 <style> |
| 66 body: { padding: 10px; } |
| 67 </style> |
| 68 </head> |
| 69 |
| 70 <body> |
| 71 Favorite color: |
| 72 <select id="color"> |
| 73 <option value="red">red</option> |
| 74 <option value="green">green</option> |
| 75 <option value="blue">blue</option> |
| 76 <option value="yellow">yellow</option> |
| 77 </select> |
| 78 |
| 79 <label> |
| 80 <input type="checkbox" id="like"> |
| 81 I like colors. |
| 82 </label> |
| 83 |
| 84 <div id="status"></div> |
| 85 <button id="save">Save</button> |
| 86 |
| 87 <script src="options.js"></script> |
| 88 </body> |
| 89 </html> |
| 90 </pre> |
| 91 |
| 92 <pre data-filename="options.js"> |
| 93 // Saves options to chrome.storage.sync. |
| 94 function save_options() { |
| 95 var color = document.getElementById('color').value; |
| 96 var likesColor = document.getElementById('like').checked; |
| 97 chrome.storage.sync.set({ |
| 98 favoriteColor: color, |
| 99 likesColor: likesColor |
| 100 }, function() { |
| 101 // Update status to let user know options were saved. |
| 102 var status = document.getElementById('status'); |
| 103 status.textContent = 'Options saved.'; |
| 104 setTimeout(function() { |
| 105 status.textContent = ''; |
| 106 }, 750); |
| 107 }); |
| 108 } |
| 109 |
| 110 // Restores select box and checkbox state using the preferences |
| 111 // stored in chrome.storage. |
| 112 function restore_options() { |
| 113 // Use default value color = 'red' and likesColor = true. |
| 114 chrome.storage.sync.get({ |
| 115 favoriteColor: 'red', |
| 116 likesColor: true |
| 117 }, function(items) { |
| 118 document.getElementById('color').value = items.favoriteColor; |
| 119 document.getElementById('like').checked = items.likesColor; |
| 120 }); |
| 121 } |
| 122 document.addEventListener('DOMContentLoaded', restore_options); |
| 123 document.getElementById('save').addEventListener('click', |
| 124 save_options); |
| 125 </pre> |
| 126 |
| 127 <h2 id="considerations">Considerations</h2> |
| 128 |
| 129 <p> |
| 130 Options pages embedded inside <em>chrome://extensions</em> have some subtle |
| 131 behavior you should consider while writing them, mostly caused by not being |
| 132 hosted inside their own tabs. |
| 133 </p> |
| 134 |
| 135 <h3 id="tabs-api">Tabs API</h3> |
| 136 <p> |
| 137 Options page code cannot assume that it's hosted inside a tab, and this may |
| 138 affect how the $(ref:tabs Tabs API) can be used. For example, |
| 139 <ul> |
| 140 <li>$(ref:tabs.query) will never find a tab with your extension's options |
| 141 page URL.</li> |
| 142 <li>$(ref:tabs.onCreated) will not fire when your options page is |
| 143 opened.</li> |
| 144 <li>$(ref:tabs.onUpdated) will not fire when your options page load state |
| 145 changes.</li> |
| 146 <li>You cannot use $(ref:tabs.connect) or $(ref:tabs.sendMessage) to |
| 147 communicate with your options page.</li> |
| 148 </ul> |
| 149 </p> |
| 150 <p> |
| 151 It is easy to work around these issues or use alternative APIs. Generally |
| 152 speaking you shouldn't need to manipulate the tab containing your extensions |
| 153 options page. |
| 154 </p> |
| 155 <p> |
| 156 You can use $(ref:runtime.connect) and $(ref:runtime.sendMessage) because your |
| 157 options page is an extension page. |
| 158 </p> |
| 159 |
| 160 <h3 id="messaging-api">Messaging APIs</h3> |
| 161 <p> |
| 162 If your options page sends a message using $(ref:runtime.connect) or |
| 163 $(ref:runtime.sendMessage) then the $(ref:runtime.MessageSender.tab Tab's) URL |
| 164 and $(ref:runtime.MessageSender.url MessageSender's URL) properties won't agree |
| 165 - the tab URL will be of <em>chrome://settings</em> while the URL will be your |
| 166 options page URL. |
| 167 </p> |
| 168 |
| 169 <h3 id="sizing">Sizing</h3> |
| 170 <p> |
| 171 The embedded dialogue should automatically determine its own size based on the |
| 172 options page content. However, the dialogue may not find a good size for some |
| 173 types of options pages. This problem is most common for options pages that |
| 174 adjust their size based on window size. |
| 175 </p> |
| 176 <p> |
| 177 If this is an issue, provide fixed minimum dimensions for the options page to |
| 178 ensure that the dialogue will find an appropriate size. |
| 179 </p> |
| 180 |
| 181 <h2 id="migration">Migrating from old options pages</h2> |
| 182 <p class="warning"> |
| 183 At least until Chrome 40 is stable, you should specify <strong>both</strong> |
| 184 the <code>options_ui</code> <strong>and</strong> the <code>options_page</code> |
| 185 fields. |
| 186 <br><br> |
| 187 Older versions of Chrome will only recognize <code>options_page</code>, and |
| 188 only open in tabs. Chrome 40 and onwards prefers to use the |
| 189 <code>options_ui</code> field if it's specified. |
| 190 </p> |
| 191 |
| 192 The <code>options_ui</code> manifest field and embedded extension options |
| 193 were introduced in Chrome 40. Prior to these changes, options pages were always |
| 194 displayed in new tabs and were declared using the <code>options_page</code> |
| 195 field: |
| 196 </p> |
| 197 |
| 198 <pre data-filename="manifest.json"> |
| 199 { |
| 200 "name": "My extension", |
| 201 ... |
| 202 "options_page": "options.html" |
| 203 ... |
| 204 } |
| 205 </pre> |
| 206 <p> |
| 207 See <a href="options">this document</a> for full details. |
| 208 </p> |
| 209 |
| 210 <p> |
| 211 Chrome will continue to support extensions that use the legacy |
| 212 <code>options_page</code> manifest field, but new and existing extensions |
| 213 should use the <code>options_ui</code> manifest field to ensure that their |
| 214 options pages are displayed as intended. |
| 215 </p> |
| 216 <p> |
| 217 If you specify both, Chrome 40 and onwards will ignore the value of |
| 218 <code>options_page</code>. |
| 219 </p> |
| 220 <p> |
| 221 In a future version of Chrome, any extension which specifies |
| 222 <code>options_page</code> will change to match the <code>options_ui</code> |
| 223 behavior - most importantly, they will always be embedded in |
| 224 <em>chrome://extensions</em> - so migrate as soon as possible. |
| 225 </p> |
OLD | NEW |