W3docs

JavaScript LocalStorage, SessionStorage

Learn how to use JavaScript localStorage and sessionStorage: store and read data, save objects with JSON, listen for storage events.

localStorage and sessionStorage are the two objects that make up the Web Storage API — the simplest way to keep data in the browser between page reloads. Both store information as string key/value pairs tied to the page's origin (protocol + host + port), and both expose exactly the same methods. The only difference is how long the data lives: localStorage keeps it indefinitely, while sessionStorage discards it when the tab closes.

This page covers the full API, how to store objects safely with JSON, how to react to changes in other tabs with the storage event, how to handle the errors these APIs can throw, and when to reach for a more capable store instead.

Warning

Never store sensitive information (passwords, tokens, personal data) in localStorage or sessionStorage. Any JavaScript running on the page — including third-party scripts — can read it, and it is fully exposed to cross-site scripting (XSS) attacks.

Understanding LocalStorage in JavaScript

localStorage stores data on the user's browser persistently, with no expiration date. The data survives closing the tab, closing the browser, and even rebooting the machine — it stays until your code (or the user) clears it. The data is scoped to the origin, so https://example.com cannot read what https://other.com stored.

How to Use LocalStorage

The API is small. You write a pair with setItem(key, value), read it back with getItem(key), and delete it with removeItem(key). Reading a key that does not exist returns null (not undefined). The API also provides:

  • clear() — remove every item for this origin.
  • key(index) — get the name of the key at a given index.
  • length — the number of stored items.
  • a storage event you can listen for to detect changes made in other tabs.
javascript— editable
Note

Storage operations are synchronous and run on the main thread, so reading or writing large amounts of data can block UI rendering. For larger or structured data, prefer IndexedDB.

Storing Objects and Arrays with JSON

The single most common mistake with Web Storage is forgetting that everything is stored as a string. If you pass an object to setItem, it is silently converted with toString(), giving you the useless value "[object Object]". The fix is to serialize with JSON.stringify when writing and JSON.parse when reading.

javascript— editable

Learn more about converting values to and from strings in Working with JSON.

Iterating Over Stored Items

Use length together with key(index) to walk through everything in storage, or read the keys with Object.keys:

javascript— editable

Practical Application: Creating a Theme Switcher Using LocalStorage

Consider a scenario where you want to save the user's preferred theme (light or dark) so that it persists across sessions. The following example combines HTML, CSS, and JavaScript into a single block for simplicity.

<style>
    :root {
        --bg-color: #ffffff;
        --text-color: #000000;
    }
    .dark {
        --bg-color: #333333;
        --text-color: #ffffff;
    }
    body {
        background-color: var(--bg-color);
        color: var(--text-color);
        transition: background-color 0.5s, color 0.5s;
    }
    button {
        padding: 10px 20px;
        font-size: 16px;
        cursor: pointer;
    }
</style>
<body>
<button onclick="toggleTheme()">Toggle Theme</button>
<script>
    function setTheme(themeName) {
        localStorage.setItem('theme', themeName);
        document.documentElement.className = themeName;
    }

    function toggleTheme() {
        var currentTheme = localStorage.getItem('theme') === 'dark' ? 'dark' : 'light';
        if (currentTheme === 'light') {
            setTheme('dark');
        } else {
            setTheme('light');
        }
    }

    function loadTheme() {
        var theme = localStorage.getItem('theme') || 'light';
        setTheme(theme);
    }

    // Initial theme load
    loadTheme();
</script>
</body>

This script checks for a stored theme in LocalStorage or defaults to 'light'. It then applies the theme by setting the class name of the root HTML element, allowing CSS to adjust the styles accordingly.

SessionStorage: Temporary Data Storage in JavaScript

While LocalStorage is designed for storing data with no expiration, SessionStorage provides a way to store data for the duration of the page session. Data stored in SessionStorage is cleared when the page session ends — that is, when the tab or window is closed.

How to Use SessionStorage

Below is a basic example of using SessionStorage. The methods and syntax are identical to localStorage — only the lifetime differs. A sessionStorage value is also scoped per tab: opening the same site in a new tab starts with empty sessionStorage, whereas a new tab shares the same localStorage.

javascript— editable

Example: Using SessionStorage in a Form Data Auto-Save Feature

Imagine you have a form that a user might fill out, but there’s a risk they might close their browser by accident. You can use SessionStorage to temporarily save the form data.


<body>
    <div>Start writing an email address in the following input. Refresh the page in the middle of your typing, and you'll see that the page remembers what you entered before.</div>
    <br />
    <input type="email" id="email"/>
</body>
<script>
window.onload = function() {
    const email = sessionStorage.getItem('email');
  
    if (email) {
        alert('email found from session storage: ' + email);
        document.getElementById('email').value = email;
    }

    document.getElementById('email').oninput = function() {
        sessionStorage.setItem('email', this.value);
    };
};
</script>

This code automatically loads any saved email when the page is loaded and updates the SessionStorage item whenever the email field changes. To test it, click on the "try it yourself" button, write something in the input, and then refresh the page. The value will remain there after a refresh.

Info

Always consider the size limitations before storing any data (typically around 5 MB for both LocalStorage and SessionStorage).

LocalStorage vs. SessionStorage

Both objects share the same API, the same per-origin scope, and the same string-only storage model. The practical differences come down to lifetime and visibility:

FeaturelocalStoragesessionStorage
LifetimeUntil explicitly clearedUntil the tab is closed
Survives tab/browser restartYesNo
Shared between tabs of same originYesNo (each tab is isolated)
Capacity~5 MB~5 MB
Fires the storage event in other tabsYesNo

Reach for sessionStorage when the data is only meaningful for the current visit — a multi-step wizard, an in-progress form, a scroll position. Use localStorage for preferences and other data that should persist between visits.

Reacting to Changes with the storage Event

When localStorage changes in one tab, the browser fires a storage event in every other tab of the same origin (but not in the tab that made the change). This is the standard way to keep multiple tabs in sync — for example, logging the user out everywhere when they log out in one tab.

window.addEventListener('storage', (event) => {
  console.log('Key changed:', event.key);
  console.log('Old value:', event.oldValue);
  console.log('New value:', event.newValue);
  console.log('URL of the page that made the change:', event.url);
});

// In another tab, this would trigger the handler above:
// localStorage.setItem('theme', 'dark');

The event object's key, oldValue, and newValue properties tell you exactly what changed. Note that sessionStorage does not trigger this event in other tabs, because its data is never shared.

Handling Errors and Edge Cases

Storage calls can throw, so production code should not assume they always succeed:

  • Quota exceeded. Writing past the ~5 MB limit throws a QuotaExceededError. Wrap writes in try...catch if the value could be large.
  • Disabled or private mode. Some browsers (or strict privacy settings) make storage unavailable, and even accessing localStorage can throw a SecurityError. Feature-detect before relying on it.
javascript— editable

For larger datasets, complex queries, or storing binary data, a more capable client-side database such as IndexedDB is a better fit. If you need data sent automatically with every request to the server, use cookies instead. You can also check remaining capacity and request persistence with the Storage API.

Conclusion

LocalStorage and SessionStorage offer powerful options for enhancing user experience by efficiently managing data in web applications. By understanding their capabilities and limitations, developers can make informed decisions on how best to use these tools in their projects.

Practice

Practice
Which of the following statements are true about JavaScript's localStorage and sessionStorage?
Which of the following statements are true about JavaScript's localStorage and sessionStorage?
Was this page helpful?