Earlier this year Google’s Chrome browser landed official support for extensions. This is incredibly exciting, not only because extending browsers is cool, but because Chrome’s extensions are fully based on open web standards. And who knows about open web standards? Yup, web hackers.

In other words, if you can build a website, you can build a Chrome extension. They don’t consist of anything else but HTML, CSS, JavaScript, HTML5ish features such as localStorage and <canvas>, and some APIs (implemented in JavaScript) to interact with the browser itself. It’s much easier than developing extensions for Firefox, which has a complicated setup and configuration and the XUL language to work with Firefox’s user interface. (Admittedly, Mozilla is trying to rectify this through Jetpack, which I haven’t looked into closely, but is not included by default in Firefox.) Another advantage of Chrome over Firefox is that Chrome can reload extensions without restarting the browser, which is a fair bit nicer!

Let’s see about building a very simple extension that will alert “Hello world” for every page you load. This will help cover the basics of extension development. First, open up the Extensions overview, which is under the Tools menu in the toolbar. This page shows the extensions you’ve already installed. It also has a Developer mode, which you can select by clicking on the “Developer mode” link in the top right. This should show a few extra options: “Load unpacked extension…”, “Pack extension…” and “Update extensions now”.

We’ll focus on “Load unpacked extension…” first. If you click on it a folder selector dialog will come up. It only lets you select folders, which is great because a Chrome extension is nothing more than a folder with a few files! In the folder selector, go to your Documents folder and open it. Chrome will try to open the Documents folder as an extension, which, of course, is silly. Luckily it finds out quickly and gives this error message:

Could not load extension from ‘/Users/mark/Documents’. Manifest file is missing or unreadable.

This then brings us to what a Chrome extension really is: a manifest file inside a folder. More specifically, a file called manifest.json, that contains a valid JSON object describing your extension. At the very minimum, a manifest file looks like this:

{
  "name": "Hello World",
  "version": "1.0"
}

Create a hello_world directory somewhere on your computer, and place the above in manifest.json (inside that directory). Now in Chrome, click on “Load unpacked extension…” again and open the hello_world directory you just created. You’ll see how the extension is added to the list of installed extensions. Congrats, you just build your first Chrome extension!

Uhm, okay, technically the extension doesn’t do anything yet. There are a few different ways an extension can interact with the browser, but for now we’ll just look at content scripts. These allow you to run JavaScript for pages visited. If you’ve ever written a user script for Greasemonkey you’ll be familiar with content scripts, since they do pretty much the same thing. In fact, Aaron Boodman, who originally started Greasemonkey, is a main driving force behind Chrome extensions.

An extension can define multiple content scripts, each of which can load multiple JavaScript files. First create alert.js in the hello_world folder, it should contain:

alert("Hello world");

To load this for all web pages we use the following manifest:

{
  "name": "Hello World",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["alert.js"]
    }
  ]
}

content_scripts is an array, each item being a declaration of the actual content script. matches lets you specify on which pages you want your content script to work, by providing a set of match patterns. js specifies which JavaScript files (included in your extension folder) to load if the page matches. (And yes, technically speaking this content script only works with http:// sites, not https://.)

In the Extensions overview, click the “Reload” link underneath the “Hello World” extension. This will reload the extension. Then go to any website and you should see a “Hello World” alert as it loads.

You can also specify CSS files that should be included on the matched pages. Create red.css (again in the hello_world folder) containing the following:

html, body { background: red !important; background-image: none !important; }

Change the manifest to:

{
  "name": "Hello World",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "css": ["red.css"],
      "js": ["alert.js"]
    }
  ]
}

Save and reload the extension. Again go to any webpage and it should now have a red background color.

Admittedly this example extension is rather contrived. In future articles we’ll build more advanced extensions, look at different UI concepts supported by Chrome extensions, Chrome’s security model and how you can publish your extensions for others to use. In the meantime, have a look at the official documentation for Chrome extensions.

As a final note, I’ll be speaking about Chrome Extensions on the Scandinavian Web Developer Conference in Stockholm on June 2nd. Go check it out!

One response