6c7064faf0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
ADR-004: Browser localStorage for User Settings
Status: Accepted Date: 2026-03-05 Deciders: Plugin maintainers
Context
The plugin has two user-configurable settings:
- Auto-refresh interval (1-30 minutes, default 5 minutes) - how often to re-fetch Polaris audit data
- Polaris dashboard URL - endpoint for the Polaris dashboard service (supports custom namespaces/service names and external instances)
These are per-user preferences, not cluster configuration. They should persist across browser sessions and page reloads.
Several storage mechanisms are available:
- Browser
localStorage- simple key-value store, persistent, synchronous API - Headlamp
ConfigStoreAPI - backed by Redux, reactive, integrated with Headlamp's state management - React state only - in-memory, lost on page reload
- URL query parameters - visible in URL, lost on navigation
Constraints:
- Settings need to be reactive: the
PolarisDataProvidermust detect changes made on the settings page - Headlamp provides
registerPluginSettingswhich renders a settings component - the settings page and the data provider are separate component trees - Only two scalar values need to be stored
Requirements:
- Persist settings across browser sessions and page reloads
- React to setting changes without requiring a full page reload
- Simple implementation for two scalar values
- Work with Headlamp's
registerPluginSettingsAPI
Decision
Use browser localStorage directly for persisting plugin settings.
Implementation:
- Refresh interval stored at key
polaris-plugin-refresh-interval(value in minutes as string) - Dashboard URL stored at key
polaris-plugin-dashboard-url(URL string or empty for default) PolarisSettingscomponent (registered viaregisterPluginSettings) reads/writes these keysPolarisDataProviderpollslocalStorageviasetIntervalevery 1 second to detect setting changes- Helper functions in
polaris.ts(getRefreshInterval(),getPolarisApiPath()) encapsulate localStorage access
Consequences
Positive
- ✅ Simple and well-understood API -
localStorage.getItem/setItemis straightforward - ✅ Persists across browser sessions - Data survives page reloads, tab closes, browser restarts
- ✅ No dependency on Headlamp store internals - Decoupled from Headlamp's Redux implementation
- ✅ Works with
registerPluginSettings- Settings page and data provider communicate via shared localStorage keys - ✅ Minimal code - No state management boilerplate for two simple values
Negative
- ❌ Not reactive by default - localStorage has no built-in change notification within the same tab
- Mitigated by: 1-second polling interval in
PolarisDataProviderto detect changes
- Mitigated by: 1-second polling interval in
- ❌ Settings are browser-local - Not synced across devices or browsers
- Mitigated by: These are user preferences, browser-local storage is appropriate
- ❌ No type safety on stored values - All values stored as strings
- Mitigated by: Helper functions with
parseIntand default values handle type conversion
- Mitigated by: Helper functions with
Neutral
- localStorage has a 5-10 MB limit per origin, more than sufficient for two string values
- The 1-second polling interval has negligible performance impact (reading two string keys)
- The
storageevent could detect cross-tab changes but does not fire for same-tab writes
Alternatives Considered
Option 1: Headlamp ConfigStore API
Pros:
- Integrated with Headlamp's Redux store
- Reactive (Redux state changes trigger re-renders)
- Type-safe with TypeScript
Cons:
- Couples plugin to Headlamp's internal Redux store implementation
- More complex API for two scalar values
- ConfigStore API may change across Headlamp versions
Decision: Not chosen (localStorage is simpler for two scalar values, avoids coupling to Headlamp's Redux internals)
Option 2: React State Only (No Persistence)
Pros:
- Simplest implementation
- Fully reactive
- No side effects
Cons:
- Settings lost on page reload - users must reconfigure every session
- Poor user experience for frequently changed settings
Decision: Rejected (settings must persist across page reloads)
Option 3: URL Query Parameters
Pros:
- Shareable via URL
- No storage API needed
Cons:
- Lost on navigation to different routes
- Clutters the URL
- Not suitable for persistent settings
Decision: Rejected (does not persist across navigation)
References
Revision History
| Date | Author | Change |
|---|---|---|
| 2026-03-05 | Plugin Team | Initial decision |