htmlofflinehtml5-appcachecache-manifesthtml5-history

How to make a cache manifest and HTML5 history work together


I have a single page web app that use HTML5 history. I recently added a cache manifest to make it works offline.

The URL of the app is domain.com/app and when it load the cache manifest make this URL able to go offline. But once the app is ready, the state of the app change, and the URL become domain.com/app/page (thanks to history.pushState()).

But if I go offline and reload the page (with this URL domain.com/app/page), the browser tell me that there is no internet connexion instead of loading the app. If I ask for this URL: domain.com/app, the app load and the URL become domain.com/app/page once the app is ready.

So basically, is there a way to tell the browser that domain.com/app and domain.com/app/page are the same app ?


Solution

  • Yes, it's actually quite simple, add a fallback section to your manifest.appcache file, so it looks something like this

    CACHE MANIFEST
    # 2014-06-26T12:11:34.216Z
    
    CACHE:
    /app
    /app/script.js
    /app/style.css
    
    NETWORK:
    *
    
    FALLBACK:
    /app /app
    

    /app /app means that all requests to paths that start with /app shall fallback to /app.

    There is a gotcha with HTML5 apps using history.pushState(): All paths you open your app initially with will be stored as extra entries in localStorage. If you have paths like app/document/<id> this can quickly become a lot. The biggest problem here is that when applicatioCache checks for an update, it will go trough all these entries and you can't do much about it.

    Best practice is to use an iframe to load the /manifest.appcache file instead and remove the manifest property from your app's index.html file. You can find out more about it at http://labs.ft.com/category/tutorial/

    I've made a small library that provides a nice JS API to cache your app with the iframe hack (and also provides lots of other goodies): https://github.com/gr2m/appcache-nanny