Local Storage Adapter
Browser localStorage adapter for client-side analytics storage ✅ Production Ready
The Local Storage adapter stores analytics data in the browser's localStorage. Perfect for client-side analytics, testing, or offline scenarios.
Status: ✅ Production Ready
Fully implemented with all query methods and automatic data parsing.
Usage
Basic Setup
import { LocalAdapter } from 'honolytics/storage'
const adapter = new LocalAdapter()
await adapter.connect()
// Insert analytics data
await adapter.insertEvent({
id: 'evt_123',
timestamp: Date.now(),
sessionId: 'session_abc',
url: '/dashboard',
event: 'pageview',
userAgent: navigator.userAgent,
duration: 45
})
// Query analytics
const metrics = await adapter.queryFullMetrics(
new Date('2024-01-01'),
new Date('2024-01-31')
)With Storage Factory
import { initStorage, local } from 'honolytics/storage'
await initStorage(local())
// Now use with React hooks in storage mode
<HonolyticsProvider storageMode={true}>
<App />
</HonolyticsProvider>API Reference
Constructor
new LocalAdapter()No configuration required. The adapter uses fixed localStorage keys:
honolytics:events— Event storagehonolytics:sessions— Session storage
Connection Management
async connect(): Promise<void>Validates browser environment. Throws error if window is undefined (SSR).
async disconnect(): Promise<void>No-op for localStorage (no persistent connections).
Data Insertion
async insertEvent(event: TEvent): Promise<void>Appends event to localStorage array. No deduplication - events with duplicate IDs will be stored multiple times.
async insertSession(session: TSession): Promise<void>Upserts session by ID. Updates existing sessions or creates new ones.
Query Methods
Time Series Metrics
async queryMetrics(start: Date, end: Date): Promise<TMetric[]>Returns daily aggregated metrics (users, sessions, pageviews) grouped by date.
Event Filtering
async queryEvents(filters: TEventFilter): Promise<TEvent[]>Filter events by date range, user ID, session ID, or event type:
// Get all pageviews for a user
const events = await adapter.queryEvents({
start: new Date('2024-01-01'),
end: new Date('2024-01-31'),
userId: 'user_123',
event: 'pageview'
})Breakdown Queries
async queryTopPages(start: Date, end: Date, limit = 10): Promise<TPageStat[]>Returns top pages by views with average duration. Only includes 'pageview' events.
async queryCountries(start: Date, end: Date, limit = 10): Promise<TCountryStat[]>Groups users by country using IP parsing. Note: Returns 'Unknown' since geo-IP lookup is not implemented.
async queryBrowsers(start: Date, end: Date, limit = 10): Promise<TBrowserStat[]>Parses user agents and groups users by browser (Chrome, Firefox, Safari, etc.).
async queryDevices(start: Date, end: Date, limit = 10): Promise<TDeviceStat[]>Groups users by device type (Desktop, Mobile, Tablet).
Aggregate Queries
async queryTotals(start: Date, end: Date): Promise<TTotals>Returns summary statistics: total users, sessions, pageviews, and average session duration.
async queryFullMetrics(start: Date, end: Date): Promise<TFullMetrics>Executes all query methods in parallel and returns complete analytics data structure.
Data Processing
Automatic Parsing
The adapter automatically processes raw event data:
- User Agent Parsing: Extracts browser, version, device type, and OS
- Date Grouping: Groups events by ISO date strings (
YYYY-MM-DD) - Duration Calculations: Computes average session and page durations
- Deduplication: Removes duplicate users/sessions in metrics
Example Data Flow
// Raw event storage
{
"id": "evt_123",
"timestamp": 1704067200000,
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"sessionId": "session_abc",
"event": "pageview",
"url": "/dashboard",
"duration": 45
}
// Processed metrics output
{
"totals": {
"users": 1,
"sessions": 1,
"pageviews": 1,
"avgDuration": 45
},
"breakdowns": {
"browsers": [{ "browser": "Chrome", "users": 1 }],
"devices": [{ "device": "Desktop", "users": 1 }],
"topPages": [{ "url": "/dashboard", "views": 1, "avgDuration": 45 }]
}
}Performance Considerations
Storage Limits
- localStorage Limit: ~5-10MB per origin (browser dependent)
- Memory Usage: All data loaded into memory for queries
- Query Performance: O(n) linear scan for most operations
Best Practices
// ✅ Good: Clear old data periodically
const oneMonthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
const events = adapter.getEvents().filter(e => e.timestamp > oneMonthAgo.getTime())
localStorage.setItem('honolytics:events', JSON.stringify(events))
// ✅ Good: Use date range queries to limit data processing
const recentMetrics = await adapter.queryMetrics(
new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days
new Date()
)
// ❌ Avoid: Storing large amounts of event data
// Consider using IndexedDB adapter for larger datasetsBrowser Compatibility
- Modern Browsers: Full support (Chrome, Firefox, Safari, Edge)
- localStorage Required: Fails gracefully if localStorage is disabled
- SSR Safe: Throws clear error when used server-side
Data Persistence
- Persistent: Data survives browser restarts
- Origin Scoped: Isolated per domain/subdomain
- User Controllable: Users can clear via browser settings
- Incognito: Available but cleared when session ends
Migration Notes
When upgrading from HTTP mode to Local Storage:
- Data Import: No automatic import from existing backends
- Schema Compatibility: Uses same event/session structure as other adapters
- Query Compatibility: Identical API ensures hooks work unchanged
Limitations
- No Geo-IP: Country queries return 'Unknown'
- Client-Side Only: Cannot be used in Node.js/server environments
- Storage Limits: Browser localStorage size restrictions
- No Real-Time: Data only available to current browser tab
Use Cases
Perfect for:
- Client-side Analytics: Track user behavior without server dependency
- Offline Applications: Analytics that work without internet connection
- Development: Testing analytics integration during development
- Privacy-First: No data leaves the user's browser
Not suitable for:
- Cross-Device Analytics: Data is browser-specific
- Large-Scale Analytics: Storage and performance limitations
- Server-Side Tracking: Requires browser environment