The KIRUPA orange logo! A stylized orange made to look like a glass of orange juice! Tutorials Books Videos Forums

Change the theme! Search!

Customize Theme


Color

Background


Done

Table of Contents

Storing Data Using Web Storage

by kirupa   |   filed under JavaScript 101

  Have questions? Discuss this HTML5 tutorial with others on the forums.

Just like Las Vegas, often what you do in a web page stays in the web page. Let's say you have a simple application that allows you to maintain a to-do list:

a to-do list example

If you accidentally navigate to another page or close the tab this page was on, the default behavior when you return to this page would be to see an empty to-do list.

Because web pages do not persist data by default, you have a bunch of approaches you can take for solving this problem. In this tutorial, we are going to look at one of my favorite ways of storing data by relying on what is known as the Web Storage API. This API allows you to write just a few lines of code to handle a lot of tricky storage situations, so it's going to be a fun one!

Onwards!

How Web Storage Works

The Web Storage API sounds complicated and scary, but it is mostly a pushover. It is exposed to us via two global (attached to window) objects called localStorage and sessionStorage. You can use these two objects to specify what data to store as well as what data to retrieve, update, permanently remove, and perform a whole bunch of other storage-related activities. Let's go a bit deeper in our understanding of what happens.

What Exactly Goes on Inside

For the sake of simplicity, I am not going to focus on both local storage and session storage at the same time. They are both very VERY similar, so I am going to flip a coin and pick on...our localStorage object instead:

 

If you take a peek inside this object, what you will see is a well-oiled machine that is designed for storing data. It stores data by neatly organizing them into key and value pairs. If you aren't familiar with this approach, take a look at the following visualization:

I am storing information about one of my favorite cartoon characters where the data I want to store is indexed by an easily identifiable key value. More specifically, you can see that there are three pieces of data that I am storing:

  1. firstName key with a value of Bugs
  2. lastName key with a value of Bunny
  3. location key with a value of Earth

The key serves as the identifier, and the value is the data associated with it. As you will soon find out, almost all operations you perform using our storage objects will involve the key, the value, or both!

Web Storage Data is Tied to Your Domain

We are almost done here. There is one last detail you need to know before we start looking at the code. All of the operations you perform with the Web Storage APIs are tied to whatever domain your code is being run on. This level of isolation ensures that you don't accidentally (or deliberately!) modify any data that 3rd party sites may have already set in your storage. In other words, any data I store on kirupa.com is inaccessible to code that may be running on google.com...and vice versa. If you were hoping to use local or session storage to persist some data across multiple sites on different domains, you are out of luck!

Getting Your Code On

Now that you have a basic idea of how Web Storage does its thing, let's look at the code for doing all sorts of data-ey things to it. If you want to follow along, all you need is an empty HTML page with a script tag:

<!DOCTYPE html>
<html>

<head>
  <title>Local Storage</title>
</head>

<body>
  <script>

  </script>
</body>

</html>

There is no UI to what we are doing here, so it's all inspecting the state of our localStorage or sessionStorage objects using your browser developer tools.

Adding Data

If you've never done anything with local storage before, let's start by adding some data into it. The method you use for adding data lives off of your localStorage object, and it is called setItem. This method (unsurprisingly) takes two arguments made up of your key and value:

localStorage.setItem("key", "value");

Below is an example of the setItem method in action where I am storing the details of the (totally sweet!) music I'm listening to right now while writing this:

localStorage.setItem("artist", "Tycho");
localStorage.setItem("album", "Awake");
localStorage.setItem("track", "Apogee");
localStorage.setItem("year", "2014");

With each line, we are pushing data into our localStorage object. At the end of all this, the data in your localStorage object can be visualized as follows:

As you can see, the way you add entries is by using setItem and specifying a key that you haven't used before. If you specify an existing key, then the existing value the key is pointing to will be overwritten with your new value:

// overwriting some data
localStorage.setItem("track", "Apogee");
localStorage.setItem("track", "L");

Now, here is one more important detail that you should know. Your keys and values must be strings. That's right. If you want to store a snazzy custom object for retrieval later, you are completely out of luck under Web Storage. Basically, use string values and rely heavily on methods like toString() and JSON.stringify() to ensure you are storing any complex data in the form of a string that you can (hopefully) un-stringify later.

Retrieving Data

To retrieve some data stored in your localStorage object, you use the getItem method:

var artist = localStorage.getItem("artist");
console.log(artist); // will print out 'Tycho'

The getItem method takes only the key as an argument, and it returns the value associated with that key. If the key you pass in does not exist, a value of undefined is returned instead. Pretty simple, right?

A Shortcut for Adding and Removing...Maybe?

If for whatever reason you don't like using the getItem or setItem methods, you can bypass them by using the following notation for setting and retrieving data:

// storing data 
localStorage["key"] = value; 

// retrieiving data 
var myData = localStorage["key"];

This is a notation you may have seen (and possibly even used!) when working with objects and associative arrays. That same technique can be used with your localStorage and sessionStorage objects as well.

