Skip to lesson content
Web Technologies › Level 19
LEVEL 19 · STORAGE

Browser Storage and Web APIs

Save and restore small preferences with explicit lifetimes, validation and failure handling.

💾 Storage🔤 JSON records🔑 One-key ownership🧪 Lab + MCQs
01

Learning Objectives

A workshop form can collect data and an API loader can receive it, but neither automatically remembers a learner’s choices after the page reloads. Browser storage adds a local record with its own lifetime, failure modes and validation requirements. In this lesson, build a small study preference rather than treating the browser as a permanent database.

Compare ordinary JavaScript memory, localStorage, sessionStorage and cookies. Serialize a controlled record, load it defensively, remove only the record you own and describe when another document receives a storage event. You will also identify where other browser APIs belong in a larger application.

Lifetime

Choose memory, a page session or a longer-lived preference.

Data contract

Store text; parse and validate before accepting it.

Failures

Handle denied access and failed writes honestly.

Ownership

Use one named key and preserve other site data.

02

Memory and Persistence Are Different Decisions

A variable or Map belongs to the running JavaScript environment. It is useful for a draft, a current selection or a temporary result. Reloading the document creates a new environment, so a new Map does not contain the old draft. Navigating away can also end that instance.

Persistence means putting data somewhere that can outlive the current script instance. It introduces another source of truth: the editor may contain unsaved changes while the stored record still contains an earlier value. Label Save and Load separately so learners can observe that distinction.

Our preference contains a topic, a study duration and a short note. The default lab mode is memory. Selecting localStorage or sessionStorage does not immediately read or write anything; the learner explicitly chooses an operation. This makes the persistence boundary visible instead of hiding it inside every keystroke.

const draft = new Map();
draft.set("study", "HTML for 15 minutes");
console.log(draft.get("study"));
// A freshly reloaded page creates a new Map.

Resetting form controls is a third action. A reset can restore editor defaults while leaving the saved value untouched. Deleting a saved value should be a clearly named operation, not an unexpected side effect of resetting the screen.

03

Compare the Four Storage Choices

Choose a mechanism from the behavior your feature needs. A temporary preview can use memory. A theme preference can use localStorage. A draft intended for one page session can use sessionStorage. A server-managed session commonly uses a cookie carrying a session identifier. These are different contracts, not a ranking from bad to good.

Web Storage values are not automatically attached to HTTP requests. Cookies can accompany matching requests subject to cookie rules and browser policy. A value saved locally is also not automatically synchronized to an account, another device or the server.

ChoiceTypical lifetimeUseful exampleImportant limit
JavaScript memoryCurrent script instanceUnsaved previewA reload creates fresh state
localStorageCan survive reloads and browser restartsSmall study preferenceUser settings, clearing and policy affect availability
sessionStoragePage session, partitioned by origin and tabTab-specific draftNot a server login session
CookieSession or configured expiryServer session identifierRequest scope and security attributes matter

None of these choices guarantees that a record is correct merely because it exists. A preference written by an older application version may no longer match today’s fields. Treat persistence as a boundary where data must be checked again.

04

Origins, Paths and Storage Scope

An origin combines scheme, host and port. For example, https://codebhavya.com and https://www.codebhavya.com have different hosts, so do not assume they share one localStorage area. HTTP and HTTPS are also different origins.

A pathname does not create a separate Web Storage namespace. Lessons under different folders on one origin may use the same localStorage area. A generic key such as data can collide with another feature. Use a descriptive application key and a record version.

A namespaced key prevents accidental collisions; it does not create an access-control boundary between scripts running with the same origin’s privileges. The lab therefore uses a fictional study note and never asks for credentials or confidential information.

Locate a stored preference
Origin

Scheme + host + port selects the area.

Backend

Local and session storage are separate areas.

Key

One feature-specific key identifies the record.

Value

A JSON string represents the controlled preference.

