We use cookies to enhance your experience on the site
CodeWorlds

Web Storage (localStorage and sessionStorage)

In Jurassic Park, we need to save visitor preferences, security settings, and temporary session data on the client side. JavaScript provides two built-in storage mechanisms: localStorage and sessionStorage — both letting us store key-value pairs in the browser without needing a server.

localStorage vs sessionStorage

| Feature | localStorage | sessionStorage | |---------|-------------|----------------| | Persistence | Survives browser close/reopen | Cleared when tab/window closes | | Scope | Shared across all tabs/windows of the same origin | Isolated to the current tab | | Storage limit | ~5-10 MB per origin | ~5-10 MB per tab | | Use case | User preferences, settings | Temporary session data, form state |

Basic Operations

1// setItem — save data
2localStorage.setItem('parkTheme', 'dark');
3localStorage.setItem('language', 'en');
4sessionStorage.setItem('currentSector', 'B-4');
5
6// getItem — read data
7const theme = localStorage.getItem('parkTheme'); // "dark"
8const missing = localStorage.getItem('nothere'); // null
9
10// removeItem — delete a key
11localStorage.removeItem('parkTheme');
12
13// clear — delete all data
14localStorage.clear();
15
16// length and key() — iterate
17console.log(localStorage.length); // number of items
18for (let i = 0; i < localStorage.length; i++) {
19  const key = localStorage.key(i);
20  console.log(key, localStorage.getItem(key));
21}

Storing Complex Data with JSON

Web Storage only stores strings, so for objects and arrays we use JSON:

1// Storing an object
2const userPrefs = {
3  theme: 'dark',
4  fontSize: 16,
5  language: 'en',
6  notifications: { security: true, feeding: true }
7};
8
9localStorage.setItem('userPreferences', JSON.stringify(userPrefs));
10
11// Reading back
12const storedPrefs = JSON.parse(localStorage.getItem('userPreferences'));
13console.log(storedPrefs.theme); // "dark"
14
15// Storing an array
16const recentIncidents = ['INC-001', 'INC-002', 'INC-003'];
17localStorage.setItem('recentIncidents', JSON.stringify(recentIncidents));
18
19const incidents = JSON.parse(localStorage.getItem('recentIncidents') || '[]');

UserPreferences Class

1class UserPreferences {
2  constructor() {
3    this.storageKey = 'jurassicParkPrefs';
4    this.defaults = {
5      theme: 'light',
6      language: 'en',
7      alertSound: true,
8      mapZoom: 2,
9      favoriteSection: 'overview'
10    };
11  }
12
13  get(key) {
14    const stored = localStorage.getItem(this.storageKey);
15    const prefs = stored ? JSON.parse(stored) : {};
16    return key in prefs ? prefs[key] : this.defaults[key];
17  }
18
19  set(key, value) {
20    const stored = localStorage.getItem(this.storageKey);
21    const prefs = stored ? JSON.parse(stored) : {};
22    prefs[key] = value;
23    localStorage.setItem(this.storageKey, JSON.stringify(prefs));
24  }
25
26  setMultiple(updates) {
27    const stored = localStorage.getItem(this.storageKey);
28    const prefs = stored ? JSON.parse(stored) : {};
29    Object.assign(prefs, updates);
30    localStorage.setItem(this.storageKey, JSON.stringify(prefs));
31  }
32
33  reset() {
34    localStorage.removeItem(this.storageKey);
35  }
36
37  getAll() {
38    const stored = localStorage.getItem(this.storageKey);
39    const prefs = stored ? JSON.parse(stored) : {};
40    return { ...this.defaults, ...prefs };
41  }
42}
43
44const prefs = new UserPreferences();
45prefs.set('theme', 'dark');
46prefs.set('alertSound', false);
47console.log(prefs.get('theme')); // "dark"
48console.log(prefs.getAll()); // All preferences with defaults

DataCache with TTL (Time To Live)

1class DataCache {
2  constructor(storage = localStorage, defaultTtlMs = 5 * 60 * 1000) {
3    this.storage = storage;
4    this.defaultTtlMs = defaultTtlMs;
5  }
6
7  set(key, value, ttlMs = this.defaultTtlMs) {
8    const item = {
9      value,
10      expiresAt: Date.now() + ttlMs
11    };
12    this.storage.setItem(`cache:${key}`, JSON.stringify(item));
13  }
14
15  get(key) {
16    const stored = this.storage.getItem(`cache:${key}`);
17    if (!stored) return null;
18
19    const item = JSON.parse(stored);
20
21    if (Date.now() > item.expiresAt) {
22      this.storage.removeItem(`cache:${key}`);
23      return null; // Expired
24    }
25
26    return item.value;
27  }
28
29  getOrFetch(key, fetchFn, ttlMs) {
30    const cached = this.get(key);
31    if (cached !== null) return Promise.resolve(cached);
32
33    return fetchFn().then(value => {
34      this.set(key, value, ttlMs);
35      return value;
36    });
37  }
38
39  clear(prefix) {
40    const keysToRemove = [];
41    for (let i = 0; i < this.storage.length; i++) {
42      const key = this.storage.key(i);
43      if (key && key.startsWith(`cache:${prefix || ''}`)) {
44        keysToRemove.push(key);
45      }
46    }
47    keysToRemove.forEach(key => this.storage.removeItem(key));
48  }
49}
50
51// Usage
52const cache = new DataCache(localStorage, 10 * 60 * 1000); // 10 min TTL
53
54async function getDinosaurData(id) {
55  return cache.getOrFetch(
56    `dino:${id}`,
57    () => fetch(`/api/dinosaurs/${id}`).then(r => r.json()),
58    5 * 60 * 1000  // 5 minutes
59  );
60}

Security Warnings

IMPORTANT — never store sensitive data in Web Storage:

  • Passwords or password hashes
  • Authentication tokens (use httpOnly cookies instead)
  • Credit card numbers
  • Personal data (GDPR/CCPA considerations)
  • Session tokens

Web Storage is accessible from any JavaScript on the page, making it vulnerable to XSS attacks.

Summary

Web Storage is a simple, convenient client-side storage mechanism:

  1. localStorage — persistent storage across browser sessions, shared between tabs
  2. sessionStorage — tab-scoped storage, cleared when tab closes
  3. JSON.stringify/parse — required for storing objects and arrays
  4. UserPreferences — a class pattern for managing user settings
  5. DataCache with TTL — cache API responses to avoid unnecessary network calls
  6. Security — never store sensitive data in Web Storage
Go to CodeWorlds