Installable Web Apps

Background: Extending Your App's Life

As of Google Chrome 10, the background feature lets a hosted app run as soon as the user logs into their computer—before the user launches Chrome or the app—and to continue running even when Chrome or the app has no visible windows. However, if the user explicitly quits Chrome, the browser and app both exit.

One common use of this feature is to display notifications for events that can occur when the app's UI isn't visible—for example, a new email or chat message, important news, or a price change.

To use the background feature, an app declares the "background" permission in its manifest. Apps with "background" permission can use a background window to do miscellaneous tasks in an invisible page that can live as long as the browser runs.

Contents

  1. Example: The basics
    1. Specify "background" permission
    2. Open the background window
      1. Using "background_page" (Chrome 12+)
      2. Using window.open()
    3. Do something in the window
  2. When to use the background feature
  3. How the background feature works
  4. Writing code for the background feature
    1. Opening a background window or navigating to a new URL
    2. Closing the background window
    3. Replacing the background window
    4. Calling the opener from the background window
    5. Calling the background window from the opener
  5. More examples

Example: The basics

To use the background feature, a hosted app must declare the "background" permission in its manifest. Then it must create a background window that contains whatever code needs to run in the background.

Specify "background" permission

Here's an example of specifying the "background" permission in an app's manifest:

//In manifest.json:
{
  "name": "App Name",
  ...
  "permissions": ["background"],
  ...
}

Open the background window

Once your app has "background" permission, it can open a background window. You can do this in either of two ways:

Version note: Before Chrome 12, window.open() was the only way to open a background window. You should avoid using "background_page" in published apps until Chrome 12 has been released on the Stable channel. For information about Stable channel releases, see the Google Chrome Releases blog.

Using "background_page" (Chrome 12+)

If you want the background window to open as soon as your app is installed—even if the app is never launched—put a "background_page" field in the app's manifest. When you specify a URL with "background_page", a background window opens every time the browser launches, running the contents of that URL. Once your app launches, it can close the background window or navigate it to a new URL.

Here's how you use the "background_page" field in an app's manifest:

//In manifest.json:
{
  "name": "App Name",
  ...
  "permissions": ["background"],
  "background_page": "https://somePath/background.html#0",
  ...
}

The URL for the "background_page" value must be an HTTPS URL. If the URL is covered by the "urls" field in the manifest, then the background window is in the same process as the app and can be called by the app. The fragment identifier ("#0") at the end of the URL is optional; see the performance tip for details on why you might want to use it.

Note: During development, you can specify a non-HTTPS URL for "background_page" by launching Chrome with the --allow-http-background-page flag. On Windows, you can do this by modifying the properties of the shortcut that you use to launch Google Chrome. For example: path_to_chrome.exe --allow-http-background-page

Using window.open()

Using window.open() instead of "background_page" lets you control when the window opens, and it lets you change which URL the window opens. After the app has launched for the first time, you have the option of opening the background window whenever the browser launches.

Note: Although window.open() gives you more flexibility than "background_page", you should use "background_page" if you need the background window to open before the app has ever launched. Because your app must explicitly invoke window.open(), if you don't use "background_page" your app's background window can't be loaded until your app has run and used window.open() to open a background window.

To open a background window with this technique, use the standard window.open() method, specifying "background" as the third argument:

//In the app's launch page:
...
if (window.chrome && window.chrome.app && window.chrome.app.isInstalled) {
  window.open("background.html#0", "bg", "background");
  ...
}
...

That call to window.open() creates a background window only if the app has "background" permission and it doesn't already have a background window. See Opening a background window for details.

Do something in the window

You can put any code you like in the background window. This code goes in the HTML file that you specified with "background_page" or window.open(); in the preceding code snippets, this is a file named background.html. Here's an example of background window code that brings up a notification.

//In the background window's page (for example, background.html):
<html>
<script>
  var notification = webkitNotifications.createNotification("",
      "Simple Background App",
      "A background window has been created");
  notification.show();
</script>
</html>

When to use the background feature

Use the background feature when you want your app to always be running. The following table shows some common use cases.