const key = "codebhavya-wt19-storage-lab-v1";
// Same-origin paths can share this localStorage key.
// sessionStorage uses a different area for the same key text.
05

localStorage — Remember a Small Preference

The localStorage property gives access to a synchronous key/value store. Use setItem to write a string, getItem to read one and removeItem to delete a named entry. A successful write is available to later reads from the same applicable storage area.

Local data can survive reloads and restarts, but “local” does not mean guaranteed forever. Users can clear site data, private browsing has its own lifetime and browser policies can prevent access. A site must remain usable when a preference is missing.

In the lab, Save in local mode is the only preference-writing action. After a reload, select local mode again and press Load. The editor starts with defaults and does not silently import the old note. Delete this lab key when you finish the experiment.

try {
  const store = window.localStorage;
  store.setItem("study-topic", "html");
  const topic = store.getItem("study-topic");
  store.removeItem("study-topic");
} catch (error) {
  console.error("Preference storage unavailable", error.name);
}

This teaching snippet uses a separate example key. Do not run broad cleanup code on a shared site. Catch property access as well as method calls, since failure can occur before you obtain the Storage object.

06

sessionStorage — A Page Session, Not a Login

Session storage is partitioned by origin and top-level browsing context, usually a tab. A reload within that page session can retain its values. Ending the page session clears its session storage; browser restoration behavior should not be treated as an application backup guarantee.

A newly opened page with an opener can start with a copy of the opener’s session storage. The two copies then evolve independently. A fresh independent tab and a duplicated or restored tab need not provide the same starting experiment.

SessionStorage is not the server’s authenticated session. Saving loggedIn = true cannot authenticate a user. The next lesson will connect server requests, sessions and server-side checks. Here, use session mode only to explore a local draft lifetime.

try {
  window.sessionStorage.setItem("draft-topic", "css");
  console.log(window.sessionStorage.getItem("draft-topic"));
} catch (error) {
  console.error("Draft storage unavailable", error.name);
}

For a controlled browser check, reload the same tab and Load the lab key. Then compare with an independently opened tab. Describe how you opened it before concluding that session data is shared.

07

Strings, JSON and Missing Values

Storage keys and values are strings. Passing a plain object directly to setItem does not preserve its useful field structure. Serialize a simple record with JSON.stringify, and parse retrieved text with JSON.parse.

GetItem returns null when a key is absent. The stored string "null" is a present value that parses into null; an empty string is another present value. Check absence before parsing rather than using a truthiness check that mixes these cases.

JSON cannot preserve every JavaScript value. Functions, undefined fields, cyclic objects and special class instances need separate decisions. A small record made only of strings and ordinary numbers is a good starting contract.

const preference = {
  version: 1, topic: "html", minutes: 15, note: "Review forms"
};
const text = JSON.stringify(preference);
// After reading: distinguish null from stored text.
if (text !== null) {
  const parsed = JSON.parse(text);
  console.log(parsed.topic);
}

The text variable above represents serialization, not an actual storage read. In a real loader, obtain raw text from getItem inside the error-handling boundary. Parsing can throw, and a successful parse still needs the next section’s validation.

08

Validate the Record and Its Version

Our exact record contract is {version, topic, minutes, note}. Version must be numeric 1. Topic must be html, css or javascript. Minutes must be numeric 15, 30 or 45. Note must be a string whose trimmed length is at most 160 characters; an empty note is allowed. Unexpected fields are rejected so the exercise has one explicit shape.

The editor converts its known duration select value into a number before validating. Loaded JSON does not receive that conversion: the string "30" is rejected. This difference helps distinguish deliberate input normalization from blindly repairing stored data.

The loader limits raw text to 4096 characters before parsing and checks the whole record before replacing any editor field. Malformed JSON, an unknown version or a wrong shape leaves unsaved editor content intact. The learner can inspect the raw text and deliberately delete the lab record if needed.

