> ## Documentation Index
> Fetch the complete documentation index at: https://docs.extensy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage & State

> Persist and retrieve user data across your extension using chrome.storage.sync and chrome.storage.local.

Chrome extensions cannot use `localStorage` reliably across all extension contexts. Use the `chrome.storage` API instead — it works in content scripts, the background service worker, the popup, and the options page.

## Sync vs local storage

Choose the right storage area based on how the data should behave:

| | `chrome.storage.sync` | `chrome.storage.local` |
| - | - | - |
| Synced across devices | Yes (via Chrome account) | No |
| Storage limit | \~100 KB total, 8 KB per item | \~10 MB |
| Best for | User preferences, settings | Cached data, large payloads |
| Requires permission | `"storage"` | `"storage"` |

> [!TIP]
>
> Use `chrome.storage.sync` for small settings like theme preferences or toggle states. Use `chrome.storage.local` for larger data like cached API responses or collected page data.

## Write data

Call `chrome.storage.sync.set` or `chrome.storage.local.set` with an object of key-value pairs:

**sync**

```javascript theme={null}
chrome.storage.sync.set({ theme: "dark", notificationsEnabled: true }, () => {
  console.log("Settings saved.");
});
```

**local**

```javascript theme={null}
chrome.storage.local.set({ cachedResults: ["item1", "item2"] }, () => {
  console.log("Cache saved.");
});
```

## Read data

Pass an array of keys to retrieve:

**sync**

```javascript theme={null}
chrome.storage.sync.get(["theme", "notificationsEnabled"], (result) => {
  console.log("Theme:", result.theme);
  console.log("Notifications:", result.notificationsEnabled);
});
```

**local**

```javascript theme={null}
chrome.storage.local.get(["cachedResults"], ({ cachedResults }) => {
  if (cachedResults) {
    console.log("Cached items:", cachedResults);
  }
});
```

Pass `null` to read everything in storage:

```javascript theme={null}
chrome.storage.sync.get(null, (allItems) => {
  console.log("All stored data:", allItems);
});
```

## Remove and clear data

```javascript theme={null}
// Remove specific keys
chrome.storage.sync.remove(["theme"], () => {
  console.log("Theme setting removed.");
});

// Clear everything in local storage
chrome.storage.local.clear(() => {
  console.log("Local storage cleared.");
});
```

## React to storage changes

Listen for changes across all extension contexts using `chrome.storage.onChanged`. This is useful for keeping the popup and content scripts in sync without manual polling:

```javascript theme={null}
chrome.storage.onChanged.addListener((changes, areaName) => {
  for (const [key, { oldValue, newValue }] of Object.entries(changes)) {
    console.log(`[${areaName}] "${key}" changed from`, oldValue, "to", newValue);
  }
});
```

> [!TIP]
>
> Add this listener in your popup script to automatically refresh the UI when settings change — even if the change came from the options page.

## Full example: save and load user preferences

```javascript theme={null}
// options.js — save preferences when user submits the form
document.getElementById("save-btn").addEventListener("click", () => {
  const prefs = {
    theme: document.getElementById("theme-select").value,
    showBadge: document.getElementById("badge-toggle").checked,
  };

  chrome.storage.sync.set(prefs, () => {
    document.getElementById("status").textContent = "Saved!";
  });
});

// Load existing preferences when the options page opens
chrome.storage.sync.get(["theme", "showBadge"], ({ theme, showBadge }) => {
  if (theme) document.getElementById("theme-select").value = theme;
  if (showBadge !== undefined) document.getElementById("badge-toggle").checked = showBadge;
});
```

## Prompt Extensy to use storage

Include storage requirements in your extension prompt:

> "Remember the user's preferred language setting across sessions. Let them change it on the options page and apply it in the popup."

Extensy will generate `chrome.storage.sync.set` and `chrome.storage.sync.get` calls in the appropriate files. If you need large-scale caching, specify that explicitly:

> "Cache the last 50 search results in `chrome.storage.local` and clear them when the user clicks 'Reset cache'."

> [!NOTE]
>
> `chrome.storage` is asynchronous. Always read data inside the callback (or use `await` with the Promise-based API available in MV3) before acting on the result.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.