Use case Example
Notifications A stock market app that notifies the user about changes in the price of a set of stocks
Downloading data from a server A book reader app that downloads book info automatically, so that it always has the latest data and startup is faster
Uploading data to a server A picture uploader that can send data to the server even when the app's window isn't visible
Preparing the UI An app with a complex UI that preloads the UI, instead of creating or loading the UI when the user explicitly launches the app

Note: The HTML5 application cache API is a natural fit here; you can use it to preemptively download the components for your app
Playing audio A radio app that offers the option of continuing to play even when the app's window isn't open
Performing computations An app that performs complex computations in the background, either for its own work or in support of a distributed computing effort

Back to top

How the background feature works

To understand how the background feature works, you first need to know how hosted apps normally execute, without the background feature. A hosted app normally starts executing when the user visits a page in the app or clicks the app's icon in Chrome's New Tab page. When the user closes all tabs for that app, the app stops executing.

The "background" permission changes the way Chrome starts up. If any hosted apps, packaged apps, or extensions are installed that have "background" permission, Chrome starts up (without displaying any windows) as soon as the user logs in.

Each time Chrome starts up, it opens all URLs specified by "background_page", plus it reopens any other background windows that were open the last time Chrome shut down. Chrome records the URL for each background window at the time that the window is created. If the background window navigates to a new URL, that new URL isn't recorded.

Each app can have at most one background window open at a time. Unless the app uses "background_page", if an app closes its background window without opening a new one, Chrome won't create a background window for that app when Chrome starts up.

Extension API note: Extensions and packaged apps can use "background" and "background_page", either separately or together. However, they can't close background pages or navigate them to new URLs. For details, see Background Pages in the extensions documentation.

Back to top

Writing code for the background feature

The following sections have details about the code you need to write for background windows and the pages that interact with them.

This discussion is relevant even if you use the "background_page" feature. Just keep in mind that the name of the window created using "background_page" is "background". For example, to close the background window, you can use the following code:

var bgWindow = window.open(bgUrl, "background", "background");
bgWindow.close();

Opening a background window or navigating to a new URL

If your app has no background window open, calling window.open(bgUrl, BG_WIN_NAME, "background") opens a new background window and (unless you used "background_page") records bgUrl as the URL to be used at startup, when Chrome opens your app's background window.

If your app does have a background window open, calling window.open(bgUrl, BG_WIN_NAME, "background") with a new URL makes the existing background window navigate to the new URL, rather than opening a new window. In this case, Chrome doesn't record the new URL, and at startup Chrome opens the background window using its original URL.

