Lesson 0003 · ~12 minutes
One skill: run a 60-second design-review scan — when
sessionStorage is the wrong tool, and which edges kill
“just stash it in the session.”
You can reject bad proposals quickly (multi-tab bus, tokens, bulk data, “always available”) and green-light a tab-scoped wizard draft with eyes open on sync cost and write failures.
Two sticky spots from last time — lock them before the scan:
sessionStorage.setItem in Tab A does
not fire storage on Tab B (or on Tab A).
Session maps are not shared across tabs
(MDN).
typeof sessionStorage alone. Probe with
setItem + removeItem (MDN
storageAvailable) and still
try/catch production writes.
| Requirement | Usually not sessionStorage | Prefer |
|---|---|---|
| Multi-tab live sync of one key | Tab-private map + no cross-tab events |
localStorage events,
BroadcastChannel, or server
|
| Survive browser restart / all tabs | Dies when the tab closes | localStorage (tiny) or server prefs |
| Large structured / offline entities | Strings, ~few MB, sync, no workers | IndexedDB |
| App shell / HTTP assets offline | Not Request/Response storage | Cache API (+ SW) |
| Access / refresh tokens | Any script can read (XSS loot) | HttpOnly cookies / hardened session design |
| Worker-owned pipeline state |
Storage is
Window-only
|
IndexedDB (or message the window) |
Lesson 1 still holds: sessionStorage wins for small tab-scoped session state — isolation is the feature, not a bug (web.dev, HTML ticket-window motivation).
Design reviews often say: “we’ll put the flag in sessionStorage and
listen for storage in other tabs.” That pattern is for
localStorage, not sessionStorage
(MDN Using guide).
storage events.
storage event for either store.
window.open starts with a
copy of sessionStorage, then diverges — still not a live
channel
(MDN).
“sessionStorage is for isolation, not broadcast. If two tabs must stay in sync, don’t use it as the bus.”
Web Storage is synchronous on the main thread (MDN, web.dev). Fine for occasional small reads/writes; bad for every keystroke on a huge string or polling loops.
setItem can throw
QuotaExceededError
or fail when the user/browser disables storage (often tied to cookie
blocking).
storageAvailable("sessionStorage"), and still catch
write errors in product paths.
Anything in Web Storage is readable by same-origin script. XSS that can run on your origin can dump every key. Putting long-lived API tokens in sessionStorage or localStorage is a classic foot-gun — “tab only” does not make it httpOnly.
Prefer patterns where secrets never land in script-readable storage (e.g. httpOnly cookies for session cookies, short-lived memory tokens with a careful design). Full auth architecture is out of scope here; the deal-breaker is: don’t stash secrets in Web Storage by default.
Equal-length options. Includes a deliberate re-test of the lesson-2 soft spots.
Proposal: “Put cart count in sessionStorage; other open tabs listen
for storage and update the badge.”
Checkout wizard step index: small string, must survive reload in this tab only; parallel checkout tabs must stay independent.
Auth proposal: store the long-lived OAuth access token in sessionStorage so SPA fetches can attach Authorization after reload.
Tab A: sessionStorage.setItem("k","1"). Same-origin Tab
B open, no iframes. Who receives storage?
Before shipping a sessionStorage-backed draft, what is the sound availability posture?
storage for session writes.
web.dev — Storage for the web (why Web Storage is the “use with caution” bucket). For the event and probe details, keep MDN Using the Web Storage API and the checklist open.