localStorage, c'est cette petite boîte de rangement que le navigateur offre à chaque site web pour mémoriser des informations d'une visite à l'autre. C'est simple à utiliser, ça marche en trois lignes de code, et c'est précisément ce qui en fait un piège. La facilité pousse à y mettre des choses qui n'ont rien à y faire. Dans mes applications, il ne sert qu'à retenir des préférences d'affichage sans conséquence, jamais rien de plus. Voici pourquoi.
Ce que localStorage est vraiment
Trois propriétés à garder en tête :
- Ce n'est pas chiffré.
localStoragestocke du texte en clair sur le poste de l'utilisateur, et n'importe quel script qui tourne sur la page peut le lire. - C'est attaché à un seul navigateur. Changez d'appareil, de navigateur, ou videz le cache, et tout disparaît.
- Ça n'existe que côté client. Le serveur ne voit jamais ces données, sauf si le code les lui renvoie explicitement.
Ces trois propriétés ne sont pas des défauts. Ce sont des caractéristiques parfaitement adaptées à un seul usage : retenir un choix d'affichage sans importance, comme le mode sombre ou la dernière colonne de tri d'un tableau. Le problème commence quand on s'en sert pour autre chose.
Le piège de la fuite de données personnelles
Le scénario le plus courant : pour aller vite, on stocke dans localStorage le profil de l'utilisateur connecté, ses informations de session, parfois le contenu d'un formulaire en cours. C'est pratique, ça évite un aller-retour au serveur.
Sauf que ces données restent sur la machine, en clair, sans date d'expiration. Sur un poste partagé (accueil, poste de production, ordinateur familial), l'utilisateur suivant peut les retrouver. Et surtout, tout script chargé sur la page peut les lire : une bibliothèque tierce compromise, une balise marketing trop curieuse, une faille d'injection, et les données personnelles partent ailleurs sans que personne ne s'en aperçoive. Du point de vue du RGPD, c'est une fuite silencieuse, et c'est exactement le genre de risque qu'un audit met en lumière. La règle est simple : une donnée personnelle ne se stocke pas en clair sur le poste client. Une session se gère côté serveur, avec un cookie correctement protégé.
Le piège de l'accessibilité et du rendu serveur
Deuxième problème, plus discret mais structurant. Beaucoup d'applications modernes affichent leurs pages en deux temps : le serveur envoie une première version complète et lisible immédiatement, puis le navigateur prend le relais. C'est ce qui rend un site rapide à l'affichage et correctement lu par les moteurs de recherche.
Or localStorage n'existe pas au moment où le serveur prépare la page. Le serveur ne sait rien du contenu rangé dans le navigateur de l'utilisateur. Si l'application dépend de cette boîte pour décider quoi afficher (la langue, l'état de connexion, le contenu personnalisé), le serveur produit une page incohérente, puis le navigateur la corrige brutalement une fois chargé. Résultat : un clignotement désagréable, du contenu qui saute, et une page que les moteurs de recherche indexent mal.
Par ailleurs, il y a un angle d'accessibilité, souvent oublié. Une personne qui navigue au lecteur d'écran ou au clavier subit ces sauts de contenu de plein fouet : le focus se perd, la lecture reprend au mauvais endroit. Ce qui n'est qu'un clignotement pour un utilisateur voyant devient un obstacle réel pour quelqu'un d'autre.
Ce que je fais à la place
Rien de sophistiqué, juste la bonne boîte pour le bon objet :
- L'identité et la session se gèrent côté serveur, avec un cookie protégé (inaccessible au JavaScript, transmis uniquement en HTTPS). C'est le navigateur qui le porte, mais aucun script ne peut le lire.
- Les données métier vivent dans la base de données, derrière une interface sécurisée. Elles sont ainsi sauvegardées, partagées entre les appareils de l'utilisateur, et soumises à des règles de conservation claires.
- Les vraies préférences d'affichage sans enjeu (mode sombre, densité d'un tableau) peuvent rester dans le navigateur. Si elles disparaissent, l'utilisateur ne perd rien d'important.
La question que je me pose à chaque fois est la même : « si cette donnée disparaît parce que l'utilisateur a changé de navigateur, est-ce grave ? » Si oui, elle n'a rien à faire dans localStorage. Si la réponse est « on s'en moque », alors c'est le bon endroit.
Pourquoi ça compte pour vous
Ce genre de choix ne se voit pas sur une démo. Une application qui stocke tout dans le navigateur fonctionne parfaitement le temps d'une présentation : un seul utilisateur, un seul poste, une seule session. Les problèmes (fuite de données, perte d'informations au changement d'appareil, mauvais référencement, accessibilité dégradée) apparaissent en usage réel, avec de vrais utilisateurs sur de vrais postes.
C'est la différence entre du code qui impressionne en réunion et du code qui tient dans la durée. Quand j'audite une application existante, localStorage utilisé à mauvais escient fait partie des signaux que je cherche en premier : c'est souvent le symptôme d'un développement pressé qui a privilégié la démo sur la solidité. Si vous vous demandez ce que cache votre propre application, c'est typiquement ce qu'un audit révèle.
