Browser Storage Guide

Storage Options Comparison

StorageCapacityPersistenceAccessible FromBest For
localStorage5–10 MBUntil clearedSame origin, JS onlyUser preferences, non-sensitive settings
sessionStorage5–10 MBTab sessionSame origin, JS onlyTemporary state, wizard steps
IndexedDB50–100+ MBUntil clearedSame origin, JS + WorkersOffline data, structured data, blobs
Cookies4 KBConfigurableHTTP + JS (if not httpOnly)Auth tokens, session IDs, server-readable data
Cache APIQuota-basedUntil clearedJS + Service WorkersNetwork request caching (PWA)

localStorage

// Set localStorage.setItem('theme', 'dark'); localStorage.setItem('user', JSON.stringify({ name: 'Alice', id: 42 })); // Get const theme = localStorage.getItem('theme'); // "dark" const user = JSON.parse(localStorage.getItem('user')); // Remove localStorage.removeItem('theme'); // Clear all localStorage.clear(); // Check size used const used = new Blob(Object.values(localStorage)).size; // Listen for changes (other tabs) window.addEventListener('storage', (e) => { console.log('Key changed:', e.key, e.oldValue, e.newValue); });

IndexedDB (with idb library)

import { openDB } from 'idb'; // Open / create database const db = await openDB('my-app', 1, { upgrade(db) { const store = db.createObjectStore('products', { keyPath: 'id' }); store.createIndex('category', 'category', { unique: false }); } }); // Add record await db.add('products', { id: 1, name: 'Widget', category: 'tools', price: 9.99 }); // Get record const product = await db.get('products', 1); // Get all by index const toolProducts = await db.getAllFromIndex('products', 'category', 'tools'); // Update await db.put('products', { id: 1, name: 'Widget Pro', category: 'tools', price: 19.99 }); // Delete await db.delete('products', 1);

Secure Cookie Attributes

// Server-set cookie (Go/Gin) c.SetCookie( "session_id", // name sessionToken, // value 3600*24, // maxAge (seconds) "/", // path ".example.com", // domain true, // secure (HTTPS only) true, // httpOnly (no JS access) ) // Cookie string Set-Cookie: session_id=abc123; Max-Age=86400; Path=/; Domain=.example.com; Secure; HttpOnly; SameSite=Strict // SameSite options: // Strict — only same-site requests // Lax — allows top-level GET (default) // None — cross-site (requires Secure)