Mozilla

offline web applications

The network is a key component of any web application, whether it is used to download JavaScript, CSS, and HTML source files and accompanying resources (images, videos, …) or to reach web services (XMLHttpRequest and <forms>).

Yet having offline support for web applications can be very useful to users. Imagine, for example, a webmail application that allows users to read emails already in their inbox and write new messages even when they are not connected.

The mechanism used to support offline web applications can also be used to improve an application’s performance by storing data in the cache or to make data persistent between user sessions and when reloading and restoring pages.

Demo: a To Do List Manager

To see an offline web application in action, watch Vivien Nicolas’ demo (OGV, MP4), which shows a to do list manager working online and offline on an N900 running Firefox.

You can also check out the live demo of the application.

Creating your Own Offline Application

For a web application to work offline, you need to consider three things:

Let’s see how to use each of these components.

Storage: Persistent Data

DOM storage lets you store data between browser sessions, share data between tabs and prevent data loss (for example from page reloads or browser restarts). The data are stored as strings (for example a JSONified JavaScript object) in a Storage object.

There are two kinds of storage global objects: sessionStorage and localStorage.

  • sessionStorage maintains a storage area that’s available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window causes a new session to be initiated.
  • localStorage maintains a storage area that can be used to hold data over a long period of time (e.g. over multiple pages and browser sessions). It’s not destroyed when the user closes the browser or switches off the computer.

Both localStorage and sessionStorage use the following API:

window.localStorage and window.sessionStorage {
  long length; // Number of items stored
  string key(long index); // Name of the key at index
  string getItem(string key); // Get value of the key
  void setItem(string key, string data); // Add a new key with value data
  void removeItem(string key); // Remove the item key
  void clear(); // Clear the storage
};

Here is an example showing how to store and how to read a string:

// save the string
function saveStatusLocally(txt) {
  window.localStorage.setItem("status", txt);
}

// read the string
function readStatus() {
   return window.localStorage.getItem("status");
}

Note that the storage properties are limited to an HTML5 origin (scheme + hostname + non-standard port). This means that window.localStorage from http://foo.com is a different instance of window.localStorage from http://bar.com. For example, http://google.com can’t access the storage of http://yahoo.com.

Are We Offline?

Before storing data, you may want to know if the user is online or not. This can be useful, for example, to decide whether to store a value locally (client side) or to send it to the server.

Check if the user is online with the navigator.onLine property.
In addition, you can be notified of any connectivity changes by listening to the online and offline events of the window element.

Here is a very simple piece of JavaScript code, which sends your status to a server (à la twitter).

  • If you set your status and you’re online, it sends the status.
  • If you set your status and you’re offline, it stores your status.
  • If you go online and have a stored status, it sends the stored status.
  • If you load the page, are online, and have a stored status, it sends the stored status.
function whatIsYourCurrentStatus() {
  var status = window.prompt("What is your current status?");
  if (!status) return;
  if (navigator.onLine) {
    sendToServer(status);
  } else {
    saveStatusLocally(status);
  }
}

function sendLocalStatus() {
  var status = readStatus();
  if (status) {
    sendToServer(status);
    window.localStorage.removeItem("status");
  }
}


window.addEventListener("load", function() {
   if (navigator.onLine) {
     sendLocalStatus();
   }
}, true);

window.addEventListener("online", function() {
  sendLocalStatus();
}, true);

window.addEventListener("offline", function() {
  alert("You're now offline. If you update your status, it will be sent when you go back online");
}, true);

Offline Resources: the Cache Manifest

When offline, a user’s browser can’t reach the server to get any files that might be needed. You can’t always count on the browser’s cache to include the needed resources because the user may have cleared the cache, for example. This is why you need to define explicitly which files must be stored so that all needed files and resources are available when the user goes offline: HTML, CSS, JavaScript files, and other resources like images and video.

The manifest file is specified in the HTML and contains the explicit list of files that should be cached for offline use by the application.


Here is an example of the contents of a manifest file:

CACHE MANIFEST
fonts/MarketingScript.ttf
css/main.css
css/fonts.css
img/face.gif
js/main.js
index.xhtml

The MIME-Type type of the manifest file must be: text/cache-manifest.

See the documentation for more details on the manifest file format and cache behavior.

Summary

The key components you should remember to think about when making your application work offline are to store the user inputs in localStorage, create a cache manifest file, and monitor connection changes.

Visit the Mozilla Developer Center for the complete documentation.

34 comments

