HTML5 Mastery: The Complete Web Foundation
HomeInsightsCoursesHTMLWeb Storage Basics
HTML5 APIs

Web Storage API (localStorage & sessionStorage)

Store data in the browser with Web Storage API. Learn localStorage for persistent storage and sessionStorage for temporary data in modern web applications.

What is Web Storage?

Web Storage provides two mechanisms for storing key-value pairs in the browser: localStorage (persistent) and sessionStorage (session-only).

localStorage

  • ✅ Persists forever (until manually cleared)
  • ✅ Shared across all tabs/windows
  • ✅ ~5-10MB storage per origin
  • ✅ Perfect for user preferences

sessionStorage

  • ⏱️ Cleared when tab closes
  • 📄 Separate for each tab
  • 📦 ~5-10MB storage per origin
  • ✅ Perfect for temporary data

vs Cookies

FeaturelocalStoragesessionStorageCookies
Capacity~10MB~10MB~4KB
LifetimeForeverTab sessionSet by expires
Sent to serverNoNoYes (every request)
AccessClient-side onlyClient-side onlyClient & server

localStorage Basics

Storing Data

JAVASCRIPT
// Store string
localStorage.setItem('username', 'JohnDoe');
localStorage.setItem('theme', 'dark');

// Alternative syntax
localStorage.username = 'JohnDoe';
localStorage['theme'] = 'dark';

// Store numbers (converted to strings)
localStorage.setItem('count', '42');

// Store objects (must stringify)
const user = { name: 'John', age: 30 };
localStorage.setItem('user', JSON.stringify(user));

Retrieving Data

JAVASCRIPT
// Get string
const username = localStorage.getItem('username');
console.log(username); // 'JohnDoe'

// Alternative syntax
const theme = localStorage.theme;
const theme2 = localStorage['theme'];

// Get number (parse)
const count = parseInt(localStorage.getItem('count'));

// Get object (parse JSON)
const userStr = localStorage.getItem('user');
const user = JSON.parse(userStr);
console.log(user.name); // 'John'

// Handle missing keys (returns null)
const missing = localStorage.getItem('nonexistent');
console.log(missing); // null

Removing Data

JAVASCRIPT
// Remove specific item
localStorage.removeItem('username');

// Clear all items
localStorage.clear();

// Check if item exists
if (localStorage.getItem('theme') !== null) {
    console.log('Theme is set');
}

Getting All Keys

JAVASCRIPT
// Get number of items
console.log(localStorage.length);

// Iterate through all keys
for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    const value = localStorage.getItem(key);
    console.log(key, '=', value);
}

// Or use Object.keys (simpler)
Object.keys(localStorage).forEach(key => {
    console.log(key, '=', localStorage.getItem(key));
});

sessionStorage Basics

sessionStorage has the exact same API as localStorage, but data only lasts for the tab session.

JAVASCRIPT
// Same API as localStorage
sessionStorage.setItem('tempData', 'value');
sessionStorage.getItem('tempData');
sessionStorage.removeItem('tempData');
sessionStorage.clear();

// Use case: form data persistence during session
function saveFormData() {
    const formData = {
        name: document.getElementById('name').value,
        email: document.getElementById('email').value
    };
    sessionStorage.setItem('formDraft', JSON.stringify(formData));
}

function restoreFormData() {
    const data = sessionStorage.getItem('formDraft');
    if (data) {
        const formData = JSON.parse(data);
        document.getElementById('name').value = formData.name;
        document.getElementById('email').value = formData.email;
    }
}

// Restore on page load
window.onload = restoreFormData;

Practical Examples

Example 1: Theme Persistence