if (record.version !== 1) throw new Error("Unsupported version");
if (![15, 30, 45].includes(record.minutes)) {
  throw new Error("Invalid study duration");
}
// Also check object shape, topic and bounded note.
// Only then update editor fields.

A production migration should explicitly convert an old supported version into the new contract and validate the result. Do not claim to migrate a record by ignoring its version. The JSON checker below validates pasted examples without writing them to browser storage.

09

Denied Access, Quotas and Honest Feedback

Storage can fail because access is denied or a write cannot be accommodated. Existence of window.localStorage is not proof that a specific write will succeed. Keep the read or write in try/catch and report the outcome of the operation actually attempted.

The lab has two clearly labeled simulations. Blocked access throws a SecurityError before using the selected backend. Quota failure throws a QuotaExceededError only for Save; Load, Inspect and Delete can still operate. These switches do not change browser settings or fill real storage.

Native browser errors are also caught. A failed Save must not announce success, erase the previous record or silently write into another backend. The editor remains available, so the learner can choose memory explicitly if persistent storage is unavailable.

try {
  store.setItem(key, JSON.stringify(validated));
  showStatus("Saved in the selected storage area.");
} catch (error) {
  showStatus("Save failed: " + error.name);
}

Avoid a misleading “saved” message before setItem returns. Storage failure and validation failure need different descriptions: one concerns the backend, while the other concerns the attempted data.

10

Delete One Key and Keep Other Features Intact

A website can store theme choices, completion markers and unrelated feature records in one origin’s area. RemoveItem(key) deletes the named entry. Storage.clear() removes every entry in that area and is inappropriate for a lesson’s cleanup button.

The lab uses one key in each selected backend. Delete in local mode does not delete the session-mode record, and resetting editor fields does not delete either. The memory record is independent as well. This gives three observable locations for the same named preference.

Inspect shows bounded literal text with textContent. It does not insert stored notes as HTML. A note containing angle brackets should remain visible text rather than creating a new element.

store.removeItem("codebhavya-wt19-storage-lab-v1");
// Preserve unrelated keys, including course completion.
output.textContent = rawText;
// Display saved text as text, rather than HTML.

Deleting a missing key is harmless. Still report the selected area so a learner understands why a record in another backend remains. Do not imply that deleting this key clears all personal data on the site.

11

Storage Events and Unsaved Work

A storage event informs other documents that share the changed storage area. The document performing a change does not receive its own event. Local storage changes can notify other same-origin tabs; session storage notifications stay within the same top-level context, such as a same-origin iframe in that tab.

The event includes key, oldValue, newValue and storageArea. A key of null can represent a clear operation. Filter by the storage area and the key your feature owns. Receiving an event about a different feature is not a reason to reload this preference.

The lab listens only for relevant localStorage events while local mode and normal access are selected. It announces that the saved record changed elsewhere and offers Load. It does not automatically replace unsaved editor fields. Concurrent updates still need an application conflict policy; this exercise uses explicit Save and Load.

window.addEventListener("storage", event => {
  if (event.storageArea !== window.localStorage) return;
  if (event.key !== key && event.key !== null) return;
  showStatus("Saved data changed elsewhere. Load to inspect.");
});

A single-tab test cannot demonstrate a native cross-tab notification. Open the deployed lesson in two same-origin tabs, select local mode in both and save a changed record in one. Check the other tab’s notice before deliberately loading it.

12

Cookies — Data Attached to Matching Requests

Cookies serve a different purpose from a local preference store: they can accompany HTTP requests according to domain, path, expiry and browser policy. A server can set them with the Set-Cookie response header. A server session cookie often carries an opaque identifier while the server keeps session data.

Secure restricts transmission to secure contexts such as HTTPS. HttpOnly prevents JavaScript from reading the cookie. SameSite governs cross-site sending behavior; SameSite=None requires Secure. These settings address different concerns and do not replace server validation.

