| OLD | NEW |
| 1 <h1>Getting Started: Building a Chrome Extension</h1> | 1 <h1>Getting Started: Building a Chrome Extension</h1> |
| 2 | 2 |
| 3 <p> | 3 <p> |
| 4 Extensions allow you to add functionality to Chrome without diving deeply | 4 Extensions allow you to add functionality to Chrome without diving deeply |
| 5 into native code. You can create new extensions for Chrome with those core | 5 into native code. You can create new extensions for Chrome with those core |
| 6 technologies that you're already familiar with from web development: HTML, | 6 technologies that you're already familiar with from web development: HTML, |
| 7 CSS, and JavaScript. If you've ever built a web page, you should feel right at | 7 CSS, and JavaScript. If you've ever built a web page, you should feel right at |
| 8 home with extensions pretty quickly; we'll put that to the test right now by | 8 home with extensions pretty quickly; we'll put that to the test right now by |
| 9 walking through the construction of a simple extension that will give you | 9 walking through the construction of a simple extension that will fetch an |
| 10 one-click access to pictures of kittens. Kittens! | 10 image from Google using the current page's URL as a search term. |
| 11 </p> | 11 </p> |
| 12 | 12 |
| 13 <p> | 13 <p> |
| 14 We'll do so by implementing a UI element we call a | 14 We'll do so by implementing a UI element we call a |
| 15 <a href="browserAction">browser action</a>, which allows us to place a | 15 <a href="browserAction">browser action</a>, which allows us to place a |
| 16 clickable icon right next to Chrome's Omnibox for easy access. Clicking that | 16 clickable icon right next to Chrome's Omnibox for easy access. Clicking that |
| 17 icon will open a popup window filled with kittenish goodness, which will look | 17 icon will open a popup window filled with an image derived from the current |
| 18 something like this: | 18 page, which will look something like this: |
| 19 </p> | 19 </p> |
| 20 | 20 |
| 21 <img src="{{static}}/images/gettingstarted-1.jpg" | 21 <img src="{{static}}/images/gettingstarted-preview" |
| 22 width="600" | 22 width="558" |
| 23 height="420" | 23 height="264" |
| 24 alt="Chrome, with an extension's popup open and displaying many kittens."> | 24 alt="Chrome with an extension's popup open."> |
| 25 | 25 |
| 26 <p> | 26 <p> |
| 27 If you'd like to follow along at home (and you should!), create a shiny new | 27 If you'd like to follow along at home (and you should!), create a shiny new |
| 28 directory on your computer, and pop open your favourite text editor. Let's get | 28 directory on your computer, and pop open your favourite text editor. Let's get |
| 29 going! | 29 going! |
| 30 </p> | 30 </p> |
| 31 | 31 |
| 32 <h2 id="declaration">Something to Declare</h2> | 32 <h2 id="declaration">Something to Declare</h2> |
| 33 | 33 |
| 34 <p> | 34 <p> |
| 35 The very first thing we'll need to create is a <dfn>manifest file</dfn> named | 35 The very first thing we'll need to create is a <dfn>manifest file</dfn> named |
| 36 <code>manifest.json</code>. The manifest is nothing more than a JSON-formatted | 36 <code>manifest.json</code>. This manifest is nothing more than a metadata file |
| 37 table of contents, containing properties like your extension's name and | 37 in JSON format that contains properties like your extension's name, |
| 38 description, its version number, and so on. At a high level, we'll use it to | 38 description, version number and so on. At a high level, we will use it to |
| 39 declare to Chrome what the extension is going to do, and what permissions it | 39 declare to Chrome what the extension is going to do, and what permissions it |
| 40 requires in order to do those things. | 40 requires in order to do those things. To learn more about the manifest, read |
| 41 the <a href="manifest">Manifest File Format documentation</a>. |
| 41 </p> | 42 </p> |
| 42 | 43 |
| 43 <p> | 44 <p> |
| 44 In order to display kittens, we'll want to tell Chrome that we'd like to | 45 In our example's manifest, |
| 45 create a browser action, and that we'd like free-reign to access kittens from | 46 we will declare a <a href="browserAction">browser action</a>, |
| 46 a particular source on the net. A manifest file containing those instructions | 47 the <a href="activeTab">activeTab permission</a> to see the URL of the current |
| 47 looks like this: | 48 tab, and the host <a href="declare_permissions">permission</a> to access the |
| 49 external Google Image search API. |
| 48 </p> | 50 </p> |
| 49 | 51 |
| 50 <pre data-filename="manifest.json"> | 52 <pre data-filename="manifest.json"> |
| 51 { | 53 { |
| 52 "manifest_version": 2, | 54 "manifest_version": 2, |
| 53 | 55 |
| 54 "name": "One-click Kittens", | 56 "name": "Getting started example", |
| 55 "description": "This extension demonstrates a browser action with kittens.", | 57 "description": "This extension shows a Google Image search result for the curr
ent page", |
| 56 "version": "1.0", | 58 "version": "1.0", |
| 57 | 59 |
| 58 "permissions": [ | |
| 59 "https://secure.flickr.com/" | |
| 60 ], | |
| 61 "browser_action": { | 60 "browser_action": { |
| 62 "default_icon": "icon.png", | 61 "default_icon": "icon.png", |
| 63 "default_popup": "popup.html" | 62 "default_popup": "popup.html" |
| 64 } | 63 }, |
| 64 "permissions": [ |
| 65 "activeTab", |
| 66 "https://ajax.googleapis.com/" |
| 67 ] |
| 65 } | 68 } |
| 66 </pre> | 69 </pre> |
| 67 | 70 |
| 68 <p> | 71 <p> |
| 69 Go ahead and save that data to a file named <code>manifest.json</code> in the | 72 Go ahead and save that data to a file named <code>manifest.json</code> in the |
| 70 directory you created, or | 73 directory you created, or |
| 71 <a href="examples/tutorials/getstarted/manifest.json" download="manifest.json"
> | 74 <a href="examples/tutorials/getstarted/manifest.json" download="manifest.json"
> |
| 72 download a copy of <code>manifest.json</code> from our sample repository | 75 download a copy of <code>manifest.json</code> from our sample repository |
| 73 </a>. | 76 </a>. |
| 74 </p> | 77 </p> |
| 75 | 78 |
| 76 <h3 id="manifest">What does it mean?</h3> | |
| 77 | |
| 78 <p> | |
| 79 The attribute names are fairly self-descriptive, but let's walk through the | |
| 80 manifest line-by-line to make sure we're all on the same page. | |
| 81 </p> | |
| 82 | |
| 83 <p> | |
| 84 The first line, which declares that we're using version 2 of the manifest file | |
| 85 format, is mandatory (version 1 is old, deprecated, and generally not | |
| 86 awesome). | |
| 87 </p> | |
| 88 | |
| 89 <p> | |
| 90 The next block defines the extension's name, description, and version. These | |
| 91 will be used both inside of Chrome to show a user which extensions you have | |
| 92 installed, and also on the Chrome Web Store to display your extension to | |
| 93 potentially new users. The name should be short and snappy, and the | |
| 94 description no longer than a sentence or so (you'll have more room for a | |
| 95 detailed description later). | |
| 96 </p> | |
| 97 | |
| 98 <p> | |
| 99 The final block first requests permission to work with data on | |
| 100 <code>https://secure.flickr.com/</code>, and declares that this extension | |
| 101 implements a browser action, assigning it a default icon and popup in the | |
| 102 process. | |
| 103 </p> | |
| 104 | |
| 105 <h2 id="resources">Resources</h2> | 79 <h2 id="resources">Resources</h2> |
| 106 | 80 |
| 107 <p> | 81 <p> |
| 108 You probably noticed that <code>manifest.json</code> pointed at two resource | 82 You probably noticed that <code>manifest.json</code> pointed at two resource |
| 109 files when defining the browser action: <code>icon.png</code> and | 83 files when defining the browser action: <code>icon.png</code> and |
| 110 <code>popup.html</code>. Both resources must exist inside the extension | 84 <code>popup.html</code>. Both resources must exist inside the extension |
| 111 package, so let's create them now: | 85 package, so let's create them now: |
| 112 </p> | 86 </p> |
| 113 | 87 |
| 114 <ul class="imaged"> | 88 <ul class="imaged"> |
| 115 <li> | 89 <li> |
| 116 <p> | 90 <p> |
| 117 <img src="{{static}}/images/gettingstarted-icon.png" | 91 <img src="{{static}}/images/gettingstarted-icon.png" |
| 118 width="127" | 92 width="127" |
| 119 height="127" | 93 height="127" |
| 94 style="float:right" |
| 120 alt="The popup's icon will be displayed right next to the Omnibox."> | 95 alt="The popup's icon will be displayed right next to the Omnibox."> |
| 121 <code>icon.png</code> will be displayed next to the Omnibox, waiting for | 96 <code>icon.png</code> will be displayed next to the Omnibox, waiting for |
| 122 user interaction. Download a copy of icon.png from our sample repository, | 97 user interaction. |
| 123 <a href="examples/tutorials/getstarted/icon.png" download="icon.png"> | 98 <a href="examples/tutorials/getstarted/icon.png" download="icon.png"> |
| 124 Download a copy of <code>icon.png</code> from our sample repository | 99 Download a copy of <code>icon.png</code> from our sample repository |
| 125 </a>, and save it into the directory you're working in. You could also | 100 </a>, and save it into the directory you're working in. You could also |
| 126 create your own if you're so inclined; it's just a 19px-square PNG file. | 101 create your own if you're so inclined; it's just a 19px-square PNG file. |
| 127 </p> | 102 </p> |
| 128 </li> | 103 </li> |
| 129 <li> | 104 <li> |
| 130 <p> | 105 <p> |
| 131 <img src="{{static}}/images/gettingstarted-popup.jpg" | |
| 132 width="165" | |
| 133 height="200" | |
| 134 alt="The popup's HTML will be rendered directly below the icon when c
licked."> | |
| 135 <code>popup.html</code> will be rendered inside the popup window that's | 106 <code>popup.html</code> will be rendered inside the popup window that's |
| 136 created in response to a user's click on the browser action. It's a | 107 created in response to a user's click on the browser action. It's a |
| 137 standard HTML file, just like you're used to from web development, giving | 108 standard HTML file, just like you're used to from web development, giving |
| 138 you more or less free reign over what the popup displays. | 109 you more or less free reign over what the popup displays. |
| 139 <a href="examples/tutorials/getstarted/popup.html" download="popup.html"> | 110 <a href="examples/tutorials/getstarted/popup.html" download="popup.html"> |
| 140 Download a copy of <code>popup.html</code> from our sample repository | 111 Download a copy of <code>popup.html</code> from our sample repository |
| 141 </a>, and save it into | 112 </a>, and save it into the directory you're working in. |
| 142 the directory you're working in. | |
| 143 </p> | 113 </p> |
| 144 <p> | 114 <p> |
| 145 <code>popup.html</code> requires an additional JavaScript file in order to | 115 The actual logic of rendering the content of the popup is implemented by |
| 146 do the work of grabbing kitten images from the web and loading them into | 116 <a href="examples/tutorials/getstarted/popup.js">popup.js</a>. You are |
| 147 the popup. To save you some effort, just | 117 encouraged to read the elaborate comments in this file to learn more |
| 118 about the logic.<br> |
| 148 <a href="examples/tutorials/getstarted/popup.js" download="popup.js"> | 119 <a href="examples/tutorials/getstarted/popup.js" download="popup.js"> |
| 149 download a copy of <code>popup.js</code> from our sample repository | 120 Download a copy of <code>popup.js</code> from our sample repository |
| 150 </a>, and save it into the directory you're working in. | 121 </a>, and save it into the directory you're working in. |
| 151 </p> | 122 </p> |
| 152 </li> | 123 </li> |
| 153 </ul> | 124 </ul> |
| 154 | 125 |
| 155 <p> | 126 <p> |
| 156 You should now have four files in your working directory: | 127 You should now have four files in your working directory: |
| 157 <a href="examples/tutorials/getstarted/icon.png" download="icon.png"><code>ico
n.png</code></a>, | 128 <a href="examples/tutorials/getstarted/icon.png" download="icon.png"><code>ico
n.png</code></a>, |
| 158 <a href="examples/tutorials/getstarted/manifest.json" download="manifest.json"
><code>manifest.json</code></a>, | 129 <a href="examples/tutorials/getstarted/manifest.json" download="manifest.json"
><code>manifest.json</code></a>, |
| 159 <a href="examples/tutorials/getstarted/popup.html" download="popup.html"><code
>popup.html</code></a>, | 130 <a href="examples/tutorials/getstarted/popup.html" download="popup.html"><code
>popup.html</code></a>, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 171 </p> | 142 </p> |
| 172 | 143 |
| 173 <ol> | 144 <ol> |
| 174 <li> | 145 <li> |
| 175 <p> | 146 <p> |
| 176 Visit <code>chrome://extensions</code> in your browser (or open up the | 147 Visit <code>chrome://extensions</code> in your browser (or open up the |
| 177 Chrome menu by clicking the icon to the far right of the Omnibox: | 148 Chrome menu by clicking the icon to the far right of the Omnibox: |
| 178 <img src="{{static}}/images/hotdogmenu.png" | 149 <img src="{{static}}/images/hotdogmenu.png" |
| 179 height="29" | 150 height="29" |
| 180 width="29" | 151 width="29" |
| 181 alt="The menu's icon is three horizontal bars.">. and | 152 alt="The menu's icon is three horizontal bars."> and |
| 182 select <strong>Extensions</strong> under the <strong>Tools</strong> menu | 153 select <strong>Extensions</strong> under the <strong>Tools</strong> menu |
| 183 to get to the same place). | 154 to get to the same place). |
| 184 </p> | 155 </p> |
| 185 </li> | 156 </li> |
| 186 <li> | 157 <li> |
| 187 <p> | 158 <p> |
| 188 Ensure that the <strong>Developer mode</strong> checkbox in the top | 159 Ensure that the <strong>Developer mode</strong> checkbox in the top |
| 189 right-hand corner is checked. | 160 right-hand corner is checked. |
| 190 </p> | 161 </p> |
| 191 </li> | 162 </li> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 212 If the extension is valid, it'll be loaded up and active right away! If it's | 183 If the extension is valid, it'll be loaded up and active right away! If it's |
| 213 invalid, an error message will be displayed at the top of the page. Correct | 184 invalid, an error message will be displayed at the top of the page. Correct |
| 214 the error, and try again. | 185 the error, and try again. |
| 215 </p> | 186 </p> |
| 216 | 187 |
| 217 <h2 id="update-code">Fiddle with Code</h2> | 188 <h2 id="update-code">Fiddle with Code</h2> |
| 218 | 189 |
| 219 <p> | 190 <p> |
| 220 Now that you've got your first extension up and running, let's fiddle with | 191 Now that you've got your first extension up and running, let's fiddle with |
| 221 things so that you have an idea what your development process might look like. | 192 things so that you have an idea what your development process might look like. |
| 222 As a trivial example, let's change the data source to search for pictures of | 193 For example, let's set a tooltip on the browser action button. |
| 223 puppies instead of kittens. | 194 </p> |
| 195 <p> |
| 196 According to the browserAction documentation, tooltips can be set by |
| 197 specifying the <code>default_title</code> key in the manifest file. Open |
| 198 <code>manifest.json</code>, and add the <code>default_title</code> key to the |
| 199 <code>browser_action</code>. |
| 200 Make sure that the JSON is valid, so quote the key and add a comma where neces
sary. |
| 201 </p> |
| 202 |
| 203 <pre data-filename="manifest.json"> |
| 204 { |
| 205 ... |
| 206 "browser_action": { |
| 207 "default_icon": "icon.png", |
| 208 "default_popup": "popup.html", |
| 209 "default_title": "Click here!" |
| 210 }, |
| 211 ... |
| 212 } |
| 213 </pre> |
| 214 |
| 215 <p> |
| 216 The manifest file is only parsed when the extension is loaded. If you want to |
| 217 see the previous changes in action, the extension has to be reloaded. |
| 218 Visit the extensions page (go to <strong>chrome://extensions</strong>, or |
| 219 <strong>Tools > Extensions</strong> under the Chrome menu), and click |
| 220 <strong>Reload</strong> under your extension. |
| 221 All extensions are also reloaded when the extensions page is reloaded, e.g. |
| 222 after hitting <kbd>F5<kbd> or <kbd>Ctrl</kbd>-<kbd>R</kbd>. |
| 224 </p> | 223 </p> |
| 225 | 224 |
| 226 <p> | 225 <p> |
| 227 Hop into <code>popup.js</code>, and edit line 11 from | 226 Once you've reloaded the extension, hover over the browser action badge to see |
| 228 <code>var QUERY = 'kittens';</code> to read | 227 the new tooltip!<br> |
| 229 <code>var QUERY = 'puppies';</code>, and save your changes. | 228 <img src="{{static}}/images/gettingstarted-tooltip-before.png" |
| 230 </p> | 229 width="160" |
| 230 height="120" |
| 231 alt=""Getting started example" tooltip."> |
| 231 | 232 |
| 232 <p> | 233 <img src="{{static}}/images/gettingstarted-tooltip-after.png" |
| 233 If you click on your extension's browser action again, you'll note that your | 234 width="160" |
| 234 change hasn't yet had an effect. You'll need to let Chrome know that something | 235 height="120" |
| 235 has happened, either explicitly by going back to the extension page | 236 alt=""Click here!" tooltip, after modifying manifest.json and r
eloading the extension."> |
| 236 (<strong>chrome://extensions</strong>, or | |
| 237 <strong>Tools > Extensions</strong> under the Chrome menu), and clicking | |
| 238 <strong>Reload</strong> under your extension, or by reloading the extensions | |
| 239 page itself (either via the reload button to the left of the Omnibox, or by | |
| 240 hitting F5 or Ctrl-R). | |
| 241 </p> | |
| 242 | |
| 243 <p> | |
| 244 Once you've reloaded the extension, click the browser action icon again. | |
| 245 Puppies galore! | |
| 246 </p> | 237 </p> |
| 247 | 238 |
| 248 <h2 id="next-steps">What next?</h2> | 239 <h2 id="next-steps">What next?</h2> |
| 249 | 240 |
| 250 <p> | 241 <p> |
| 251 You now know about the manifest file's central role in bringing things | 242 You now know about the manifest file's central role in bringing things |
| 252 together, and you've mastered the basics of declaring a browser action, and | 243 together, and you've mastered the basics of declaring a browser action. |
| 253 rendering some kittens (or puppies!) in response to a user's click. That's a | 244 That's a great start, and has hopefully gotten you interested enough to |
| 254 great start, and has hopefully gotten you interested enough to explore | 245 explore further. There's a lot more out there to play around with. |
| 255 further. There's a lot more out there to play around with. | |
| 256 </p> | 246 </p> |
| 257 | 247 |
| 258 <ul> | 248 <ul> |
| 259 <li> | 249 <li> |
| 260 <p> | 250 <p> |
| 261 The <a href="overview">Chrome Extension Overview</a> backs up a bit, | 251 The <a href="overview">Chrome Extension Overview</a> backs up a bit, |
| 262 and fills in a lot of detail about extensions' architecture in general, | 252 and fills in a lot of detail about extensions' architecture in general, |
| 263 and some specific concepts you'll want to be familiar with going forward. | 253 and some specific concepts you'll want to be familiar with going forward. |
| 264 It's the best next step on your journey towards extension mastery. | 254 It's the best next step on your journey towards extension mastery. |
| 265 </p> | 255 </p> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 280 walk you through each API in turn. | 270 walk you through each API in turn. |
| 281 </p> | 271 </p> |
| 282 </li> | 272 </li> |
| 283 <li> | 273 <li> |
| 284 <p> | 274 <p> |
| 285 Finally, the <a href="devguide">developer's guide</a> has dozens of | 275 Finally, the <a href="devguide">developer's guide</a> has dozens of |
| 286 additional links to pieces of documentation you might be interested in. | 276 additional links to pieces of documentation you might be interested in. |
| 287 </p> | 277 </p> |
| 288 </li> | 278 </li> |
| 289 </ul> | 279 </ul> |
| OLD | NEW |