DEV Community

Cover image for Javascript local storage - beginner's guide
Arika O
Arika O

Posted on • Edited on

Javascript local storage - beginner's guide

Before going into any kind of explanation, we need to understand the difference between server side storage and client side storage when it comes to websites and applications. Server side means that we store our data on a server, using a database, client side consists of JavaScript APIs that allow you to store data on the client (in the browser).

WHAT IS LOCAL STORAGE?
In simple terms, the local storage can be compared to a data base, except it's found in a browser and not on a server. It's basically a huge Javascript object inside which we are able to store data in the form of key-value pairs. Not only we can store data, we can also delete it or retrieve it (a complete list of browsers which have a localStorage cant be found here). The data you store in the localStorage never leaves you machine (doesn't get sent back to the server, unlike with cookies, which will discuss in a future article), and depending on the browser, you can store up to 5MB of data.

In technical terms,

the localStorage read-only property of the window interface allows you to access a Storage object for the Document's origin;
the stored data is saved across browser sessions.

WHY USE IT?
Local storage lets us cache (store) some application data in the browser, for later usage. Therefore, it is very useful if we want to speed applications up (since the data is stored totally on the client, it does not travel between the client and server on each request or response). This way we can allow an user, for example, to continue a game where they left off or serve them relevant content based on their previous visit of our website.

I'm mostly using it when I'm building static websites. Since I don’t need any backend language or logic to store data in the browser, my web pages can run independently of any web server.

There are two types of storages, local and session, but for now the only difference you should remember is that the local storage has no expiration date (meaning that the data will stay in there until we remove it manually), whereas the session one gets cleared once we close the browser (session).

I will be using Chrome browser for this article, but generally, accessing the localStorage of any browser is pretty similar. We open the console (F12), navigate to the Application tab and in the menu on the left we'll see Local storage under the Storage tab. Something like this:

Alt Text

If we expand the Local storage dropdown, we'll get to this view:

Alt Text

We have two columns, Key and Value, and usually they're filled with data, which I just removed before taking the screen shot.

The way we can access this storage object and populate the two columns is by making use of some specific methods. Remember, local storage is read-only, meaning we can add, read and delete data from it but we can't modify it (at most, we can overwrite the previous value of a key, by re-adding to the storage, using the same key and the new value we want to store). For access we should use the following syntax:

window.localStorage 
//or 
localStorage
Enter fullscreen mode Exit fullscreen mode

If we want to add something, we can do it like this:

localStorage.setItem("key", "value");
Enter fullscreen mode Exit fullscreen mode

To access a value, we write this:

localStorage.getItem("key");
Enter fullscreen mode Exit fullscreen mode

And lastly, we can delete one specific value:

localStorage.removeItem("key");
Enter fullscreen mode Exit fullscreen mode

Or we can clear the whole local storage:

localStorage.clear();
Enter fullscreen mode Exit fullscreen mode

Now, let's try to actually write some code. I will use my console, for simplicity's sake. Let's add an item:

window.localStorage.setItem("city", "Toronto");
Enter fullscreen mode Exit fullscreen mode

Now, local storage looks like this:
Alt Text

One important thing to remember is that the localStorage can store only strings. To store objects, we must first convert them to strings using the JSON. stringify() method. And we convert the strings back into objects, after we retrieve them from the localStorage, using the JSON.parse().

Let's add some more values, using different types of data as keys and values:

localStorage.setItem(0, "number");
Enter fullscreen mode Exit fullscreen mode
const person = {name: "Alan", age: 32};
JSON.stringify(person); // returns "{\"name\":\"Alan\",\"age\":32}"
localStorage.setItem("person","{\"name\":\"Alan\",\"age\":32}");
Enter fullscreen mode Exit fullscreen mode

Now the local storage will look like this:

Alt Text

We can add as many key-value pairs as we want as long as the data doesn't exceed 5MB. Now let's retrieve the value of the person key, convert it to an object and print it to the console:

const result = localStorage.getItem("person");
console.log(result); // returns {"name":"Alan","age":32}
const objectResult = JSON.parse(result);
console.log(objectResult);// returns {name: "Alan", age: 32}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Finally, let's delete one item only, followed by clearing the whole localStorage:

localStorage.removeItem("0");
Enter fullscreen mode Exit fullscreen mode

Alt Text

localStorage.clear();
Enter fullscreen mode Exit fullscreen mode

Alt Text

THINGS TO REMEMBER ABOUT THE LOCAL STORAGE

  • it is tab specific, meaning each browser tab we open will have different data in the localStorage(this doesn't apply if the tabs have the same origin (share the same domain))
  • some browsers, when used in incognito mode don't allow for setting data in the localStorage
  • it is synchronous, meaning each operation will execute one after the other (this might work for small projects, but it will impact the runtime of the more complex ones)
  • it can only store data string data (this is fine for small projects, but it can be cumbersome to serialize data in complex ones)

SUPER IMPORTANT THING TO REMEMBER
Local storage should under no circumstances be used to store sensitive information (e.g. passwords or personal details), since the data inside it can be accessed from anywhere on the page (it has no real protection and it's susceptible to cross-site scripting).

Image source: ThisIsEngineering/ @thisisengineering on Pexels

Top comments (21)

Collapse
 
nithish_13 profile image
Nithish Kumar

It seems like you have deleted the previous post and then re-created it.
Tnx for the post :)

Collapse
 
arikaturika profile image
Arika O

Yes, true. To answer your question, I believe your usage of localStorage is safe, for development purposes. Unrelated to localStorge, what I would pay attention to would be not to expose your API key if the API you're using has provided you with a private key (that if tou chose to upload your project using Gihub Pages, Netlify etc).

Collapse
 
nithish_13 profile image
Nithish Kumar

I agree. For that reason, I use .env to protect api key

Thread Thread
 
arikaturika profile image
Arika O

Even if you store your keys in an .env file, they will be exposed once the React project is built. For more details you can read this article

Thread Thread
 
michaelcurrin profile image
Michael Currin • Edited

Indeed. A file with credentials should not be read by the client / frontend by JS because it means a user can access the value too.

An appropriate use for .env file credentials is if your frontend did not care about this details at all. But you have a server side REST API or Lambda which internally loads the .env file and obscures the values and then your frontend requests that service.

Also remember that a .env on GitHub can be read by other users. So typically you would use secret environment variables set in your CI so that only you and admin users can see the values and they get used in the app at build time, and when the app starts.

Thread Thread
 
arikaturika profile image
Arika O

But you have a server side REST API or Lambda which internally loads the .env file and obscures the values and then your frontend requests that service.

Do you have some resources on how to achieve this exactly? I've been dealing with this issue myself but I nevet got into details on how to obscure my API keys. Thank you!

Thread Thread
 
michaelcurrin profile image
Michael Currin

If you have a simple app that does one thing then consider Netlify Functions, similar to Lambda but letting you run server side Node code and the frontend interfaces through API requests. And it is serveless so you don't need to set up a Node server! Add a file in the right directory and Netlify will deploy your serverless code. In your Function file, you would reference process.env.

And the value would be set in the env variables in your Netlify admin view.

For example if you want to search the Twitter API using your secret keys but allow users to input their own search terms and not have to do any auth themselves.

Here is an article I found

dev.to/irohitgaur/how-to-access-ap...

Thread Thread
 
michaelcurrin profile image
Michael Currin

I have an example of a file and site for reference. I use frontend JS to query the Function and return the result on the frontend.

github.com/MichaelCurrin/netflix-a...

It doesn't use an API key because the external API doesn't need one. But for Twitter where you do need one, I would have set and used env variables as in my previous comment. Note I would not use a .env file because it would be stored in version control and maybe accidentally deployed as a public file on the site. Keep your secrets out of version control and in your CI tool env variables. Or say AWS secrets manager.

Thread Thread
 
michaelcurrin profile image
Michael Currin

Drifting from the web app flow, here is how to use secret environment variables on GitHub Actions to post a tweet.

github.com/MichaelCurrin/tweet-gh-...

Thread Thread
 
michaelcurrin profile image
Michael Currin

If you are making complex app handling say user profiles and photos then instead of Function you probably need to make a REST API with Express JS or Flask (Python) and maybe a database. And host that on Vercel or AWS. And your app would read the env variables on process.env or os.env when the app starts but only send and receive precise info to the user so they cannot see the API key used behind the scenes.

Thread Thread
 
arikaturika profile image
Arika O

Thank you so much for all the resources, sounds very interesting (and tricky :D)!

Collapse
 
pchilligp profile image
pchilligp

Nie!!!

Collapse
 
pchilligp profile image
pchilligp

Sorry nice!!!

Collapse
 
chrisczopp profile image
chris-czopp

it is tab specific, meaning each browser tab we open will have different data in the localStorage

Not if the tabs share the same origin. It's only true if you use sessionStorage

Collapse
 
arikaturika profile image
Arika O

True, I forgot to mention that. Thx!

Collapse
 
veekeey profile image
Veekeey

Very useful... Thank you

Collapse
 
aalphaindia profile image
Pawan Pawar

Thanks for sharing!

Collapse
 
arikaturika profile image
Arika O • Edited

Thx for pointing out the typos (bad copy paste :D). I mentioned you can access the storage both ways (with or without window), but yes, I might as well remove the window keyword in the examples.

Collapse
 
chadgotis profile image
Chadric Gotis

Thanks for this wonderful post :)

Collapse
 
arikaturika profile image
Arika O

Thx for reading, I hope it was useful.

Collapse
 
sabiyatabassum profile image
Sabiya Tabassum

Nice post. Thanks for sharing.