How to Listen to LocalStorage Changes Across Tabs

The Web Storage API provides a built-in mechanism called the storage event, which allows JavaScript applications to detect and respond to localStorage changes made across different browser tabs or windows in real time. This article explains how the storage event works, the key properties it exposes, and how to implement it to keep user state synchronized across multiple active tabs belonging to the same origin.

What is the Storage Event?

The storage event is a DOM event fired on the window object whenever a document’s localStorage or sessionStorage object is updated. In the context of localStorage, it acts as a lightweight cross-tab communication channel.

A key characteristic of the storage event is that it only fires in browser tabs or windows other than the one that triggered the change. The tab performing the modification (setItem(), removeItem(), or clear()) does not trigger the event on itself. This behavior prevents infinite update loops and allows external tabs to sync their state automatically.

Storage Event Properties

When the storage event fires, the event listener receives a StorageEvent object containing useful contextual properties:

Implementing a Cross-Tab Listener

To listen for changes across tabs, attach an event listener to the window object:

window.addEventListener('storage', (event) => {
  // Ensure the change is from localStorage
  if (event.storageArea !== localStorage) return;

  console.log(`Key changed: ${event.key}`);
  console.log(`Old value: ${event.oldValue}`);
  console.log(`New value: ${event.newValue}`);
  console.log(`Updated by URL: ${event.url}`);

  // Example: Handle authentication sync
  if (event.key === 'authToken') {
    if (!event.newValue) {
      // User logged out in another tab
      window.location.href = '/login';
    } else {
      // User logged in or refreshed token
      updateSession(event.newValue);
    }
  }
});

Mutating LocalStorage in Another Tab

When another tab executes any standard mutation, the listener defined above executes immediately in all other open tabs of the same origin:

// Executed in Tab A:
localStorage.setItem('authToken', 'new-token-123');

// Result:
// Tab B, Tab C, etc., receive the 'storage' event instantly.
// Tab A does not receive the event.

Limitations and Considerations

  1. Same-Origin Policy: The storage event strictly obeys the same-origin policy. Changes in localStorage are only shared between tabs sharing the exact same protocol, domain, and port.
  2. Same-Tab Detection: If an application requires handling updates within the tab that made the change, developers must manually dispatch a custom event or wrap localStorage methods (setItem, removeItem) in helper functions.
  3. Storage Quotas: Because localStorage is synchronous and limited to roughly 5MB per origin, high-frequency data transmission across tabs should use alternatives like the Broadcast Channel API or WebSockets instead.