👀 Live Preview
Save a theme below, then open this page in another tab and save again — this tab receives the storage event:
Current theme: light — open another tab to test cross-tab sync

The onstorage handler runs JavaScript when the storage event fires on window. This happens when localStorage or sessionStorage is changed in another tab, window, or iframe of the same origin — not in the document that made the change. Use it to keep UI in sync across tabs (theme, username, cart count), react to logout in one tab, or refresh cached settings. Assign window.onstorage or use window.addEventListener("storage", …). Prefer addEventListener in production.
Not on body.
Other tabs.
key, values.
Live updates.
Preferred way.
Update UI locally.
onstorage AttributeThe primary purpose of onstorage is to react when web storage changes elsewhere so your page can stay synchronized across tabs. For example, if a user logs out in Tab A, Tab B can listen for the storage event and redirect to the login page.
The storage event is dispatched on the window object. It fires for localStorage changes across all same-origin tabs and for sessionStorage changes among tabs in the same browsing session. It does not bubble and is not cancelable.
When you call localStorage.setItem() in Tab A, Tab A does not get a storage event. Only other tabs receive it. Update your own UI immediately after writing storage in the same document.
Assign the handler on window — the event target for storage changes:
<script>
function handleStorageEvent(event) {
console.log("Key:", event.key);
console.log("Old:", event.oldValue);
console.log("New:", event.newValue);
}
window.onstorage = handleStorageEvent;
window.addEventListener("storage", handleStorageEvent);
</script>window, not <body> or form elements.storage event fires.setItem, removeItem, and clear in other documents.window.onstorage = function(event) { … }.window.addEventListener("storage", handler).The onstorage property accepts a function that receives a StorageEvent:
window.onstorage = handleStorageEvent — Named function reference.window.onstorage = function(event) { … } — Inline anonymous function.window.addEventListener("storage", handler).window.addEventListener("storage", (event) => {
// event.key — changed key (null if clear() was called)
// event.oldValue — value before change (null if new key)
// event.newValue — value after change (null if removed)
// event.url — URL of document that triggered the change
// event.storageArea — localStorage or sessionStorage object
if (event.key === "theme") {
document.body.dataset.theme = event.newValue || "light";
}
});| StorageEvent property | Meaning | Notes |
|---|---|---|
key | Changed storage key | null when clear() runs |
oldValue | Previous string value | null for new keys |
newValue | New string value | null when key removed |
url | Page that made the change | Same origin only |
storageArea | localStorage or sessionStorage | Which store changed |
| Target | Supported? | Notes |
|---|---|---|
window | Yes | Primary and correct target |
window.addEventListener("storage") | Yes | Recommended registration |
<body onstorage> | Avoid | Event does not bubble — use window |
<input>, <button> | No | Not an element-level event |
| IndexedDB / cookies | No | Only localStorage / sessionStorage |
onstorage vs BroadcastChannel vs same-tab updates| Approach | When it fires | Typical use |
|---|---|---|
storage event | Other tabs change web storage | Persisted cross-tab sync (theme, auth) |
BroadcastChannel | Any tab posts a message | Ephemeral messages, same-tab + cross-tab |
Direct UI update after setItem | Same tab immediately | Required — storage event won’t fire locally |
onhashchange | URL hash changes | Fragment routing, not storage |
Window handler, addEventListener with StorageEvent details, and cross-tab username sync.
Save a theme below, then open this page in another tab and save again — this tab receives the storage event:
Current theme: light — open another tab to test cross-tab sync
React when another tab changes localStorage:
<button onclick="changeStorage()">Change Storage</button>
<p id="event-log" aria-live="polite"></p>
<script>
function handleStorageEvent(event) {
document.getElementById("event-log").textContent =
"Key: " + event.key + ", New: " + event.newValue;
}
window.onstorage = handleStorageEvent;
function changeStorage() {
localStorage.setItem("username", "MariSelvan");
}
</script>When another document changes localStorage, the storage event fires on window and runs handleStorageEvent with the changed key and values.
Register with addEventListener and read all StorageEvent properties:
<script>
window.addEventListener("storage", function (event) {
log.textContent =
"Key: " + event.key + "\nOld: " + event.oldValue +
"\nNew: " + event.newValue + "\nURL: " + event.url;
});
</script>addEventListener is the production-friendly way to attach storage handlers. You can add multiple listeners and remove them with removeEventListener.
Keep a displayed username in sync when any tab updates localStorage:
var STORAGE_KEY = "syncUsername";
function renderName() {
display.textContent = "Signed in as: " +
(localStorage.getItem(STORAGE_KEY) || "Guest");
}
saveBtn.addEventListener("click", function () {
localStorage.setItem(STORAGE_KEY, input.value.trim() || "Guest");
renderName(); // same-tab update
});
window.addEventListener("storage", function (event) {
if (event.key !== STORAGE_KEY) return;
renderName(); // other-tab update
});Always update the UI in the tab that writes storage, and rely on the storage event for all other tabs. Filter by event.key when you only care about specific values.
aria-live="polite" on status regions updated by storage events.setItem() runs.
Manually — no event.
onstorage runs.
Theme, auth, settings.
The storage event and onstorage handler are supported in all modern browsers for localStorage and sessionStorage cross-document updates.
onstorage supportAll major browsers fire storage when another same-origin document changes web storage.
Bottom line: Reliable for cross-tab storage sync in all modern browsers.
window, not <body>setItem in the same tabevent.key when listening for specific valuesaddEventListener("storage", …) in productionstorage to fire in the tab that wrote dataalert() for cross-tab notificationsonstorage on non-window elementsstorageThe onstorage handler runs JavaScript when localStorage or sessionStorage changes in another tab — useful for themes, auth state, settings, and any persisted data that should stay consistent across browser tabs.
Remember: update the UI in the writing tab yourself, use addEventListener in production, and open a second tab when testing your handlers.
onstorageBookmark these before wiring cross-tab sync.
Not on body.
WhereNot same tab.
Whenkey, values.
DataSame-tab UI.
PairWeb storage.
Scopestorage event fires — when localStorage or sessionStorage is changed in another same-origin document (tab or window).storage event notifies other documents. The writing tab already knows it changed storage — update its UI directly after setItem.window and does not bubble. Use window.onstorage or window.addEventListener("storage", handler).localStorage in one tab (button or DevTools Application panel) and watch the other tab receive the event.window.addEventListener("storage", handler) is preferred in production — easier to attach multiple listeners and remove them later.Practice the onstorage attribute with cross-tab theme and username demos in the Try It editor.
5 people found this page helpful