Files
gemini-nexus/.agent/skills/vercel-react-best-practices/rules/client-localstorage-schema.md
T
AngeloooooandDraculabo 8ed4593f73 Refactor Gemini model display: filter old versions, group low/high pкo, and improve naming (#114)
* Refactor Gemini model display: filter old versions, group low/high pro, and improve naming

* Fix potential negative minutes and refine Gemini 3 Pro grouping logic based on PR feedback

* The account change process has been sped up

* Address PR review: enhance error message and parameterize polling interval in process handler

* Address PR review: fix potential race condition in database backup logic

* fix: prevent renderer white screen and harden sentry gating

* feat:  localize model labels

* chore: enable hoisted node-linker

* chore: ignore .agent/.claude/.codex in prettier

---------

Co-authored-by: Draculabo <[email protected]>
2026-02-19 19:37:30 +08:00

1.9 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Version and Minimize localStorage Data MEDIUM prevents schema conflicts, reduces storage size client, localStorage, storage, versioning, data-minimization

Version and Minimize localStorage Data

Add version prefix to keys and store only needed fields. Prevents schema conflicts and accidental storage of sensitive data.

Incorrect:

// No version, stores everything, no error handling
localStorage.setItem('userConfig', JSON.stringify(fullUserObject));
const data = localStorage.getItem('userConfig');

Correct:

const VERSION = 'v2';

function saveConfig(config: { theme: string; language: string }) {
  try {
    localStorage.setItem(`userConfig:${VERSION}`, JSON.stringify(config));
  } catch {
    // Throws in incognito/private browsing, quota exceeded, or disabled
  }
}

function loadConfig() {
  try {
    const data = localStorage.getItem(`userConfig:${VERSION}`);
    return data ? JSON.parse(data) : null;
  } catch {
    return null;
  }
}

// Migration from v1 to v2
function migrate() {
  try {
    const v1 = localStorage.getItem('userConfig:v1');
    if (v1) {
      const old = JSON.parse(v1);
      saveConfig({ theme: old.darkMode ? 'dark' : 'light', language: old.lang });
      localStorage.removeItem('userConfig:v1');
    }
  } catch {}
}

Store minimal fields from server responses:

// User object has 20+ fields, only store what UI needs
function cachePrefs(user: FullUser) {
  try {
    localStorage.setItem(
      'prefs:v1',
      JSON.stringify({
        theme: user.preferences.theme,
        notifications: user.preferences.notifications,
      }),
    );
  } catch {}
}

Always wrap in try-catch: getItem() and setItem() throw in incognito/private browsing (Safari, Firefox), when quota exceeded, or when disabled.

Benefits: Schema evolution via versioning, reduced storage size, prevents storing tokens/PII/internal flags.