HTML onstorage Attribute

Beginner
⏱️ 6 min read
📚 Updated: Jun 2026
🎯 3 Examples
Events & Handlers

Introduction

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.

What You’ll Learn

01

Window handler

Not on body.

02

storage event

Other tabs.

03

StorageEvent

key, values.

04

Cross-tab sync

Live updates.

05

addEventListener

Preferred way.

06

Same-tab gap

Update UI locally.

Purpose of onstorage Attribute

The 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.

💡
Does not fire in the same tab

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.

📝 Syntax

Assign the handler on window — the event target for storage changes:

onstorage.html
<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>

Syntax Rules

  • Target is window, not <body> or form elements.
  • Value is JavaScript executed when the storage event fires.
  • Triggered by setItem, removeItem, and clear in other documents.
  • Does not fire in the document that made the storage change.
  • Only same-origin storage changes are reported.
  • JavaScript: window.onstorage = function(event) { … }.
  • Modern alternative: window.addEventListener("storage", handler).

💎 Values

The onstorage property accepts a function that receives a StorageEvent:

  • window.onstorage = handleStorageEvent — Named function reference.
  • window.onstorage = function(event) { … } — Inline anonymous function.
  • Preferred: window.addEventListener("storage", handler).
onstorage-handler.js
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";
  }
});

⚡ Quick Reference

StorageEvent propertyMeaningNotes
keyChanged storage keynull when clear() runs
oldValuePrevious string valuenull for new keys
newValueNew string valuenull when key removed
urlPage that made the changeSame origin only
storageArealocalStorage or sessionStorageWhich store changed

Applicable Elements

TargetSupported?Notes
windowYesPrimary and correct target
window.addEventListener("storage")YesRecommended registration
<body onstorage>AvoidEvent does not bubble — use window
<input>, <button>NoNot an element-level event
IndexedDB / cookiesNoOnly localStorage / sessionStorage

onstorage vs BroadcastChannel vs same-tab updates

ApproachWhen it firesTypical use
storage eventOther tabs change web storagePersisted cross-tab sync (theme, auth)
BroadcastChannelAny tab posts a messageEphemeral messages, same-tab + cross-tab
Direct UI update after setItemSame tab immediatelyRequired — storage event won’t fire locally
onhashchangeURL hash changesFragment routing, not storage

Examples Gallery

Window handler, addEventListener with StorageEvent details, and cross-tab username sync.

👀 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

Example — window.onstorage handler

React when another tab changes localStorage:

window-onstorage.html
<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>
Try It Yourself

How It Works

When another document changes localStorage, the storage event fires on window and runs handleStorageEvent with the changed key and values.

Dynamic Values with JavaScript

Register with addEventListener and read all StorageEvent properties:

dynamic-onstorage.html
<script>
  window.addEventListener("storage", function (event) {
    log.textContent =
      "Key: " + event.key + "\nOld: " + event.oldValue +
      "\nNew: " + event.newValue + "\nURL: " + event.url;
  });
</script>
Try It Yourself

How It Works

addEventListener is the production-friendly way to attach storage handlers. You can add multiple listeners and remove them with removeEventListener.

Example — Cross-tab username sync

Keep a displayed username in sync when any tab updates localStorage:

cross-tab-sync.html
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
});
Try It Yourself

How It Works

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.

♿ Accessibility

  • Announce cross-tab changes — Use aria-live="polite" on status regions updated by storage events.
  • Do not surprise users — If storage sync changes layout or theme, ensure contrast and focus order remain usable.
  • Logout sync — When auth state clears in another tab, move focus to a clear message or login link.
  • Keyboard access — Controls that write storage must remain keyboard-operable.
  • Avoid alert() — Use visible on-page feedback instead of blocking dialogs.

🧠 How onstorage Works

1

Tab A writes storage

setItem() runs.

Write
2

Tab A updates UI

Manually — no event.

Same tab
3

storage fires on Tab B

onstorage runs.

Other tabs
=

Tabs stay in sync

Theme, auth, settings.

Browser Support

The storage event and onstorage handler are supported in all modern browsers for localStorage and sessionStorage cross-document updates.

Web Storage API · Fully supported

Universal onstorage support

All major browsers fire storage when another same-origin document changes web storage.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 8+ supported
Full support
Opera Fully supported
Full support
onstorage attribute 99% supported

Bottom line: Reliable for cross-tab storage sync in all modern browsers.

💡 Best Practices

✅ Do

  • Attach handlers on window, not <body>
  • Update UI immediately after setItem in the same tab
  • Filter by event.key when listening for specific values
  • Use addEventListener("storage", …) in production
  • Test with two tabs of the same page open

❌ Don’t

  • Expect storage to fire in the tab that wrote data
  • Use alert() for cross-tab notifications
  • Put onstorage on non-window elements
  • Assume IndexedDB or cookie changes trigger storage
  • Store sensitive secrets only in localStorage without extra care

Conclusion

The 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.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about onstorage

Bookmark these before wiring cross-tab sync.

5
Core concepts
🔌 02

Other tabs

Not same tab.

When
📄 03

StorageEvent

key, values.

Data
🔄 04

+ local update

Same-tab UI.

Pair
05

Not cookies

Web storage.

Scope

❓ Frequently Asked Questions

It runs JavaScript when the storage event fires — when localStorage or sessionStorage is changed in another same-origin document (tab or window).
By design, the storage event notifies other documents. The writing tab already knows it changed storage — update its UI directly after setItem.
No. The event targets window and does not bubble. Use window.onstorage or window.addEventListener("storage", handler).
Open the same page in two tabs. Change 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.
Yes in all modern browsers. Internet Explorer 8+ also supports the storage event.

Sync data across browser tabs

Practice the onstorage attribute with cross-tab theme and username demos in the Try It editor.

Try cross-tab demo →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful