Skip to content

localStorage and JSON

Every variable in JavaScript disappears when the page reloads. localStorage is a browser API that persists data between sessions — it survives page reloads, tab closes, and browser restarts.

// Save a value
localStorage.setItem('key', 'value');
// Read it back
const value = localStorage.getItem('key'); // 'value'
// Remove it
localStorage.removeItem('key');

localStorage is available everywhere on the same origin — any page under https://example.com can read what any other page under that origin stored.

This is the critical limitation. Everything stored becomes a string:

localStorage.setItem('count', 42);
const count = localStorage.getItem('count');
console.log(count); // '42' — a string, not a number
console.log(typeof count); // 'string'

For numbers, convert back explicitly. For objects and arrays, the problem is worse:

const tour = { name: 'Cascade Ridge', price: 149 };
localStorage.setItem('tour', tour);
localStorage.getItem('tour'); // '[object Object]' — useless

JSON converts JavaScript values to strings and back:

const tour = { name: 'Cascade Ridge', price: 149, available: true };
// Store: convert object → JSON string
localStorage.setItem('tour', JSON.stringify(tour));
// Read: convert JSON string → object
const saved = localStorage.getItem('tour');
const parsedTour = JSON.parse(saved);
console.log(parsedTour.name); // 'Cascade Ridge'
console.log(parsedTour.price); // 149 (a number again)

JSON.stringify works on arrays too:

const favorites = ['cr-01', 'sl-02'];
localStorage.setItem('favorites', JSON.stringify(favorites));
const savedFavorites = JSON.parse(localStorage.getItem('favorites'));
console.log(savedFavorites); // ['cr-01', 'sl-02']

getItem returns null if the key does not exist. Always handle this:

const saved = localStorage.getItem('activeCategory');
const activeCategory = saved ? saved : 'all';

For objects and arrays, use a default value in the null case:

const saved = localStorage.getItem('favorites');
const favorites = saved ? JSON.parse(saved) : [];

Without this guard, calling JSON.parse(null) returns null — which will cause errors when you try to iterate it or access properties.

STO: persist the active tour category filter

Section titled “STO: persist the active tour category filter”

Save and restore the active category across page reloads:

const CATEGORY_KEY = 'sto-active-category';
// Read the saved category when the page loads (default to 'all')
const saved = localStorage.getItem(CATEGORY_KEY);
let activeCategory = saved ? saved : 'all';
function setActiveCategory(category) {
activeCategory = category;
localStorage.setItem(CATEGORY_KEY, category);
console.log('Active category saved:', category);
}

Call setActiveCategory('hiking') when a filter button is clicked. The next time the page loads, activeCategory will be 'hiking' instead of 'all'. In Module 07 you will wire this to the visible tour list.

To verify in the Console:

localStorage.setItem('sto-active-category', 'hiking');
// Reload the page
localStorage.getItem('sto-active-category'); // 'hiking' — persisted
localStorage.removeItem('sto-active-category');
localStorage.getItem('sto-active-category'); // null
  • It is not a database — no queries, no indexing, ~5MB limit per origin
  • It is not secure — never store passwords, tokens, or sensitive data
  • It is not shared — only readable by the same origin

For complex persistent data, IndexedDB exists — but localStorage is the right tool for simple UI state like the active filter or a favorites list.

  • localStorage.setItem(key, value), getItem(key), and removeItem(key) — the three core methods.
  • Everything in localStorage is a string. Numbers, objects, and arrays must be serialized.
  • JSON.stringify(value) converts a value to a JSON string for storage. JSON.parse(string) converts it back.
  • Safe read pattern: const data = saved ? JSON.parse(saved) : defaultValue; — always handle the null case.
  • In Module 07 you will use localStorage to power the STO tour favorites list — saving and restoring which tours a user has marked across page reloads.