localStorage : introduction et API
localStorage est un petit stockage clé-valeur intégré au navigateur : les données y restent après la fermeture de l’onglet et du navigateur, et ne sont jamais envoyées au serveur automatiquement. Cette rubrique appartient au front : le code s’exécute dans le navigateur. Les exemples utilisent des noms génériques.
Caractéristiques
Section intitulée « Caractéristiques »| Propriété | Valeur |
|---|---|
| Type de données | Chaînes de caractères uniquement |
| Durée de vie | Illimitée (jusqu’à suppression par le code ou par l’utilisateur) |
| Portée | Une origine (schéma + domaine + port) : https://exemple.com et https://autre.exemple.com ont des stockages séparés |
| Partage | Tous les onglets et fenêtres de la même origine |
| Taille | Environ 5 Mo par origine (variable selon le navigateur) |
| Fonctionnement | Synchrone : bloque le thread principal pendant l’accès |
| Envoi au serveur | Jamais automatique (contrairement aux cookies) |
localStorage.setItem('theme', 'dark'); // écrirelocalStorage.getItem('theme'); // lire : 'dark', ou null si absentlocalStorage.removeItem('theme'); // supprimer une clélocalStorage.clear(); // tout supprimer pour cette originelocalStorage.length; // nombre de cléslocalStorage.key(0); // nom de la première clé| Méthode | Rôle |
|---|---|
setItem(clé, valeur) |
Écrit (la valeur est convertie en chaîne) |
getItem(clé) |
Lit ; renvoie null si la clé n’existe pas |
removeItem(clé) |
Supprime une clé |
clear() |
Supprime toutes les clés de l’origine |
key(index) |
Nom de la clé à une position |
length |
Nombre de clés |
La notation par propriété (localStorage.theme = 'dark') fonctionne aussi, mais setItem et getItem sont préférables : ils évitent les collisions avec les méthodes de l’objet (length, key…).
Lire toutes les clés
Section intitulée « Lire toutes les clés »for (let i = 0; i < localStorage.length; i++) { const cle = localStorage.key(i); console.log(cle, localStorage.getItem(cle));}
Object.keys(localStorage); // tableau des clésObject.entries(localStorage); // tableau de [clé, valeur]Une valeur par défaut
Section intitulée « Une valeur par défaut »const langue = localStorage.getItem('langue') ?? 'fr';const compteur = Number(localStorage.getItem('compteur') ?? 0) + 1;localStorage.setItem('compteur', String(compteur));getItem renvoie null (et non undefined) si la clé est absente : utiliser ??. Une valeur numérique ou booléenne revient sous forme de chaîne : localStorage.setItem('actif', true) stocke "true", qui est truthy comme "false" ; convertir explicitement (voir JSON et structure des données).
Toujours protéger les accès
Section intitulée « Toujours protéger les accès »L’accès peut échouer : stockage désactivé, navigation privée de certains navigateurs, quota dépassé, politique de confidentialité stricte. Entourer les accès :
export function lire(cle, defaut = null) { try { const valeur = localStorage.getItem(cle); return valeur === null ? defaut : valeur; } catch { return defaut; }}
export function ecrire(cle, valeur) { try { localStorage.setItem(cle, valeur); return true; } catch { return false; // quota dépassé ou stockage indisponible }}Une application doit fonctionner sans stockage : le stockage améliore l’expérience, il ne doit pas la conditionner.
Exemple : mémoriser le thème
Section intitulée « Exemple : mémoriser le thème »<button id="theme">Changer de thème</button>
<script> const racine = document.documentElement; const systeme = matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; let theme; try { theme = localStorage.getItem('theme'); } catch {} racine.dataset.theme = theme ?? systeme;
document.getElementById('theme').addEventListener('click', () => { const suivant = racine.dataset.theme === 'dark' ? 'light' : 'dark'; racine.dataset.theme = suivant; try { localStorage.setItem('theme', suivant); } catch {} });</script>Le choix de l’utilisateur est prioritaire ; sans choix mémorisé, la préférence du système s’applique. Pour éviter un flash du mauvais thème, exécuter la première partie dans un script placé dans le <head>, avant l’affichage.
Inspecter dans le navigateur
Section intitulée « Inspecter dans le navigateur »Outils de développement (F12) : onglet Stockage (Firefox) ou Application (Chrome, Edge) > Stockage local > l’origine de la page. On peut y lire, modifier et supprimer les clés. En console :
localStorage;JSON.stringify(localStorage, null, 2);Quand utiliser localStorage
Section intitulée « Quand utiliser localStorage »| Bon usage | Mauvais usage |
|---|---|
| Préférences (thème, langue, mise en page) | Secrets, jetons d’authentification, données personnelles sensibles |
| Brouillon de formulaire | Gros volumes de données (utiliser IndexedDB) |
| Petit cache non critique | Données qui doivent être cohérentes entre appareils (utiliser le serveur) |
| État d’interface (panneau replié) | Données indispensables au fonctionnement |
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
localStorage is not defined |
Code exécuté hors du navigateur (rendu serveur, Node.js) : voir Avec Astro, React et Next.js |
SecurityError |
Accès interdit (cookies et données de sites bloqués, document sans origine) |
QuotaExceededError |
Stockage plein : supprimer des clés ou passer à IndexedDB |
getItem renvoie null |
Clé absente, autre origine (domaine, schéma ou port différents) |
| Les données disparaissent | Nettoyage par l’utilisateur, navigation privée, mode « effacer à la fermeture » |
| Valeur booléenne toujours « vraie » | Les valeurs sont des chaînes : comparer à 'true' ou utiliser JSON |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune : localStorage est une fonction du navigateur. Pour le tester sous Ubuntu, Firefox (installé par défaut en paquet snap) et Chromium offrent les mêmes outils de développement.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Documentation : MDN, Web Storage API
- Suite : JSON et structure des données