Introduction
LocalStorage is a feature of the Web Storage API that allows web applications to store key-value pairs of data on the user's browser. This persistent storage method is useful for saving data such as user preferences, application states, and cached data. The stored data remains available even after the user closes the browser or restarts their computer, providing a convenient means of retaining information on the client-side.
In JavaScript, localStorage
is available as a global object, and its API provides methods to easily read, write, and manage the stored data. One important aspect of working with localStorage
is detecting when data changes, which can be especially relevant in multi-tab or multi-window scenarios. The 'storage' event helps facilitate this by providing a means of detecting and reacting to changes in localStorage
made in other browser tabs or windows within the same domain.
What is the 'storage' event?
The 'storage' event is a part of the Web Storage API, designed specifically to notify other tabs or windows of changes made to localStorage
within the same domain. This event is fired automatically when a script in another tab or window modifies the localStorage
data. It is important to note that the 'storage' event is not triggered in the same tab or window where the change was made.
The 'storage' event is useful in scenarios where an application needs to synchronize its state across multiple open tabs or windows. For instance, if a user logs out of an application in one tab, the other open tabs should update their UI accordingly to reflect the logged-out state.
Here's an example illustrating the 'storage' event:
// Add an event listener for the 'storage' event
window.addEventListener('storage', (event) => {
console.log('Storage event detected:', event);
// Check the changed key and react accordingly
if (event.key === 'loggedIn') {
if (event.newValue === 'true') {
// Update the UI to show the user is logged in
} else {
// Update the UI to show the user is logged out
}
}
});
// In another tab or window, when the user logs in or out, you can update the localStorage:
localStorage.setItem('loggedIn', 'true'); // or 'false' for logging out
Different Event Properties
When a 'storage' event is triggered, an event object is passed to the event listener, containing relevant information about the change in localStorage. The following properties are available in the event object:
key
: The key of the changed data in localStorage. If the change was the result of a new item being added, this property will contain the key of the new item. If the change resulted from an item being removed, the key will still be available.oldValue
: The value of the key before the change. If the change was the result of a new item being added, this property will benull
. If the change resulted from an item being removed, this property will contain the value of the removed item.newValue
: The value of the key after the change. If the change was the result of an item being added or updated, this property will contain the new value. If the change resulted from an item being removed, this property will benull
.url
: The URL of the document that made the change to localStorage. This property can be used to verify the source of the change, especially in cases where you want to ensure that the change came from a specific part of your application.storageArea
: A reference to the localStorage object itself. This property allows you to directly interact with the localStorage object that was affected by the change.
Adding an event listener to 'storage' event
To react to the 'storage' event, you need to add an event listener to the window
object. The event listener will be a function that gets called when the 'storage' event is fired. The function receives the event object as a parameter, which contains information about the change in localStorage.
Here's an example of adding an event listener for the 'storage' event:
function handleStorageEvent(event) {
console.log('Storage event detected:', event);
// Check the changed key and react accordingly
if (event.key === 'theme') {
// Update the UI theme based on the new value
updateTheme(event.newValue);
}
}
// Add the event listener to the window object
window.addEventListener('storage', handleStorageEvent);
// Function to update the UI theme
function updateTheme(theme) {
const body = document.querySelector('body');
body.className = theme;
}
In this example, the handleStorageEvent
function is added as an event listener for the 'storage' event. When the 'storage' event is fired in a different tab or window, the event listener checks if the changed key is 'theme', and if so, updates the UI theme accordingly using the updateTheme
function.
Manually triggering the 'storage' event in the local tab
As mentioned earlier, the 'storage' event does not fire automatically in the tab or window where the change was made. However, you can manually trigger the 'storage' event in the local tab using the dispatchEvent()
method.
Here's an example of how to manually trigger the 'storage' event in the local tab:
function handleStorageEvent(event) {
console.log('Storage event detected:', event);
// Check the changed key and react accordingly
if (event.key === 'theme') {
// Update the UI theme based on the new value
updateTheme(event.newValue);
}
}
window.addEventListener('storage', handleStorageEvent);
function updateLocalStorage(key, newValue) {
const oldValue = localStorage.getItem(key);
localStorage.setItem(key, newValue);
const storageEvent = new StorageEvent('storage', {
key: key,
oldValue: oldValue,
newValue: newValue,
url: window.location.href,
storageArea: localStorage
});
window.dispatchEvent(storageEvent);
}
// Now when you update the localStorage, you can use the following function:
updateLocalStorage('theme', 'dark');
In this example, the updateLocalStorage
function is used to update the localStorage
data and manually dispatch a 'storage' event with the relevant information (key, oldValue
, newValue
, url, and storageArea
). This triggers the 'storage' event in the local tab, allowing the event listener to handle the event as needed.
Use cases and examples
The 'storage' event can be applied to various practical scenarios where localStorage
data needs to be synchronized or reacted to across multiple tabs or windows. Here are a few use cases and examples to demonstrate this:
Synchronize user preferences across multiple tabs
Imagine a web application where users can customize the UI theme. When a user changes the theme, all open tabs should update their UI immediately to reflect the new theme.
// Add an event listener for the 'storage' event
window.addEventListener('storage', (event) => {
if (event.key === 'theme') {
// Update the UI theme based on the new value
updateTheme(event.newValue);
}
});
// Function to update the UI theme
function updateTheme(theme) {
const body = document.querySelector('body');
body.className = theme;
}
// Function to change the theme and update localStorage
function changeTheme(theme) {
// Update localStorage with the new theme
updateLocalStorage('theme', theme);
// Update the UI theme in the current tab
updateTheme(theme);
}
// Usage: call the changeTheme function with the desired theme
changeTheme('dark');
In this example, when a user changes the theme by calling the changeTheme
function, it updates the localStorage
and the UI theme in the current tab. The 'storage' event listener in other open tabs detects the change and updates their UI theme accordingly.
Synchronize shopping cart data across multiple tabs
Consider an e-commerce website where users can add items to their shopping cart. When a user adds or removes items in one tab, the shopping cart should be updated in all other open tabs.
// Add an event listener for the 'storage' event
window.addEventListener('storage', (event) => {
if (event.key === 'cart') {
// Update the shopping cart UI based on the new value
updateCart(JSON.parse(event.newValue));
}
});
// Function to update the shopping cart UI
function updateCart(cartItems) {
// Update the cart UI with the new cartItems data
}
// Function to add an item to the cart and update localStorage
function addItemToCart(item) {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
cart.push(item);
updateLocalStorage('cart', JSON.stringify(cart));
}
// Function to remove an item from the cart and update localStorage
function removeItemFromCart(item) {
const cart = JSON.parse(localStorage.getItem('cart')) || [];
const updatedCart = cart.filter(cartItem => cartItem.id !== item.id);
updateLocalStorage('cart', JSON.stringify(updatedCart));
}
In this example, when a user adds or removes items from their shopping cart, the addItemToCart
or removeItemFromCart
functions update the localStorage, and the 'storage' event listener in other open tabs detects the change, updating their shopping cart UI accordingly.
Summary
In summary, this article discussed the JavaScript localStorage
event handler example, focusing on the 'storage' event and its use cases. The 'storage' event is part of the Web Storage API, designed to notify other tabs or windows within the same domain when changes are made to the localStorage. This event is useful for synchronizing application states and data across multiple open tabs or windows.
Key aspects covered in the article include:
- Introducing
localStorage
and the 'storage' event - Explaining the 'storage' event and its triggering conditions
- Detailing event properties: key,
oldValue
,newValue
, url, andstorageArea
- Demonstrating how to add an event listener for the 'storage' event
- Manually triggering the 'storage' event in the local tab using the
dispatchEvent()
method - Presenting practical use cases and examples for using the 'storage' event with localStorage
References
Window: storage event - Web APIs | MDN (mozilla.org)
this article is misleading. ‘storage’ event doesn’t on the same browser tab.
it will only work if you have the same website(or atleast with the same domain) in 2tabs, A and B. when making changes in localStorage in tabB, listener will be triggered in tabA. and vice-versa. or in case more than 2tabs, the tabs OTHER than the one making changes, will all receive a listener.
You are correct, this crucial information was missing so we have updated the article to also handle such usescases