Skip to main content

Settings Sync Across Devices

LightningAddon uses chrome.storage.sync for user preferences so they automatically sync across all of a user's signed-in Chrome instances. No backend or account required.

How It Works

The useSettings hook in @repo/ui reads from and writes to chrome.storage.sync instead of chrome.storage.local. Chrome handles synchronization—writes are queued and synced when the user is online.

Using useSettings

import { useSettings } from '@repo/ui';

function MyComponent() {
const [darkMode, setDarkMode] = useSettings('settings.darkMode', false);
const [notificationsEnabled, setNotifications] = useSettings(
'settings.notificationsEnabled',
true,
);

return (
<div>
<label>
<input
type="checkbox"
checked={darkMode}
onChange={(e) => setDarkMode(e.target.checked)}
/>
Dark Mode
</label>
{/* ... */}
</div>
);
}

The hook returns [value, setValue, loaded]:

  • value — Current value (or defaultValue until loaded)
  • setValue — Function to update; persists to chrome.storage.sync immediately
  • loadedtrue once the value has been read from storage (useful for avoiding flash of default)

SettingsForm Component

SettingsForm from @repo/ui provides a ready-made settings UI with dark mode and notifications toggles. Use it as-is or copy its pattern for custom settings.

Adding New Settings

  1. Add a new key and default value to your component:

    const [mySetting, setMySetting] = useSettings('settings.mySetting', defaultValue);
  2. Use a consistent key prefix (e.g. settings.) to keep storage organized.

  3. Values are JSON-serialized. Supported types: string, number, boolean, plain objects, arrays.

Storage Quota

chrome.storage.sync has limits:

  • 100 KB total per extension
  • 8 KB per item
  • 512 items max

For larger data (e.g. cached content), use chrome.storage.local via getStorageValue / setStorageValue from @repo/browser-utils.

Offline Behavior

Writes to sync storage are queued when offline and applied when the user reconnects. Reads return the last known local value. The extension does not need to handle offline logic—Chrome manages it.