JavaScript cannot set an HttpOnly cookie using document.cookie. Avoid putting passwords or a trusted authentication decision in a study preference. The lab does not create cookies or implement login; it compares their role with browser-side storage.

Set-Cookie: session_id=opaque-example; Path=/; Secure; HttpOnly; SameSite=Lax

This line illustrates an HTTP response header, not JavaScript to paste into the lab. A real server must create, validate and expire session identifiers correctly. Cookie attributes should match the application’s intended request flow.

13

Other Browser APIs — Choose by the Task

The browser offers many capabilities beyond string storage. IndexedDB is suitable for larger structured collections and asynchronous database operations. The Cache API handles stored request/response pairs. Neither is simply another spelling of localStorage, and both require a deliberate lifecycle and error strategy.

URL and URLSearchParams help construct and inspect URL data. History APIs change navigation state, not permanent account data. Clipboard and geolocation capabilities bring permission and context requirements that vary by API and browser. Check a capability’s contract before using it.

Match the feature to the data: a short display preference can remain in Web Storage, a substantial offline collection may need IndexedDB, and downloaded resources may belong in a caching strategy. A server remains responsible for authoritative shared records.

Choose a capability
Small preference

Web Storage with a bounded record.

Structured collection

An asynchronous database such as IndexedDB.

Response resources

A deliberate Cache API strategy.

Navigation data

URL parsing and history state.

This lesson introduces these alternatives; its interactive exercise deliberately stays with one tiny string record. Implementing a complete offline database or service worker would require its own lesson and tests.

14

Privacy and Trust Boundaries

Minimize the data a feature keeps. A fictional study topic and duration are enough to learn the mechanics. Do not ask learners to put passwords, payment information or confidential notes into a storage demonstration. Explain how to remove the demonstration record.

Same-origin script access means localStorage is not a secret vault. A successful parse, a stored completion flag or a local boolean does not prove identity, permissions or ownership on the server. Trusted decisions must be checked at the relevant authority.

Render accepted notes as text. Validate records loaded from storage just as you validate a response from an API: they can be old, manually modified or produced by another script. Keep deletion narrow and expose failure clearly.

Minimize

Keep only fields required by the learning task.

Explain

Show the selected backend and the exact key.

Remove

Provide a button that deletes this feature’s record.

Recheck

Validate whenever saved text enters the editor.

A real product may have consent and retention requirements based on its purpose and jurisdiction. A storage API alone does not decide those requirements. The exercise demonstrates explicit user actions without claiming that it establishes a complete privacy policy.

15

Design the Save and Load Lifecycle

Separate editor state from saved state. On Save, validate all fields, serialize the accepted record and write it to the selected backend. Announce success only after the write returns. On Load, check for absence, parse bounded text, validate the contract and then update the editor together.

On failure, preserve the draft and identify the failed stage. On Reset fields, restore the editor defaults and clear its display output while leaving the saved record intact. On Delete, remove only the owned key from the selected backend.

The visualizer follows a normal Save then Load journey. The lab lets you introduce missing data, failed access, failed writes and bad JSON separately. These paths are part of the feature, rather than exceptional details to add after the happy path is finished.

Preference lifecycle
Edit

The draft may differ from saved data.

Save

Validate, serialize, then attempt one-key write.

Load

Read, distinguish absence, parse and validate.

Delete / reset

Delete saved key or reset editor, explicitly.

Before marking complete, reproduce the failure paths and explain why they do not overwrite the editor or remove unrelated site records. Then compare memory loss on reload with the selected browser storage lifetime.

16

Premium Visualizer — Save and Restore a Preference

Follow a normal preference through edit, validation, serialization, reading and restoration. The five-stage player keeps the same visual style and controls as the previous lessons. The lab below separately exercises missing data and failed operations.

BROWSER STORAGE TRACE
Step 1 of 5
STEP 01

Prepare a study preference

The editor holds a draft; nothing has been saved yet.

{ version: 1, topic: "html", minutes: 15, note: "Review forms" }

