💾 localStorage = Offline Data Persistence
Users expect apps to work offline. localStorage provides client-side persistence for user preferences and app state.
📝 localStorage API
// Set Data
localStorage.setItem('key', 'value');
localStorage.setItem('user', JSON.stringify({ name: 'John', age: 30 }));
// Get Data
const value = localStorage.getItem('key');
const user = JSON.parse(localStorage.getItem('user'));
// Remove Data
localStorage.removeItem('key');
localStorage.clear(); // Remove all
// Check if exists
if (localStorage.getItem('key') !== null) {
// Key exists
}
// Storage Event Listener
window.addEventListener('storage', function(e) {
console.log('Storage changed:', e.key, e.oldValue, e.newValue);
});
// Session Storage (Session-specific)
sessionStorage.setItem('temp', 'value');
const temp = sessionStorage.getItem('temp');
// Storage Limits
console.log('Storage available:', navigator.storage.estimate());
🎯 Advanced localStorage Patterns
// Settings Manager
class SettingsManager {
constructor() {
this.defaults = {
theme: 'light',
language: 'en',
notifications: true
};
}
get(key) {
const value = localStorage.getItem(key);
return value !== null ? JSON.parse(value) : this.defaults[key];
}
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
this.notify(key, value);
}
notify(key, value) {
document.dispatchEvent(new CustomEvent('settings-changed', {
detail: { key, value }
}));
}
reset(key) {
localStorage.removeItem(key);
}
resetAll() {
localStorage.clear();
}
}
// Cache Manager
class CacheManager {
constructor(prefix = 'cache_') {
this.prefix = prefix;
this.ttl = 3600000; // 1 hour
}
set(key, data) {
const item = {
data: data,
timestamp: Date.now()
};
localStorage.setItem(this.prefix + key, JSON.stringify(item));
}
get(key) {
const raw = localStorage.getItem(this.prefix + key);
if (!raw) return null;
const item = JSON.parse(raw);
if (Date.now() - item.timestamp > this.ttl) {
localStorage.removeItem(this.prefix + key);
return null;
}
return item.data;
}
clear() {
for (const key of Object.keys(localStorage)) {
if (key.startsWith(this.prefix)) {
localStorage.removeItem(key);
}
}
}
}
// State Persistence
const state = {
counter: 0,
todos: []
};
function saveState() {
localStorage.setItem('appState', JSON.stringify(state));
}
function loadState() {
const saved = localStorage.getItem('appState');
if (saved) {
Object.assign(state, JSON.parse(saved));
}
}
// Autosave
setInterval(saveState, 5000);
// Save on page unload
window.addEventListener('beforeunload', saveState);
💡 localStorage Best Practices
- Store only serializable data
- Handle storage errors gracefully
- Use namespacing for keys
- Implement expiration for cached data
- Don’t store sensitive information
localStorage bridges the gap between web apps and native apps. Users love apps that remember their preferences.
