Storing information locally on a user’s computer is a powerful strategy for a developer who is creating something for the Web. In this article, we’ll look at how easy it is to store information on a computer to read later and explain what you can use that for.

Adding State To The Web: The “Why” Of Local Storage

The main problem with HTTP as the main transport layer of the Web is that it is stateless. This means that when you use an application and then close it, its state will be reset the next time you open it. If you close an application on your desktop and re-open it, its most recent state is restored.

This is why, as a developer, you need to store the state of your interface somewhere. Normally, this is done server-side, and you would check the user name to know which state to revert to. But what if you don’t want to force people to sign up?

This is where local storage comes in. You would keep a key on the user’s computer and read it out when the user returns.

C Is For Cookie. Is That Good Enough For Me?

The classic way to do this is by using a cookie. A cookie is a text file hosted on the user’s computer and connected to the domain that your website runs on. You can store information in them, read them out and delete them. Cookies have a few limitations though:

They add to the load of every document accessed on the domain.

They allow up to only 4 KB of data storage.

Because cookies have been used to spy on people’s surfing behavior, security-conscious people and companies turn them off or request to be asked every time whether a cookie should be set.

To work around the issue of local storage — with cookies being a rather dated solution to the problem — the WHATWG and W3C came up with a few local storage specs1, which were originally a part of HTML5 but then put aside because HTML5 was already big enough.

Using Local Storage In HTML5-Capable Browsers

Using local storage2 in modern browsers is ridiculously easy. All you have to do is modify the localStorage object in JavaScript. You can do that directly or (and this is probably cleaner) use the setItem() and getItem() method:

localStorage.setItem('favoriteflavor','vanilla');

If you read out the favoriteflavor key, you will get back “vanilla”:

var taste = localStorage.getItem('favoriteflavor');
// -> "vanilla"

To remove the item, you can use — can you guess? — the removeItem() method:

Where To Find Local Storage Data And How To Remove It

During development, you might sometimes get stuck and wonder what is going on. Of course, you can always access the data using the right methods, but sometimes you just want to clear the plate. In Opera, you can do this by going to Preferences → Advanced → Storage, where you will see which domains have local data and how much:

Doing this in Chrome is a bit more problematic, which is why we made a screencast:

Mozilla has no menu access so far, but will in future. For now, you can go to the Firebug console and delete storage manually easily enough.

So, that’s how you use local storage. But what can you use it for?

Use Case #1: Local Storage Of Web Service Data

One of the first uses for local storage that I discovered was caching data from the Web when it takes a long time to get it. My World Info5 entry for the Event Apart 10K challenge shows what I mean by that.

When you call the demo the first time, you have to wait up to 20 seconds to load the names and geographical locations of all the countries in the world from the Yahoo GeoPlanet6 Web service. If you call the demo a second time, there is no waiting whatsoever because — you guessed it — I’ve cached it on your computer using local storage.

The following code (which uses jQuery) provides the main functionality for this. If local storage is supported and there is a key called thewholefrigginworld, then call the render() method, which displays the information. Otherwise, show a loading message and make the call to the Geo API using getJSON(). Once the data has loaded, store it in thewholefrigginworld and call render() with the same data:

This can be extremely powerful. If a Web service allows you only a certain number of calls per hour but the data doesn’t change all that often, you could store the information in local storage and thus keep users from using up your quota. A photo badge, for example, could pull new images every six hours, rather than every minute.

This is very common when using Web services server-side. Local caching keeps you from being banned from services, and it also means that when a call to the API fails for some reason, you will still have information to display.

getJSON() in jQuery is especially egregious in accessing services and breaking their cache, as explained in this blog post from the YQL team8. Because the request to the service using getJSON() creates a unique URL every time, the service does not deliver its cached version but rather fully accesses the system and databases every time you read data from it. This is not efficient, which is why you should cache locally and use ajax() instead.

Use Case #2: Maintaining The State Of An Interface The Simple Way

Another use case is to store the state of interfaces. This could be as crude as storing the entire HTML or as clever as maintaining an object with the state of all of your widgets. One instance where I am using local storage to cache the HTML of an interface is the Yahoo Firehose research interface9 (source on GitHub10):

The code is very simple — using YUI3 and a test for local storage around the local storage call:

Notice: We restored your last search for you - not live data');
}
}
});

You don’t need YUI at all; it only makes it easier. The logic to generically cache interfaces in local storage11 is always the same: check if a “Submit” button has been activated (in PHP, Python, Ruby or whatever) and, if so, store the innerHTML of the entire form; otherwise, just read from local storage and override the innerHTML of the form.

The Dark Side Of Local Storage

Of course, any powerful technology comes with the danger of people abusing it for darker purposes. Samy, the man behind the “Samy is my hero” MySpace worm12, recently released a rather scary demo called Evercookie13, which shows how to exploit all kind of techniques, including local storage, to store information of a user on their computer even when cookies are turned off. This code could be used in all kinds of ways, and to date there is no way around it.

Research like this shows that we need to look at HTML5’s features and add-ons from a security perspective very soon to make sure that people can’t record user actions and information without the user’s knowledge. An opt-in for local storage, much like you have to opt in to share your geographic location, might be in order; but from a UX perspective this is considered clunky and intrusive. Got any good ideas?

Bruno Couto

Bobby Juncosa

Good article. I always get a bit of a chuckle out of the new and shiny HTML5 technologies when Flash has had local storage for years. Even if the site wasn’t a “Flash site”, using Flash as a method for storing and receiving locally stored data (and passing back via ExternalInterface) was a powerful alternative to a cookie (not to mention the ability to store native objects instead of just strings!).

