Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / common / extensions / docs / templates / articles / optionsV2.html
blob139f3e50ba8585a40485556a7259ecd5b5a7b2e1
1 <h1>Options</h1>
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>, or you can
6 <a href="#migration">start migrating now</a>.
7 </p>
9 <p>
10 To allow users to customize the behavior of your extension, you may wish to
11 provide an options page.
13 <p>
14 If you do, an Options link will be shown on the extensions management page at
15 <em>chrome://extensions</em> which opens a dialogue containing your options
16 page:
17 </p>
19 <img src="{{static}}/images/options-ui.png" alt="Options UI screenshot">
21 <p>
22 Always use the $(ref:storage.sync) API to persist your options. This will
23 make them accessible from script within your extension, on all of your user's
24 devices.
25 </p>
27 <h2 id="step-1">Step 1: Declare your options page in the manifest</h2>
29 <p>
30 Use the <code>options_ui</code> manifest field to declare the options page and
31 how it should be displayed:
32 </p>
34 <pre data-filename="manifest.json">
36 "name": "My extension",
37 ...
38 <b>"options_ui"</b>: {
39 // Required.
40 <b>"page": "options.html"</b>,
41 // Recommended.
42 <b>"chrome_style": true,</b>
43 // Not recommended; only provided for backwards compatibility,
44 // and will be unsupported in a future version of Chrome (TBD).
45 <b>//"open_in_tab": true</b>
47 ...
49 </pre>
51 {{+partials.manifest_type
52 type:apis.extensions.extensionsManifestTypes.byName.OptionsUI /}}
54 <h2 id="step-2">Step 2: Write your options page</h2>
56 <p>
57 Here's an example, including an options page and JavaScript to persist the
58 options:
59 </p>
61 <pre data-filename="options.html">
62 &lt;!DOCTYPE html&gt;
63 &lt;html&gt;
64 &lt;head&gt;
65 &lt;title&gt;My Test Extension Options&lt;/title&gt;
66 &lt;style&gt;
67 body: { padding: 10px; }
68 &lt;/style&gt;
69 &lt;/head&gt;
71 &lt;body&gt;
72 Favorite color:
73 &lt;select id="color"&gt;
74 &lt;option value="red"&gt;red&lt;/option&gt;
75 &lt;option value="green"&gt;green&lt;/option&gt;
76 &lt;option value="blue"&gt;blue&lt;/option&gt;
77 &lt;option value="yellow"&gt;yellow&lt;/option&gt;
78 &lt;/select&gt;
80 &lt;label&gt;
81 &lt;input type="checkbox" id="like"&gt;
82 I like colors.
83 &lt;/label&gt;
85 &lt;div id="status"&gt;&lt;/div&gt;
86 &lt;button id="save"&gt;Save&lt;/button&gt;
88 &lt;script src="options.js"&gt;&lt;/script&gt;
89 &lt;/body&gt;
90 &lt;/html&gt;
91 </pre>
93 <pre data-filename="options.js">
94 // Saves options to chrome.storage.sync.
95 function save_options() {
96 var color = document.getElementById('color').value;
97 var likesColor = document.getElementById('like').checked;
98 chrome.storage.sync.set({
99 favoriteColor: color,
100 likesColor: likesColor
101 }, function() {
102 // Update status to let user know options were saved.
103 var status = document.getElementById('status');
104 status.textContent = 'Options saved.';
105 setTimeout(function() {
106 status.textContent = '';
107 }, 750);
111 // Restores select box and checkbox state using the preferences
112 // stored in chrome.storage.
113 function restore_options() {
114 // Use default value color = 'red' and likesColor = true.
115 chrome.storage.sync.get({
116 favoriteColor: 'red',
117 likesColor: true
118 }, function(items) {
119 document.getElementById('color').value = items.favoriteColor;
120 document.getElementById('like').checked = items.likesColor;
123 document.addEventListener('DOMContentLoaded', restore_options);
124 document.getElementById('save').addEventListener('click',
125 save_options);
126 </pre>
128 <h2 id="considerations">Considerations</h2>
131 Options pages embedded inside <em>chrome://extensions</em> have some subtle
132 behavior you should consider while writing them, mostly caused by not being
133 hosted inside their own tabs.
134 </p>
136 <h3 id="linking">Linking to your options page</h3>
139 If you want to link to your options page, call
140 <code>$(ref:runtime.openOptionsPage chrome.runtime.openOptionsPage())</code>.
141 This has been available since Chrome 42.
142 </p>
145 Linking directly to
146 <em style="white-space:nowrap">chrome-extension://<strong>yourextensionid/youroptionspage.html</strong></em>
147 will be a bad user experience. Linking directly to
148 <em style="white-space:nowrap">chrome://extensions<strong>?options=yourextensionid</strong></em>
149 isn't advisable either, as Chrome may change the embedding URL in the future.
152 <code>$(ref:runtime.openOptionsPage chrome.runtime.openOptionsPage())</code>
153 will always open the canonical location, and has nice behavior like re-focusing
154 an open options page if there is one.
155 </p>
157 <pre data-filename="popup.html">
158 &lt;button id="go-to-options"&gt;Go to options&lt;/button&gt;
159 </pre>
160 <pre data-filename="popup.js">
161 document.querySelector('#go-to-options').addEventListener(function() {
162 if (chrome.runtime.openOptionsPage) {
163 // New way to open options pages, if supported (Chrome 42+).
164 chrome.runtime.openOptionsPage();
165 } else {
166 // Reasonable fallback.
167 window.open(chrome.runtime.getURL('options.html'));
170 </pre>
172 <h3 id="tabs-api">Tabs API</h3>
174 Options page code cannot assume that it's hosted inside a tab, and this may
175 affect how the $(ref:tabs Tabs API) can be used. For example,
176 <ul>
177 <li>$(ref:tabs.query) will never find a tab with your extension's options
178 page URL.</li>
179 <li>$(ref:tabs.onCreated) will not fire when your options page is
180 opened.</li>
181 <li>$(ref:tabs.onUpdated) will not fire when your options page load state
182 changes.</li>
183 <li>You cannot use $(ref:tabs.connect) or $(ref:tabs.sendMessage) to
184 communicate with your options page.</li>
185 </ul>
186 </p>
188 It is easy to work around these issues or use alternative APIs. Generally
189 speaking you shouldn't need to manipulate the tab containing your extensions
190 options page.
191 </p>
193 You can use $(ref:runtime.connect) and $(ref:runtime.sendMessage) because your
194 options page is an extension page.
195 </p>
197 <h3 id="messaging-api">Messaging APIs</h3>
199 If your options page sends a message using $(ref:runtime.connect) or
200 $(ref:runtime.sendMessage), the $(ref:runtime.MessageSender.tab Sender's tab)
201 won't be set, and the $(ref:runtime.MessageSender.url Sender's URL) will be
202 your options page URL.
203 </p>
205 <h3 id="sizing">Sizing</h3>
207 The embedded dialogue should automatically determine its own size based on the
208 options page content. However, the dialogue may not find a good size for some
209 types of options pages. This problem is most common for options pages that
210 adjust their size based on window size.
211 </p>
213 If this is an issue, provide fixed minimum dimensions for the options page to
214 ensure that the dialogue will find an appropriate size.
215 </p>
217 <h2 id="migration">Migrating from old options pages</h2>
218 <p class="warning">
219 At least until Chrome 40 is stable, you should specify <strong>both</strong>
220 the <code>options_ui</code> <strong>and</strong> the <code>options_page</code>
221 fields.
222 <br><br>
223 Older versions of Chrome will only recognize <code>options_page</code>, and
224 only open in tabs. Chrome 40 and onwards prefer to use the
225 <code>options_ui</code> field if it's specified.
226 </p>
229 The <code>options_ui</code> manifest field and embedded extension options
230 were introduced in Chrome 40. Prior to these changes, options pages were always
231 displayed in new tabs and were declared using the <code>options_page</code>
232 field:
233 </p>
235 <pre data-filename="manifest.json">
237 "name": "My extension",
239 "options_page": "options.html"
242 </pre>
244 See <a href="options">this document</a> for full details.
245 </p>
248 Chrome will continue to support the <code>options_page</code> manifest field,
249 but new and existing extensions should use the <code>options_ui</code> to
250 ensure that their options pages are displayed as intended.
251 </p>
253 If you specify both, Chrome 40 and onwards will ignore the value of
254 <code>options_page</code>.
255 </p>
257 In a future version of Chrome, any extension which specifies
258 <code>options_page</code> will change to match the <code>options_ui</code>
259 behavior - most importantly, they will always be embedded in
260 <em>chrome://extensions</em> - so migrate as soon as possible.
261 </p>