What is happening?

Changing fields does not write storage. Select the area and explicitly press Save.

17

Premium Interactive — Study Preference Storage Lab

Memory mode is the default and lasts only for this page instance. Local and session modes use the real browser storage areas when available. Select a backend, edit a fictional preference and explicitly Save or Load. No preference is automatically read or written when you switch modes.

The single key is codebhavya-wt19-storage-lab-v1. Delete removes only this key from the selected backend. Reset fields restores editor defaults without deleting saved data. Use a short fictional note, then delete the lab key from local and session modes when finished.

Failure switches simulate blocked access or a quota failure without changing browser policy or filling storage. Native errors are also caught. The separate JSON checker validates pasted text without writing it into any storage area.

Leave the note empty or use a short learning reminder. The saved record version is 1.

Memory mode. No preference has been read or saved.

Last operation output

No operation yet.

JSON contract checker · does not write storage

Try the sample, an unknown version, a string duration or malformed JSON.

No JSON checked yet.
18

Debugging — Find the Storage Boundary

Wrong area

Confirm origin, backend and exact key before assuming data disappeared.

Bad JSON

Distinguish missing text, malformed JSON and an unacceptable record.

Failed write

Check the caught error; do not report success or switch areas silently.

Too much cleanup

Remove the one owned key, rather than clearing the whole origin.

If the editor returns to defaults after reload, select the original backend and Load. Memory cannot recover an earlier script instance. If a stored record is present but fails validation, inspect the raw value and the expected version instead of overwriting the current draft.

If another tab does not show a notice, check that both pages have the same origin, local mode is selected and a value actually changed. Session storage is not a cross-tab message bus. An event caused by another feature should not reload this editor.

If Reset seems not to erase data, that is its intended contract: Reset fields keeps the saved record. Use Delete this lab key in the selected backend and then Load to observe the missing outcome.

19

Interview Questions — Flip to Explain

QUESTION

Does localStorage automatically synchronize with a server?

Click or press Enter to explain
ANSWER

No. It stores strings in an applicable browser storage area. Server or account synchronization needs a separate implemented flow.

QUESTION

What does getItem return for an absent key?

Click or press Enter to explain
ANSWER

Null. A present string such as "null" or an empty string is a different case.

QUESTION

Why validate after JSON.parse?

Click or press Enter to explain
ANSWER

Parsing accepts many JSON values. The application still needs the supported version, fields, types and bounds.

QUESTION

Can sessionStorage authenticate a user?

Click or press Enter to explain
ANSWER

No. A local boolean is not a server-authorized login or permission decision.

QUESTION

Why catch access to window.localStorage itself?

Click or press Enter to explain
ANSWER

Obtaining the storage area can fail, before getItem or setItem is called.

QUESTION

Why avoid storage.clear in a lesson?

Click or press Enter to explain
ANSWER

It removes every key in that area, including other site features. Remove only the lab key.

QUESTION

Does the writer receive its own storage event?

Click or press Enter to explain
ANSWER

No. Other documents sharing the changed area can receive the notification.

QUESTION

What does HttpOnly do for a cookie?

Click or press Enter to explain
ANSWER

It prevents JavaScript access to that cookie. A server sets it through a response header; it does not replace server-side authorization.

20

MCQ Practice — Choose the Storage Behavior

PRACTICE

1. What happens to a new Map after a fresh page reload?

PRACTICE

2. What does getItem return when the key is absent?

PRACTICE

3. Which is the lab’s accepted duration?

PRACTICE

4. What should happen after loading version 2 in this version 1 lab?

PRACTICE

5. What does Reset fields do here?

PRACTICE

6. Which cleanup preserves other site features?

PRACTICE

7. What does the simulated quota mode block?

PRACTICE

8. Who receives a localStorage change event?

PRACTICE

9. How should an external change affect an unsaved editor here?

PRACTICE