HTML
<!DOCTYPE html>
<html>
<head>
    <title>Theme Persistence</title>
    <style>
        body.light { background: white; color: black; }
        body.dark { background: #1e1e1e; color: white; }
    </style>
</head>
<body>
    <button onclick="toggleTheme()">Toggle Theme</button>

    <script>
    // Load saved theme on page load
    window.onload = function() {
        const savedTheme = localStorage.getItem('theme') || 'light';
        document.body.className = savedTheme;
    };

    function toggleTheme() {
        const currentTheme = document.body.className;
        const newTheme = currentTheme === 'light' ? 'dark' : 'light';
        
        // Update UI
        document.body.className = newTheme;
        
        // Save to localStorage
        localStorage.setItem('theme', newTheme);
    }
    </script>
</body>
</html>

Example 2: Shopping Cart

JAVASCRIPT
// Cart manager using localStorage
const CartManager = {
    // Add item to cart
    addItem(product) {
        const cart = this.getCart();
        const existing = cart.find(item => item.id === product.id);
        
        if (existing) {
            existing.quantity++;
        } else {
            cart.push({ ...product, quantity: 1 });
        }
        
        this.saveCart(cart);
    },
    
    // Remove item from cart
    removeItem(productId) {
        let cart = this.getCart();
        cart = cart.filter(item => item.id !== productId);
        this.saveCart(cart);
    },
    
    // Update quantity
    updateQuantity(productId, quantity) {
        const cart = this.getCart();
        const item = cart.find(item => item.id === productId);
        
        if (item) {
            item.quantity = quantity;
            this.saveCart(cart);
        }
    },
    
    // Get cart
    getCart() {
        const cart = localStorage.getItem('cart');
        return cart ? JSON.parse(cart) : [];
    },
    
    // Save cart
    saveCart(cart) {
        localStorage.setItem('cart', JSON.stringify(cart));
    },
    
    // Get total
    getTotal() {
        const cart = this.getCart();
        return cart.reduce((sum, item) => 
            sum + (item.price * item.quantity), 0
        );
    },
    
    // Clear cart
    clearCart() {
        localStorage.removeItem('cart');
    }
};

// Usage
CartManager.addItem({ id: 1, name: 'Product A', price: 29.99 });
CartManager.addItem({ id: 2, name: 'Product B', price: 49.99 });
console.log('Cart:', CartManager.getCart());
console.log('Total:', CartManager.getTotal());

Example 3: Form Auto-Save

HTML
<!DOCTYPE html>
<html>
<head>
    <title>Form Auto-Save</title>
</head>
<body>
    <form id="myForm">
        <input type="text" id="name" placeholder="Name">
        <textarea id="message" placeholder="Message"></textarea>
        <button type="submit">Submit</button>
        <button type="button" onclick="clearDraft()">Clear Draft</button>
    </form>
    <p id="status"></p>

    <script>
    const form = document.getElementById('myForm');
    const status = document.getElementById('status');
    
    // Auto-save every 2 seconds
    let saveTimer;
    form.addEventListener('input', () => {
        clearTimeout(saveTimer);
        saveTimer = setTimeout(saveDraft, 2000);
    });
    
    function saveDraft() {
        const formData = {
            name: document.getElementById('name').value,
            message: document.getElementById('message').value,
            savedAt: new Date().toISOString()
        };
        
        localStorage.setItem('formDraft', JSON.stringify(formData));
        status.textContent = 'Draft saved at ' + new Date().toLocaleTimeString();
    }
    
    function loadDraft() {
        const draft = localStorage.getItem('formDraft');
        if (draft) {
            const data = JSON.parse(draft);
            document.getElementById('name').value = data.name || '';
            document.getElementById('message').value = data.message || '';
            
            const savedTime = new Date(data.savedAt).toLocaleTimeString();
            status.textContent = 'Draft loaded (saved at ' + savedTime + ')';
        }
    }
    
    function clearDraft() {
        localStorage.removeItem('formDraft');
        form.reset();
        status.textContent = 'Draft cleared';
    }
    
    // Load draft on page load
    window.onload = loadDraft;
    
    // Clear draft on successful submit
    form.onsubmit = (e) => {
        e.preventDefault();
        // Submit form data...
        clearDraft();
        status.textContent = 'Form submitted!';
    };
    </script>
</body>
</html>

Storage Events

The storage event fires when localStorage is modified in another tab/window, allowing you to sync data across tabs.

JAVASCRIPT
// Listen for storage changes from other tabs
window.addEventListener('storage', (e) => {
    console.log('Storage changed:');
    console.log('Key:', e.key);
    console.log('Old value:', e.oldValue);
    console.log('New value:', e.newValue);
    console.log('URL:', e.url);
    console.log('Storage area:', e.storageArea);
    
    // Example: sync theme across tabs
    if (e.key === 'theme') {
        document.body.className = e.newValue;
    }
});

// Note: storage event does NOT fire in the tab that made the change,
// only in other tabs on the same domain

Cross-Tab Sync Example

JAVASCRIPT
// Tab synchronization
window.addEventListener('storage', (e) => {
    if (e.key === 'cart') {
        // Cart updated in another tab, refresh display
        updateCartDisplay();
    }
    
    if (e.key === 'user') {
        if (e.newValue === null) {
            // User logged out in another tab
            redirectToLogin();
        } else {
            // User logged in in another tab
            updateUserDisplay(JSON.parse(e.newValue));
        }
    }
});

Security Considerations

⚠️ Important Security Notes:

  • ❌ Never store sensitive data (passwords, credit cards, tokens)
  • ❌ Data is NOT encrypted
  • ❌ Accessible to any script on your domain (XSS vulnerability)
  • ✅ Always validate/sanitize data before using
  • ✅ Consider encryption for sensitive non-critical data

Safe Practices

JAVASCRIPT
// ✅ Good: User preferences, settings
localStorage.setItem('language', 'en');
localStorage.setItem('fontSize', '16');

// ✅ Good: Non-sensitive cache data
localStorage.setItem('weatherCache', JSON.stringify(weatherData));

// ❌ Bad: Sensitive data
localStorage.setItem('password', 'secret123'); // NEVER!
localStorage.setItem('creditCard', '1234-5678-9012-3456'); // NEVER!
localStorage.setItem('authToken', 'xyz...'); // Use httpOnly cookies instead

Error Handling

JAVASCRIPT
// Storage might be full or disabled
function safeSetItem(key, value) {
    try {
        localStorage.setItem(key, value);
        return true;
    } catch (e) {
        if (e.name === 'QuotaExceededError') {
            console.error('Storage quota exceeded');
            // Clear old data or notify user
        } else if (e.name === 'SecurityError') {
            console.error('Storage access denied (private browsing?)');
        } else {
            console.error('Storage error:', e);
        }
        return false;
    }
}

// Check if storage is available
function storageAvailable(type) {
    try {
        const storage = window[type];
        const test = '__storage_test__';
        storage.setItem(test, test);
        storage.removeItem(test);
        return true;
    } catch (e) {
        return false;
    }
}

if (storageAvailable('localStorage')) {
    // localStorage is available
} else {
    // Fallback: use in-memory storage or cookies
}

Helper Functions

JAVASCRIPT
// Convenient storage wrapper
const Storage = {
    // Set with automatic JSON stringify
    set(key, value) {
        try {
            const serialized = JSON.stringify(value);
            localStorage.setItem(key, serialized);
            return true;
        } catch (e) {
            console.error('Storage set error:', e);
            return false;
        }
    },
    
    // Get with automatic JSON parse
    get(key, defaultValue = null) {
        try {
            const item = localStorage.getItem(key);
            return item ? JSON.parse(item) : defaultValue;
        } catch (e) {
            console.error('Storage get error:', e);
            return defaultValue;
        }
    },
    
    // Remove item
    remove(key) {
        localStorage.removeItem(key);
    },
    
    // Clear all
    clear() {
        localStorage.clear();
    },
    
    // Check if key exists
    has(key) {
        return localStorage.getItem(key) !== null;
    },
    
    // Get with expiration
    setWithExpiry(key, value, ttlMinutes) {
        const item = {
            value: value,
            expiry: Date.now() + (ttlMinutes * 60 * 1000)
        };
        this.set(key, item);
    },
    
    getWithExpiry(key) {
        const item = this.get(key);
        if (!item) return null;
        
        if (Date.now() &gt; item.expiry) {
            this.remove(key);
            return null;
        }
        
        return item.value;
    }
};

// Usage
Storage.set('user', { name: 'John', age: 30 });
const user = Storage.get('user');

Storage.setWithExpiry('cache', data, 60); // Expires in 60 minutes
const cache = Storage.getWithExpiry('cache');

Browser Support

Web Storage is supported in all modern browsers:

  • ✅ Chrome 4+
  • ✅ Firefox 3.5+
  • ✅ Safari 4+
  • ✅ Edge (all versions)
  • ✅ iOS Safari 3.2+
  • ✅ Android 2.1+

What's Next?

Learn about the Drag and Drop API for interactive user interfaces.