Analytics Overview
Track user behavior and events with a provider-agnostic analytics system. Supports multiple providers, page views, events, and user identification.
The @kit/analytics package provides a unified analytics abstraction that dispatches events to one or more analytics providers simultaneously. You're not locked into any specific service, and can add Google Analytics, Mixpanel, PostHog, or any custom provider with minimal code.
Features
- Provider-agnostic - Switch or combine analytics services without changing application code
- Multi-provider dispatch - Send events to multiple services at once
- Page view tracking - Automatic tracking on route changes
- User identification - Associate events with authenticated users
- Event tracking - Custom events with typed properties
- Server-side support - Track events from API routes and server actions
- App Events integration - React to application-wide events automatically
Quick Start
Track a Custom Event
import { analytics } from '@kit/analytics';void analytics.trackEvent('button_clicked', { buttonName: 'signup', location: 'header',});Identify a User
import { analytics } from '@kit/analytics';void analytics.identify('user_123', { email: 'user@example.com', plan: 'pro',});Track a Page View
import { analytics } from '@kit/analytics';void analytics.trackPageView('/dashboard');How It Works
The analytics system uses a manager pattern that dispatches events to all registered providers:
- AnalyticsManager - Central hub that routes events to registered providers
- AnalyticsService - Interface that each provider implements
- NullAnalyticsService - Default no-op service when no providers are configured
When you call analytics.trackEvent(), the manager iterates through all active providers and calls their respective tracking methods. This means a single event can be recorded in Google Analytics, Mixpanel, and your custom service simultaneously.
Automatic Page View Tracking
The kit automatically tracks page views through the AnalyticsProvider component in apps/web/components/analytics-provider.tsx. This component:
- Subscribes to route changes via
usePathname() - Calls
analytics.trackPageView()on each navigation - Includes query parameters in the tracked URL
You don't need to manually track page views - the provider handles this automatically for all client-side navigations.
App Events Integration
The analytics system integrates with the App Events system (@kit/shared/events) to automatically track important user actions. The default mappings include:
| App Event | Analytics Action |
|---|---|
user.signedIn | identify() - Associates the session with the user |
user.signedUp | trackEvent('user.signedUp') |
user.updated | trackEvent('user.updated') |
checkout.started | trackEvent('checkout.started') |
You can extend these mappings in apps/web/components/analytics-provider.tsx:
apps/web/components/analytics-provider.tsx
const analyticsMapping: AnalyticsMapping = { // Existing mappings... 'user.signedIn': (event) => { const { userId, ...traits } = event.payload; if (userId) { return analytics.identify(userId, traits); } }, // Add your custom mappings 'subscription.upgraded': (event) => { return analytics.trackEvent('subscription_upgraded', { plan: event.payload.plan, previousPlan: event.payload.previousPlan, }); },};Server-Side Analytics
For tracking events in Server Actions or API routes, use the server-only export:
import 'server-only';import { analytics } from '@kit/analytics/server';export async function processPayment(userId: string) { // Process payment... void analytics.trackEvent('payment_processed', { userId, amount: '99.00', });}The server module has the same API as the client module but is designed for server-only contexts.
Topics
- Custom Analytics Provider - Integrate your preferred analytics service
API Reference
AnalyticsManager
The main interface for tracking analytics:
interface AnalyticsManager { // Track a page view trackPageView(path: string): Promise<unknown[]>; // Track a custom event trackEvent( eventName: string, eventProperties?: Record<string, string | string[]> ): Promise<unknown[]>; // Identify a user identify( userId: string, traits?: Record<string, string> ): Promise<unknown[]>; // Add a provider at runtime addProvider(provider: string, config: object): Promise<unknown>; // Remove a provider removeProvider(provider: string): void;}AnalyticsService
Interface that analytics providers must implement:
interface AnalyticsService { initialize(): Promise<unknown>; trackPageView(path: string): Promise<unknown>; trackEvent( eventName: string, eventProperties?: Record<string, string | string[]> ): Promise<unknown>; identify( userId: string, traits?: Record<string, string> ): Promise<unknown>;}Important Notes
- No default providers - The kit ships with a
NullAnalyticsServicethat logs to console in development. You need to add your own provider for production tracking. - Fire and forget - Analytics calls use
voidto avoid blocking. They run asynchronously without awaiting completion. - Client and server - Use
@kit/analyticsfor client code,@kit/analytics/serverfor server code. - Type-safe properties - Event properties are typed as
Record<string, string | string[]>.