Persisting State
Save your flag store to localStorage (or any storage backend) so state survives page reloads and browser sessions.
Prerequisites
Before starting, you should:
Overview
We'll persist state by:
- Configuring the store with a
persistoption - Understanding auto-save behavior
- Using a custom storage key
- Handling storage errors
Step 1: Enable Persistence
Pass a persist option with your storage backend:
import { createFlagStore } from '@motioneffector/flags'
const store = createFlagStore({
initial: { gold: 0, level: 1 },
persist: {
storage: localStorage
}
})
The store now automatically saves to localStorage after every change and loads existing data on creation.
Step 2: Understand Auto-Save
By default, every change triggers a save:
store.set('gold', 100) // Saved automatically
store.increment('level') // Saved automatically
store.toggle('has_sword') // Saved automatically
Disable auto-save if you want manual control:
const store = createFlagStore({
persist: {
storage: localStorage,
autoSave: false
}
})
store.set('gold', 100) // NOT saved
store.set('level', 5) // NOT saved
store.save() // NOW saved
Step 3: Use a Custom Storage Key
The default key is @motioneffector/flags. Use a custom key to avoid conflicts:
const store = createFlagStore({
persist: {
storage: localStorage,
key: 'my-game-save'
}
})
Multiple stores can coexist with different keys:
const gameStore = createFlagStore({
persist: { storage: localStorage, key: 'game-state' }
})
const settingsStore = createFlagStore({
persist: { storage: localStorage, key: 'user-settings' }
})
Step 4: Handle Initial Values vs Persisted State
When both initial and persist are provided, persisted data wins:
// First run (nothing in localStorage)
const store = createFlagStore({
initial: { gold: 0 },
persist: { storage: localStorage }
})
store.get('gold') // 0 (from initial)
store.set('gold', 500) // Saved to localStorage
// Later / page reload
const store2 = createFlagStore({
initial: { gold: 0 }, // Ignored
persist: { storage: localStorage }
})
store2.get('gold') // 500 (from localStorage)
Use initial as defaults for first-time users. Persisted data overrides them.
Complete Example
import { createFlagStore } from '@motioneffector/flags'
const store = createFlagStore({
initial: {
gold: 0,
level: 1,
has_sword: false,
player_name: 'Hero'
},
persist: {
storage: localStorage,
key: 'my-rpg-save'
}
})
// All changes are automatically saved
store.set('player_name', 'Ada')
store.increment('gold', 100)
store.set('has_sword', true)
// On page reload, state is restored automatically
Variations
Using sessionStorage
For state that should clear when the browser closes:
const store = createFlagStore({
persist: { storage: sessionStorage }
})
Custom Storage Backend
Implement the Storage interface for custom backends:
const customStorage = {
getItem(key: string): string | null {
// Read from your backend
return myDatabase.get(key)
},
setItem(key: string, value: string): void {
// Write to your backend
myDatabase.set(key, value)
},
removeItem(key: string): void {
// Delete from your backend
myDatabase.delete(key)
}
}
const store = createFlagStore({
persist: { storage: customStorage }
})
Manual Save/Load
With autoSave: false, use explicit save/load:
const store = createFlagStore({
persist: { storage: localStorage, autoSave: false }
})
// Make many changes
store.set('a', 1)
store.set('b', 2)
store.set('c', 3)
// Save once at the end
store.save()
// Later, reload from storage
store.load()
Troubleshooting
State Not Persisting
Symptom: Changes are lost on page reload.
Cause: Storage might be unavailable (private browsing) or full.
Solution: The store logs errors to console but doesn't throw. Check for console.error messages about failed persistence.
Conflicting Data
Symptom: Multiple apps/tabs overwrite each other's data.
Cause: Using the same storage key.
Solution: Use unique keys per store: persist: { key: 'my-app-flags' }.
Corrupted Data
Symptom: Store doesn't load or has wrong values.
Cause: Manual edits to localStorage or incompatible data format.
Solution: The store handles corrupted JSON gracefully (logs error, starts fresh). Clear localStorage manually if needed.
See Also
- Flag Store - How values are stored
- API: Persistence -
save()andload()reference