There is no right or wrong way to access your data, so use whichever approach speaks to your soul :P

Now, back to our regularly scheduled programming.

Removing Data

There are two extremes to removing data from your local storage. You can remove everything scorched earth style, or you can selectively remove a key and value pair individually.

Because scorched earth is an awesome game, let's look at it first. To remove everything from your local storage, you can call the clear method on your localStorage object:

localStorage.clear();

This will remove all traces of any data you may have stored, so use it cautiously if you have several pages on your site that each write to the localStorage object independently and rely on data stored there actually being there.

To remove only select key and value entries from localStorage, you can use removeItem() and pass in the key name associated with the data you wish to remove:

localStorage.removeItem("year");

In this snippet, the year key and its value will be deleted while leaving all of the other data intact. This is the safer option if you are working on an app that has many components that rely on storing data using Web Storage.

Dealing with File Size

For reasons I don't know, all of the browsers give you have a fixed size of 5 MB for each domain your local storage is tied to. If you try to add more data after you have exceeded your 5 MB quota, a QUOTA_EXCEEDED_ERR exception will be thrown.

Handling this exception is pretty straightforward by using a try/catch statement:

try {
  localStorage.setItem("key", "some data");
} catch (e) {
  if (e == QUOTA_EXCEEDED_ERR) {
    // do something nice to notify your users
  }
}	

This ensures that your code fails nicely while still giving you the option of notifying your users that their data can't be saved. With all of that said, you really should never have to do this. Remember, all of the data you store is in the form of strings. Five m-e-g-a-b-y-t-e-s (spelling it out for greater emphasis :P) is a lot of text-based data to store. If you need to store that much data, Web Storage may not be your best solution.

Detecting Support for Web Storage

Ironically, one of the last things we are going to do is talk about detecting whether someone's browser supports local storage or not. According to the caniuse statistics on it, pretty much everybody (and their mothers) is using a browser that supports it. There is another better reason outside of browser support why you want to do this.

Web Storage, just like cookies, allows web sites to leave behind traces of themselves on your machine. When users are browsing using a "private" mode like the kind offered by all your major browsers, the goal is to avoid dealing with these traces of data. This means that your browser totally supports local and session storage, but it may have this feature disabled or severely crippled to respect user privacy. Trying to add some data into your local or session storage will either result in an error, or your data will simply be wiped out the moment you end your browsing session.

For the "private" mode case, it is a good idea to check whether Web Storage is usable on the user's browser. The code for doing this check looks as follows:

function isLocalStorageSupported() {
  try {
    localStorage.setItem("blah", "blah");
    localStorage.removeItem("blah");
    return true;
  } catch (e) {
    return false;
  }
}

A call to the isLocalStorageSupported function will return a value of true if local storage is usable, and if local storage isn't supported, you will see a value of false.

This code snippet is based entirely on the following Gist that also outlines the brief history of local storage feature detection.

What about Session Storage?

Towards the beginning, I stated that we are going to focus on the localStorage object and that we will focus on the sessionStorage object later. Guess what? Later is here, so it's time to shift gears and look at session storage! For the most part, the way you use local storage and session storage are identical. Everything you saw for the localStorage object in the previous sections applies to the sessionStorageobject as well. The way you add, update, and remove items is even unchanged. The only difference is the syntax where you specify the sessionStorage object instead of localStorage:

// adding items
sessionStorage.setItem("artist", "Tycho");
sessionStorage.setItem("album", "Awake");
sessionStorage.setItem("track", "Apogee");
sessionStorage.setItem("year", "2014");

// removing item
sessionStorage.removeItem("album");   

As you can see, things are very similar from a code point of view! If they are so similar, why would the Web Storage API expose both of these objects for you to use?

As it turns out, the major subtle difference between localStorage and sessionStorage is persistence. When you store data using local storage, your data is available across multiple browsing sessions. You can close your browser, come back later, and any data you had stored will still be accessible by your page. When you are storing data via session storage, your data is only available for that browsing session. There is no long-term persistence. You close your browser, come back a few moments later, and you'll find that all of the data stored in your sessionStorage object is gone.

The takeaway is this - if you want to persist some information for just a single browsing session, you should use session storage. If you want to persist information (theoretically) forever, use local storage. For everything else, there is MasterCard. Oh, snap!

Conclusion

The Web Storage API addresses a long-running wish by designers and developers to have client-side storage that is more flexible than cookies and easier to use than WebSQL or IndexedDB. As you can see, local storage (and session storage) is fairly easy to use. A handful of setItem and getItem calls is all it really takes to be up and running. With this, we are done for now. I'm going to run and listen to some Tycho:

Alternatively (or in addition to listening to Tycho), you can play some Scorched Earth to get some of that old-school gaming feeling going.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Serving you freshly baked content since 1998!
Killer icons by Dark Project Studios

Twitter Youtube Facebook Pinterest Instagram Github