DEV Community

Cover image for Chrome Local Storage in Extensions
milandhar
milandhar

Posted on • Updated on

Chrome Local Storage in Extensions

For my Javascript project at Flatiron School's Web Development course, my partner and I decided to build a Chrome extension. When we got the project requirement, we wanted to create something that we would actually use, and also learn about a new area that we hadn't yet explored. Since we often find ourselves needing to remind ourselves to take a break, we decided to make a break timer extension!

While we knew creating an extension would be a different challenge than other Javascript projects we'd worked on, we underestimated how difficult it would be to make the app's data persist for a sufficient amount of time. The beauty of Chrome extensions is that they allow users to access a minimal app on their toolbar, opening and closing it whenever they want. However even a straightforward challenge like a break timer was tough, since clicking away from the extension effectively kills the Javascript session, wiping away all regular variable data.

Luckily, Chrome provides its own chrome.storage API that helps solve this problem, making developing extensions feasible.

What is Local Storage?

So far at the Flatiron School, we've been exposed to some browser-storage methods such as cookies and sessions in a Rails context. The Web Storage API contains two mechanisms: localStorage and sessionStorage. LocalStorage is similar to sessionStorage in that they are both read-only, but data stored in localStorage has no expiration time, while sessionStorage gets cleared every time the page session ends (the tab is closed).

Since localStorage is persistent among multiple page sessions, it is the ideal option for saving Chrome extension data, allowing users to click off and on the extension to their heart's content.

Using Chrome's Local Storage in Your Extension

Google has developed its own chrome.storage API that provides the same storage capacity as the Web Storage API. One thing to keep in mind when using chrome.storage is that the storage space is not encrypted, so confidential customer data should not be stored.

There are a few steps you must take and things to keep in mind when implementing Chrome's storage in your extension:

Manifest

Every Chrome extension has a manifest file called manifest.json which describes the app and provides important metadata such as its name, scripts, permissions and version. If you want to use chrome storage, you must declare the "storage" permission to your manifest.json file. Here is a snippet from our extension:

{
  "name": "break alarm",
  "version": "1.0",
  "description": "Be more productive.",
  "permissions": ["alarms", "declarativeContent", "storage", "<all_urls>"],
  "background": {
    "scripts": ["helpers.js", "background.js"],
    "persistent": false
  },
...
}
Enter fullscreen mode Exit fullscreen mode

Storage.sync

One key difference between Chrome's storage API and the Web Storage API is that Chrome offers a storage.sync mechanism that allows user data to be automatically synced with Chrome sync. This would allow a user to access their data on a different device, assuming they have Chrome Sync enabled on their account.
So when developing your extension, you will need to decide whether you want to use storage.local or storage.sync. We decided to use storage.local for our break timer extension. The main difference between the two is the storage limit: storage.local offers about 5.2MB of data while storage.sync's limit is about 102KB, with maximum number of items stored of 512. A nice feature of storage.sync is that even if the user has disabled Chrome Sync, it will still work and just behave like storage.local.

Asynchronous Calling

Another cool feature of chrome.storage is that all of its calls are asynchronous, while the localStorage in the Web Storage API is called synchronously. While in our project I found the process of getting every locally stored variable asynchronously to be annoying at times, this mechanism allows extensions to run much faster.

Setting a new object in chrome.storage is relatively straightforward. In our break timer extension, when the user clicked the "resume" button, we would set the following in local storage:

chrome.storage.local.set({ isPaused: false })
chrome.storage.local.set({'user_name': json.user_name})
chrome.storage.local.set({'phone_number': json.phone_number})
chrome.storage.local.set({'redirect_url': json.default_url})
chrome.storage.local.set({'break_time': json.default_break_time});
Enter fullscreen mode Exit fullscreen mode

When calling saved objects from chrome.storage, we can use a bulk async get function that will access multiple objects at once. Here's an example from our break timer extension:

  chrome.storage.local.get(['user_name', 'phone_number', 'redirect_url',
 'break_time', 'isPaused'], function(data) {
    h1.textContent = data.user_name
    timerInput.value = data.break_time
    urlInput.value = data.redirect_url
    phoneInput.value = data.phone_number

if (!data.isPaused) {
      updateCountdown();
      countdownInterval = setInterval(updateCountdown, 100);
      isNotPausedDisplay();
    } else {
      chrome.storage.local.get('pausedCount', function(data) {
        counterElement.innerHTML = secToMin(data.pausedCount);
      });
      isPausedDisplay();
    }

  });
Enter fullscreen mode Exit fullscreen mode

Removing Items from Chrome Storage

In order to make full use of chrome.storage, it is important to understand how and when to remove stored data. In our timer extension, we had user data stored such as their preferred break time, their preferred "work" url, and their phone number for timer alerts. We wanted to persist the user's data while they were logged in so that they could set several timers and didn't have to re-enter all their settings if they returned to the extension. However when they log out, we want to remove the user's stored data from chrome.storage so that another user could log in on the same machine.

Luckily, chrome.storage makes it easy to do this! Chrome offers both a chrome.storage.local.remove function that lets you specify which key(s) you would like to remove, and a chrome.storage.local.clear function that will clear all data stored in the extension's local storage. Both functions have optional callback function parameters that will return on success or failure (and then runtime.lastError will be set).

Since in our extension, we wanted to remove all the user's data once they logged out of the app, we wrote a method that used the clear function with an error-catching callback:

function clearLocalStorage(){
  chrome.storage.local.clear(function() {
    var error = chrome.runtime.lastError;
      if (error) {
        console.error(error);
      }
   })
 }
Enter fullscreen mode Exit fullscreen mode

Conclusion

Overall, chrome.storage was an indispensable tool to ensure that our extension ran correctly and persisted the user data that we wanted. While building an extension seemed daunting at first, with so many new files and specifications, learning how to use chrome.storage made things so much easier. I would highly recommend heading over to Chrome's extensions documentation when developing your first extension, it is very helpful and concise.

Thanks for reading!

Discussion (7)

Collapse
nutondev profile image
nuton.dev

My understanding is that the total quota of storage.local (about 5 MB?) is shared among all extensions, so potentially in case one extension eats up 5MB, I won't be able to store my data. Is that correct? Also, since the storage API includes .clear() my understanding is that the scope is per extension and there is no need to namespace the settings, correct? (otherwise you would be able to clear storage area belonging to other extensions)

Collapse
ws647487t profile image
ws647487t

IT'S OBVIOUS!

Collapse
thenora profile image
thenora

I'd love to take a look at your git -- I'm working on a Pomodoro timer Chrome extension using React, and working on deciding between using local storage or messaging. I haven't seen too many examples with local storage, which is what I think I'm leaning toward.

Collapse
rhythm010 profile image
rhythm010

If I want to store some data for the chrome extension that stays even when the browser window is closed, what kind of storage should be useful then.

Collapse
milandhar profile image
milandhar Author

Chrome's local storage can persist when the window closes. You can use either storage.local or storage.sync to accomplish that.

Collapse
likejean profile image
likejean

Where this manifest.json file should be kept? At the root directory of the application?

Collapse
milandhar profile image
milandhar Author

Hi - yes, it should be kept in the root directory. Here is more info on the manifest.json file: developer.chrome.com/extensions/ma...