10. Which cookie attribute prevents JavaScript reading it?

PRACTICE

11. Are Web Storage values automatically included in HTTP request headers?

PRACTICE

12. What should a failed Save report?

21

Extra Practice — Observe Specific Storage Outcomes

Memory reload

Save in memory, reload, then Load memory. Expected: no record in the new instance.

Local reload

Save CSS/30 in local mode, reset fields, then Load. Expected: CSS/30 restored; verify after reload too.

Session reload

Save JavaScript/45 in session mode and reload the same tab. Expected: Load restores it if the area remains available.

Quota

Save a normal record, then change the note and simulate quota. Expected: Save fails; normal Load returns the earlier record.

Blocked

Select blocked access and try Save/Load/Inspect/Delete. Expected: each fails and editor fields stay intact.

Wrong shape

Check JSON with version 2, minutes "30", null and malformed text. Expected: each rejects without writing storage.

Narrow delete

Delete in local mode, then Load local and session. Expected: local missing; an independently saved session record remains.

Another tab

In two same-origin tabs use normal local mode. Save a changed note in one. Expected: other tab announces change while preserving its draft.

22

Quick Revision

Memory: Fresh script instances begin with fresh memory.
Local: Can retain small preferences; availability is not guaranteed.
Session: Partitioned by origin and top-level browsing context.
Text: Serialize simple records with JSON.
Contract: Validate version, shape, types and bounds.
Failure: Catch getter and method errors.
Key: Namespace one feature’s record.
Delete: Remove only the key you own.
Event: Other sharing documents receive change notices.
Cookie: Request-sending rules differ from Web Storage.
23

Glossary — Flip to Learn

TERM

Persistence

Click to see meaning
DEFINITION

Persistence

Keeping data beyond a current script instance, subject to the chosen storage lifecycle.

TERM

Origin

Click to see meaning
DEFINITION

Origin

The combination of scheme, host and port used in browser access boundaries.

TERM

localStorage

Click to see meaning
DEFINITION

localStorage

A synchronous string key/value area that can retain data beyond reloads.

TERM

sessionStorage

Click to see meaning
DEFINITION

sessionStorage

A synchronous string key/value area partitioned by origin and top-level browsing context.

TERM

Serialization

Click to see meaning
DEFINITION

Serialization

Converting a supported record into a text representation such as JSON.

TERM

Record version

Click to see meaning
DEFINITION

Record version

A field identifying the application data format expected by a loader.

TERM

Quota error

Click to see meaning
DEFINITION

Quota error

A failed attempt to write when the selected area cannot accommodate the operation.

TERM

Storage event

Click to see meaning
DEFINITION

Storage event

A notification to other documents sharing an area that its data changed.

TERM

Cookie

Click to see meaning
DEFINITION

Cookie

A browser-managed value that can accompany matching HTTP requests.

TERM

HttpOnly

Click to see meaning
DEFINITION

HttpOnly

A cookie attribute that prevents JavaScript access to that cookie.

24

Final Challenge — A Defensive Preference Store

Build a study preference with an explicit backend selector and separate Save, Load, Delete and Reset fields actions. Start in memory. Use one namespaced key in each browser storage area and keep a numeric record version.

Validate before writing and again after reading. Distinguish absence from malformed text and a wrong contract. Preserve the draft on failure and report real backend failures without silent fallback. Show raw saved data as literal text.

Demonstrate normal round trips, reload lifetimes, blocked access, quota failure and invalid JSON. Keep unrelated site keys intact. In a deployed browser, check a two-tab local change notice without replacing unsaved work. Delete the demonstration key after the experiment.

Success criterion: explain where data lives, when it can disappear and why saved text is still untrusted input. Level 20 will introduce server-side execution and application flow.

25

Level 19 Complete?

Before marking complete, compare the storage lifetimes, restore one valid preference, reject a bad record and explain narrow deletion plus honest failure feedback. Completion is a local study marker rather than a score.