As Apple throws their weight around with their ban against Flash on their devices, developers will have to start finding new ways (like HTML5’s local storage) to do the things that were already working so well in the past.

-9

4

Rudie

Obviously, you should use
if(window.localStorage) …
instead of
if(localStorage) …
And it seems there’s no way of storing actual live objects (with methods!) in localStorage… That’s too bad.
I love use case #2
— edit
In case of your world-thingie: if you abort before all data is loaded, NULL is saved into the localStorage and next time nothing else is loaded: oops.

Henrik Joreteg

Seeing/removing local storage in Chrome is *way* easier than shown in this demo. Just open the developer tools. CMD+Shift+J and then check the storage tab. Local storage is listed on the left along with cookies and local DBs. Just view and remove.

0

7

Koren Berman

Nice article, although I usually don’t see a great deal of functionality in HTML5 local storage capabilities I still think it’s a great feature for perhaps using it as a front-end session-like storage, which could be viable for interactive and javascript abundant apps.

Good introduction on the topic, thanks for sharing.

1

8

Richard Heyes

Rizqi Djamaluddin

That’s actually pretty sexy. But this means they’re basically just super-buffed mega-cookies, no? Maybe even a bit more difficult because we can’t interact with them directly in PHP or other server-side programming languages. I guess they’re perfect for storing stuff that can stay fully on the user end for most of the time.

Oh, and for those questioning it, this is supported by Firefox 3.5 up, IE8 up, Safari 4, and Chrome 4 up, as far as I know.

-3

10

Addy Osmani

Great article, Christian. I think that the GEOPlanet demo you showed me last week (also in this article) was an excellent example of where local storage really comes in useful.

The reality is that anyone wanting to use these technologies cross-browser *can* if they use the right tools. You can polyfill IE’s lack of local storage support in older browsers using something like YUI’s SWFStore (there are several alternatives) but most modern browsers do already support this.

dancer12

And what do you do with your shiny project when you encounter users like me who block all local storage, I wonder?

Because the flip side is – local storage can be abused, and as such is a security risk. There are going to be a lot of IT people out there who will shut this stuff down. A lot of the IT security sites are having discussion on exactly this point already.

So while it’s a cool technology – what are your plans for degrading gracefully?

Also, I believe Web Storage allows 5 megabytes per domain/origin, though I’m not sure if you get prompted to allow more if you exceed that or if it just fails silently.

Another interesting difference between sessionStorage and localStorage is with sessionStorge, values are only visible within the window or tab that created them, whereas with localStorage, values are shared across every window or tab running at the same origin.

Ferdy

Good article and I think there are situations where this is useful. Keep in mind though, that users are increasingly accessing web applications from multiple devices. Since local storage is local to the device, users may encounter inconsistent experiences across devices.

And, another dark side of local storage is that it is the enemy of data consistency. If your data definition changes, which is not uncommon in web applications, your local version will conflict with the server-side set. You will have to find a syncing solution then.

Useful in the context of the examples given, less useful in other contexts.

2

17

Curtis Scott

Antje

Very nice but the explanation of HTTP statelessness is not correct. The connection is stateless in itself and the opening or closing of an application has nothing to do with it. The connection is closed everytime the request is fulfilled. No popular website-hoster can manage 10.000’s of connection at the sametime and the host/servers would certainly fail.
So an application needs to re-establish connection everytime it needs something done. That makes everthing so slow.

0

19

Budda

Except the last part about ever cookie. The entire “Test” for the ever cookie is a pathetic joke. How can you test a pice of code in one browser and then make claims about every other browser out there and still openly say you never tested them.

Philip Tellis

Sankho

Not to self promote too much (oops), but I helped my company (HUGE) make a small JS library which allows for local & session storage across all browsers – yes, including IE 6. Actually, IE 5.5 too, but who’s counting.

Blackcoat

I recently began working on a localStorage jQuery plugin that archiving form data while the user progresses through a long form. When the user submits the form, their data is cleared. My power kept going out over a 2-month period, and the most frustrating moment was when it happened while I was filling out a long web form. Naturally, I thought that a jQuery plugin could fix this (^_^)

Max Nanasy

jeanette

Thanks for sharing.
I just made a prototype for a new web-site with 6 menu-links for demonstration purpose, only using HTML and JavaScript AND no server…Showing, deleting, adding data locally on my pc using local storage. It works great…
Thanks a lot – Again
And as mentioned earlier it’s realy a super coockie+++ with a large bold C+.

Jordi

Hi, great article!
something is not really clear for me though… anyone can clarify?
which is the difference bertween use the methods getItem, setItem, … or just do localstorage.myKey = ‘myValueString’ ?
maybe it has a obvious answer, but don’t I can’t see it…
thanks and congrats for this good stuff anyway!

Subscribe to our email newsletter for useful tips and valuable resources, sent out every second Tuesday.

Meet Smashing Book #5, our new book on real-life responsive design. With front-end techniques and patterns from actual projects, it's a playbook to master all the tricky facets and hurdles of responsive design. Save 25% today.

Fixing RWD issues can be quite easy — once you understand exactly why they come up. The Mobile Web Handbook will help you understand technical issues on mobile and how to deal with them effectively.

Hungry for more content? Over 60 eBooks are waiting to be discovered in our lovely Smashing Library. And guess what? You can watch Smashing Conference talks there, too.

SmashingConf isn't the eighth wonder of the world, but we are pretty close. Join us at at the shores of Santa Monica for SmashingConf LA on April 27–30 or at SmashingConf NYC on June 15–18. You won't be disappointed.