Before your app calls window.open(), it should check a few things:

  • Make sure your app has the ability to open a background window
    • You can't ask whether your app has "background" permission, but you can check whether it's installed in a Chrome browser. To do this, check the window.chrome.app.isInstalled property.
  • Check whether you need to close an already open background window
    • Skip this check if your app uses only one URL for the background window. Nothing bad happens if you reopen an existing background window, as long as the window's name is the same.
    • Do you want Chrome to use the new URL at startup? If so, you should close the already open background window. (Skip this check if your app uses "background_page"; you can't change the URL it uses at startup.)

To open a background window or switch to a new URL, use window.open(bgUrl, BG_WIN_NAME, "background"). For example, if the background window is implemented in a file named background.html, you might call window.open() like this:

window.open("background.html#0", "bg", "background");

Performance tip: Specifying a fragment identifier (such as #0) in the URL can improve performance when the background window is reopened. The reason is that window.open() causes a page reload if the window is already open unless a fragment identifier is present. The fragment identifier trick works with any kind of window, but it's especially useful with background windows because they tend to be long-lived and build up state over time. The fragment identifier doesn't need to point to an existing anchor.

A possible issue is that the browser might not be able to get to the URL for the background window—if there's no network connection, for example. You can use the application cache API to ensure that the background window can be loaded.

Troubleshooting

If window.open() returns undefined, check for the following causes:

  • The app isn't really installed
    Uninstall any old copies of the app and reinstall the app, being sure to use the latest copy of the app's manifest.json file. You can install the app either from a .crx file or by using the chrome://extension page's Load unpacked extension button to select the directory containing manifest.json.
  • The app's manifest doesn't specify "background" permission
    Make sure your app is in Chrome's list of background apps. To find this list, bring up the context menu for the Chrome icon that's in the Dock (Mac) or the status tray (Windows and Linux). All installed apps with "background" permission appear in this list.
  • The app's manifest doesn't have the right entries in its "urls" field
    The background window or the page that opens it might not be at a URL that was specified in the manifest; for example, it might have been redirected. Be sure that all pages in your app—including the background window—are covered by either the "urls" field or the "launch" field.

    Important: Although you can use a port number in the "launch.web_url" field, don't put port numbers in the "urls" field. Port numbers aren't necessary in "urls" because all ports are valid. Values in "urls" that have port numbers are silently ignored, leaving the corresponding pages without the requested permissions.

If you get a popup window instead of a background window, check for the following causes:

  • An argument is missing from window.open()
    You must provide all three arguments. If you try to omit the window name argument, the final argument ("background") becomes the window name for an ordinary popup.
  • You specified a different name from the current background window
    If a background window is already open for your app, you must use the same name when you attempt to reopen the window or replace it with a new background window. The easiest solution: Always specify the same value as the second argument to window.open().

A trick you can use when debugging background windows is to remove "background" from the third argument to window.open(). You'll be able to see the background window (unless Chrome's popup blocker prevents it from opening), and you can use Chrome's Developer Tools to see if any errors occurred.

Closing the background window

You close a background window using the usual window close() method. Here's an example:

//Originally opening the background window:
window.open("background.html#0", BG_WIN_NAME, "background");
...
//Closing the background window:
var bgWindow = window.open("background.html#0", BG_WIN_NAME, "background");
bgWindow.close();

In this example, the second call to window.open() has exactly the same arguments as the first call. If the background window is already open, the only effect of the second call to window.open() is to return a handle to the window. If the window isn't open, it will be opened.

Note: If you close a background window that was specified with "background_page", it will be opened again the next time Chrome starts up.

Replacing the background window

If you want to completely replace the existing background window, you need to close the existing background window and then open a new one.

Note: Unless your app's manifest contains "background_page", replacing the background window specifies a new URL to be opened when Chrome starts up.

Calling the opener from the background window

You usually shouldn't call the opener from the background window. Often, the background window has no opener, because it's either launched by Chrome on startup or persists after its opener has closed.

However, sometimes you might want call a method on the page that opened the background window, if that page is available. You can do so with code like this:

var opener = window.opener;
...
if (opener && opener.someMethod)
  opener.someMethod();

Calling the background window from the opener

Calls to window.open() can return before the background window is loaded, which means that you can't call the background window immediately after opening it.

You might be able to avoid calling the background window from the opener by putting all the necessary code in the background window's handler for window.onload.

If you want to call the background window as the result of user input, you might not need to worry about waiting for the background window to load. Your app won't get user input until the UI is available, which probably will be well after the background window loads. Here's an example of calling the background window from a button click handler.

//In the app's launch page:
var bgWindow = window.open(bgUrl, BG_WIN_NAME, "background"); 

window.onload = function() {
  //Register a button click handler that calls the background window.
  document.getElementById("schedule").onclick = function() {
    var durationSecs = parseInt(document.getElementById("durationSecs").value);
    if (durationSecs && durationSecs>0)
      bgWindow.startCountdown(durationSecs);
  };
};

If you want to be sure that the background window is open, you can use code like the following:

//In the background window:
window.bgLoaded = true; //A property that the launch page(s) can check

//In the app's launch page:
var bgWindow = window.open(bgUrl, BG_WIN_NAME, "background");
if (!bgWindow) {
  //We couldn't open the background window. 
}
...
//Check whether the property we defined in the background window is true.
if (bgWindow.bgLoaded) {
  //The background window is already loaded...
} else {
  //Register a handler to be called when the background window is done loading.
  bgWindow.addEventListener("load", bgWindowLoadedHandler);
}

Note: When designing the interaction between the background window and its opener, keep in mind that two (or more) tabs for the app might open simultaneously.

Back to top

More examples

The following examples demonstrate the background feature.

Simple background app

This very simple app lets you open and close a background window by clicking a button. You can download or view the source code. (See the README file for tips on creating your own copy to play with.) You can also install the app from background-simple.appspot.com.

Countdown

This simple app implements a countdown timer. Get the source code and details. You can install the app from the Chrome Web Store.

Back to top

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.