Comments are now closed.

  1. Paul Rouget wrote on January 7th, 2010 at 12:45 pm:

    One more thing:
    We talked about local/sessionStorage. We don’t support any databaseStorage *yet* (like Webkit does with sqlite), because we felt that we need something different, simpler (the indexed sequential storage API edited by Oracle’s Nikunj Mehta). See more details here: http://us1.campaign-archive.com/?u=168bf22f976f5a68fe5770d19&id=6c2d73c957#standards

  2. Chris wrote on January 7th, 2010 at 9:49 pm:

    Awesome i wish all browsers will support this quickly :)

  3. Eevee wrote on January 7th, 2010 at 10:33 pm:

    I miss the days when running a program and reading files without the Internet wasn’t an impressive technical feat. :(

    1. zahra wrote on January 12th, 2011 at 8:02 am:

      me too

  4. frank goossens wrote on January 8th, 2010 at 12:33 am:

    the lack of ‘structured’ storage in firefox -however correct the reasoning behind not wanting to do databasestorage with sqlite- is frustrating, especially since chrome and opera are expected to provide webdb-support. is there any roadmap for inclusion of the “indexed sequential storage API” in FF?

    that being said; the biggest problem for offline apps is cross-browser compatibility. i’ve been hacking on a cross-browser offline-enabled web application that can store data in a structured manner, using persistjs (a javascript library which abstracts access to localstorage, webdb, ie userdata behaviors, gears, flash, …) to store json-ified arrays/ objects, and application caching (using both html5′s and gears localserver). you can see the result, TrappistDB, here.

  5. Jon Rimmer wrote on January 8th, 2010 at 3:23 am:

    Isn’t there a problem with the design of localStorage? I’ve read some stuff suggesting that it’s not possible to implement the current spec in a performant way on multi-process browsers. What’s the latest on that?

  6. matt wrote on January 8th, 2010 at 4:51 am:

    Great to know in these early days of unreliable Cloud

  7. Natanael L wrote on January 8th, 2010 at 6:30 am:

    It would be nice if big files could be shared using torrents, such as on YouTube :)

  8. Cedric Dugas wrote on January 8th, 2010 at 8:33 am:

    I wish browser vendors could implement the same database storage…. its going to be a mess to get it work on safari and firefox..

  9. Pingback from Aplicaciones web offline, para que la conexión no sea problema | aNieto2K on January 8th, 2010 at 5:10 pm:

    [...] Hacks desarrolla una aplicación a modo de demostración que nos permite disponer de una lista de tareas alojada en nuestro navegador, podéis verla [...]

  10. Pingback from Aplicaciones web offline, para que la conexión no sea problema : Blogografia on January 8th, 2010 at 6:01 pm:

    [...] Hacks desarrolla una aplicación a modo de demostración que nos permite disponer de una lista de tareas alojada en nuestro navegador, podéis verla [...]

  11. nemo wrote on January 9th, 2010 at 8:11 pm:

    Cedric, localstorage works in webkit and IE8 too.
    Until the sqlite thing is ironed out, seems best to just use that. Isn’t that much of a mess.

    And even after you can finally do sql queries in firefox and safari, you’ll probably still have to wait for IE.

  12. yannski wrote on January 12th, 2010 at 7:11 am:

    One of the top thing our users wanted out of our offline app (we develop a small Product Lifecycle Management tool) is the ability to have feedback from the sync process, like “downloading 3 / 325 documents”. It was not possible at the beginning with Gears, but they eventually got it. Now, it seems that the native offline “mode” in FF cannot do the same. Or I didnd’t found the right documentation for the applicationCache javascript object… For example, I cannot access the “items” attribute described in https://developer.mozilla.org/en/nsIDOMOfflineResourceList

    Maybe you could give some pointers…

  13. Paul Rouget wrote on January 15th, 2010 at 8:05 am:

    @yannski The MDC API is wrong. The “moz” prefix is missing (mozItem for instance). We will fix that asap.

    You can check the correct API here:
    http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/offline/nsIDOMOfflineResourceList.idl

  14. yannski wrote on January 17th, 2010 at 3:44 pm:

    Well, with Firefox 3.5, window.applicationCache.mozItems seems to be always empty (or I don’t understand how to use it). Some code sample would be great…

  15. Pete wrote on February 18th, 2010 at 12:50 pm:

    Webkit like databse storage is available with https://addons.mozilla.org/de/firefox/addon/70769

  16. Aris Micro wrote on February 21st, 2010 at 6:49 pm:

    But localStorage doesn’t work if you use the file:// scheme (instead of http://) i.e. if you are offline and double-click on a local .html file.

  17. Omkar Kandarpa wrote on June 1st, 2010 at 1:21 am:

    Hi,

    You can access the current status of caching, along with pending files count using downloading,progress events of applicationCache object.

  18. Pingback from offline web applications ✩ Mozilla 웹 기술 블로그 on June 30th, 2010 at 6:32 pm:

    [...] offline web applications, 2010년 1월 7일, Paul [...]

  19. Pingback from an HTML5 offline image editor and uploader application ✩ Mozilla 웹 기술 블로그 on July 7th, 2010 at 9:22 am:

    [...] HTML5 Application Cache: 이것은 브라우저가 인터넷에 연결되어 있지 않을 때에도 사용할 수 있는 어플리케이션을 작성하게 해준다. 이것은 어플리키에션 전체를 브라우저내에 저장하고 온라인과 오프라인 이벤트에 대한 접근을 제공함으로써 어플리케이션이 언제 서버와 다시 동기화해야 할지를 알 수 있게해준다. [...]

  20. Patrick wrote on July 28th, 2010 at 4:49 am:

    Consider impel ORM for HTML5 databases (http://impel.simulacre.org/).

  21. Günter wrote on October 31st, 2010 at 5:28 am:

    Started to write an ICS/iCal ‘app’ to be used in local browser mode only and also with the goal to use only HTML/CSS/JS.
    This requires access to ics files stored with the local file system (also to use it with other applications like Lightning, etc).

    At the moment for local storage access I’m using jQuery.twFile.js which basically uses some Moz Components.classes.
    How to change that concept to use HTML5 storage so it can be used with any HTML5 platform?
    Any pointer for further info / discuss?

  22. Pedro Morais wrote on November 28th, 2010 at 9:38 am:

    I’ve written a blog post about how we made our time tracking webapp work offline.
    Might be useful as it is a real life example:
    http://blog.bitrzr.com/2010/10/html5-offline-webapps-practical-example.html

  23. Mani wrote on May 22nd, 2011 at 8:49 pm:

    Maybe a good article, I dont know… I got irritated after seeing a video downloading and I had no way of stopping it. And I know that I am paying for that bandwidth and helplessly watched the video loading.

    Probably a HTML5 downside – we have to stop the video from downloading if we are on an expensive data plan. Now I need to get a plugin to block html5 video. In future, we are going to see ads invariably loading and eating away bandwidth, flashblock used to be so good.

    To the author: cant you think from your visitor’s point of view ever, before posting that stupid HTML5 video from auto loading???? Not everyone visits your page from their unlimited home broadband.

    1. louisremi wrote on May 23rd, 2011 at 8:42 am:

      You can open about:config in your browser, read the warning message and accept it, then right-click anywhere in the list, “New” > “Integer”
      Then give the preference the name “media.preload.default” and choose 1 as the value.
      Repeat with the name “media.preload.auto” and choose 2 as the value
      You’re done :-)

      1. Mani wrote on May 23rd, 2011 at 8:54 am:

        Amazing, thanks a lot !!!

        I take back my original comment, it was unnecessary, I should have explored before posting. Sorry about it.

        Do you know any similar method for google chrome? Anyways, firefox is going to be my default till I find something for chrome.

        Thanks again :-)

  24. Pingback from Using HTML5 localStorage in Web Applications — My Girlfriend Hates This Blog on June 2nd, 2011 at 12:45 am:

    [...] http://hacks.mozilla.org/2010/01/offline-web-applications/ [...]

  25. Pingback from 解读 HTML5:建议、技巧和技术 | blog.moocss.com on June 19th, 2011 at 10:06 pm:

    [...] Mozilla Hacks: 离线网页应用程序 [...]

  26. Pingback from 解读 HTML5:建议、技巧和技术 - Leebay's Blog on July 10th, 2011 at 6:12 am:

    [...] Mozilla Hacks: Offline Web Applications [...]

  27. Pingback from Get off(line) | Web Directions on July 11th, 2011 at 4:05 am:

    [...] SitePointStandardists Estelle Weyl’s take on offline web appsMore fromthe folks at Mozilla on building offline web appsOpera Developers Network on building offline web apps.Critiques and gotchasas we know, all is not [...]

  28. Pingback from Taking your web sites and apps offline with the HTML5 appcache « van der Straten on July 19th, 2011 at 12:57 pm:

    [...] More fromthe folks at Mozilla on building offline web apps [...]

  29. Pingback from 解读 HTML5:建议、技巧和技术 | 2Kid on August 23rd, 2011 at 12:53 am:

    [...] Mozilla Hacks: 离线网页应用程序 [...]

  30. Yv.R wrote on February 12th, 2013 at 7:56 am:

    Hi, first thks for post. Just ask you few question. I’m making some web app with offline mode and using appcache… it perfectly works with chrome browser or some mobile browser like dolphin.. but still not work for firefox. I started with firefox 3.6.26( used by my clients) and then migrate to the last one 18.0.2 but it still not work. Here are the most important file

    - htaccess
    AddType text/cache-manifest .appcache

    - cache.appcache
    # v3.3..4

    CACHE:

    index.html
    page2.html
    img.png
    off.html

    SETTINGS:
    prefer-online

    FALLBACK:
    / /off.html

    NETWORK:
    *

    - and finally the line within the main file

    Have you ever met this issue?

    1. IMEVER wrote on February 19th, 2013 at 3:04 am:

      Maybe youy – cache.appcache file shoud begin with “CACHE MANIFEST”

Comments are closed for this article.