Using the cache manifest to work offline

30th August 2010

The experiment

Another one of the new features of HTML5 is the ability to specify your website to work offline, i.e. when the connection drops, your site will still work. This is achieved via a cache manifest file, and it is this file and how to use it that this experiment will look at.

The process

The manifest file basically informs the browser what files and resources it should store in its local cache in order for the site to be available offline. This list can contain images, HTML, CSS or JavaScript files. As well as specifying what the browser should cache, you can also indicate what it should not cache, as well as providing file substitutions and a fallback should something be requested that isn't available in offline mode.

Let's take a look at the file format shall we?

The CACHE MANIFEST file

There are a number of sections that make up a manifest file, and they are as follows:

Section

Repeatable

Description

CACHE MANIFEST

N

Not strictly a section, this needs to be at the top of every cache manifest file and informs the browser that what follows are the contents of a manifest file

CACHE:

Y

This contains the list of files and resources that the browser should cache. This is the default section and if no others are added, every entry in the file will default to this one

NETWORK:

Y

This contains a list of files and resources that can only be accessed when the browser has online access. This can be ommitted, and anything that isn't specifically matched in the rest of the manifest file has this default behaviour

FALLBACK:

Y

This contains a list of mappings of file replacements when the browser has no online access, e.g. file.html offline.html will mean that when offline, any request for file.html will be serves with offline.html.This can also be used as a catch-all so that all requests for unknown files can be served by offline.html: / offline.html

If you repeat a section, the entries in each will be concatenated together.

With that out of the way, let's take a look at a sample cache manifest file:CACHE MANIFEST
CACHE:
offline-application-cache.html
cache/write-message.js
NETWORK:
random-image.php
FALLBACK:
random-image.php cache/many-leaves.jpg
/ offline.html

So, what is this file doing? Well the first line, cache manifest as indicated above, tells the browser that what follows this is a cache manifest file.

Next, CACHE: lists what files the browser is to cache, here offline-application-cache.html and the JavaScript file write-message.js which is located in the cache subdirectory.

Then it specifies that the random-image.php file (which simply chooses a random image to display) can only be called when the browser has online access (which makes sense of course, as this is a PHP file) under the NETWORK: section.

Since random-image.php therefore cannot be called when the site is offline, and therefore no image would be displayed, under the FALLBACK: section a replacement JPG image (many-leaves.jpg) file is specified which will be displayed instead of the result of random-image.php. All other requests will be served with offline.html.

It's also recommended to add a comment line such as

# version N

where N is a number you manually increment when changing the cache manifest file. Browsers like to hold on to the file and this helps to force it to reload. (this tip comes straight from the pages of Introducing HTML5).

Telling the browser about the manifest

So that's the manifest file, but how do we tell the browser about it? Easy. All you need to do is to add the following attribute to the <html> element:

<html lang="en" manifest="cache.manifest">

Where cache.manifest happens to be the name of the manifest file that I'm using.

Serving the manifest

Ther server your code is running on also needs to be told how to serve the the manifest file correctly. For this we need to return to the bane of our life our old friend, the MIME type.

If you're using a common web server such as Apache, the following line needs to be added to the mime.types file:

text/cache-manifest manifest

This ensures that Apache will send the text/cache-manifest file header when you request any file with the .manifest extension. You can test this by using a command line tool such as cURL.

When you have an online connection, the application should proudly declare at the top of the file that “This heading is from a JavaScript file” which it is.

Underneath that should be a large picture of some leaves. Refresh it and you should see another one (you might see the same one - there are only 5 different images it can load, refresh it again if you don't believe me)

When you are in offline mode, the JavaScript heading should remain the same, but the image below should be a smaller JPG image of many different leaves. This is because the browser has been told to cache the HTML file itself and the JavaScript file and to replace all calls to random-image.php (which returns a link to one of the random leaf images) with the static many-leaves.jpg.

Some things to note - browser issues

As with all HTML5 elements at the moment, the cache manifest works in this brower, sort of works in that browser, and doesn't work in others.

Safari is the best browser to test this with. I was using the latest version for Windows, Safari 5.0.1.

It also works fine in the latest Google Chrome (5.0.375.127)

Opera 10.6 also gave the correct results

Firefox claims to support it, but it's apparently buggy and you need to tell it to never cache the manifest file. I tried with 3.6.8 and even Firefox 4 beta 4 but so far have been unable to get it to work correctly.

As usual, nothing in the HTML5 world works in Internet Explorer (well it will when version 9.0 comes out)

Whilst with some browsers (Opera and Firefox) you can turn on "Work Offline" mode, the best way to test it is to disable or unplug your network connection.

The results

This feature is very useful should you want to have your entire site available to users should they suddenly go offline when browsing your site. It also makes it available for browsing when the user doesn't have a connection at all (e.g. when flying).

As with all HTML5 features, support isn't complete but for those who use a compatible browser (and there's nothing wrong with informing the user of the benefits of using such a browser with your site) then the benefits are worth it.