# Understanding Analytics in MakerKit

> Learn how the Analytics system in MakerKit provides a flexible, provider-agnostic architecture for tracking user behavior in your SaaS application.

*Canonical: https://makerkit.dev/docs/nextjs-prisma/analytics/analytics-and-events*

---

The analytics system in this repo provides a unified interface for tracking user behavior across your application. Built on a provider-agnostic architecture, it lets you integrate the services you actually need without hard-wiring the app to one vendor.

{% sequence title="Analytics Documentation" description="Complete guide to analytics in the Next.js Prisma SaaS kit" %}

[How Analytics Works](#how-analytics-works)

[The AnalyticsService Interface](#the-analyticsservice-interface)

[Default Setup](#default-setup)

[Using Analytics](#using-analytics)

{% /sequence %}

## How Analytics Works

The analytics system is implemented in the `@kit/analytics` package with two core components:

1. **AnalyticsService Interface** - The contract all analytics providers must implement
2. **AnalyticsManager** - Orchestrates multiple providers and broadcasts events to all of them

By default, MakerKit ships with no analytics providers enabled. This is intentional - you choose which analytics service fits your needs and implement a provider for it.

### When to Add Analytics

- **Use analytics when** you need to understand user behavior, track conversions, or measure feature adoption
- **Avoid when** you're in early development or don't have a clear question you're trying to answer with data
- **If unsure** start with the NullAnalyticsService (default) and add a real provider once you've reached product-market fit

## The AnalyticsService Interface

Every analytics provider implements this interface:

```typescript {% title="packages/analytics/src/types.ts" %}
export interface AnalyticsService {
  // Called when the provider is registered
  initialize(): Promise<unknown>;

  // Associate a user with their actions
  identify(userId: string, traits?: Record<string, string>): Promise<unknown>;

  // Track page navigation
  trackPageView(path: string): Promise<unknown>;

  // Track custom events
  trackEvent(
    eventName: string,
    eventProperties?: Record<string, string | string[]>
  ): Promise<unknown>;
}
```

The interface is straightforward:

- **initialize** - Set up the analytics SDK, load scripts, etc.
- **identify** - Associate a user ID with subsequent events
- **trackPageView** - Record when users navigate between pages
- **trackEvent** - Record custom events with optional properties

## Default Setup

Out of the box, MakerKit uses a `NullAnalyticsService` that does nothing. This prevents errors when analytics methods are called before you've configured a provider.

```typescript {% title="packages/analytics/src/index.ts" %}
import { createAnalyticsManager } from './analytics-manager';
import { NullAnalyticsService } from './null-analytics-service';
import type { AnalyticsManager } from './types';

export const analytics: AnalyticsManager = createAnalyticsManager({
  providers: {
    null: () => NullAnalyticsService,
  },
});
```

The `NullAnalyticsService` simply ignores all calls, making it safe to use analytics throughout your codebase without defensive checks.

## Using Analytics

Import and use the analytics service anywhere in your application:

```typescript {% title="Example: Using analytics" %}
import { analytics } from '@kit/analytics';

// Identify a user after sign-in
void analytics.identify('user_123', { plan: 'pro' });

// Track a custom event
void analytics.trackEvent('feature_used', {
  featureName: 'export',
  format: 'csv',
});

// Track a page view (usually handled automatically)
void analytics.trackPageView('/dashboard');
```

The `void` keyword is used because these methods return Promises but we don't need to await them in fire-and-forget scenarios.

## Multi-Provider Support

The AnalyticsManager can run multiple providers simultaneously. When you call any analytics method, it broadcasts to all registered providers:

```typescript {% title="Example: Multiple providers" %}
export const analytics = createAnalyticsManager({
  providers: {
    googleAnalytics: () => new GoogleAnalyticsService(),
    mixpanel: () => new MixpanelService(),
    posthog: () => new PostHogService(),
  },
});

// This event is sent to all three providers
void analytics.trackEvent('button_clicked', { buttonId: 'signup' });
```

This lets you use different services for their strengths: Google Analytics for marketing attribution, Mixpanel for product analytics, and PostHog for session replay.

## Architecture Overview

```
┌─────────────────────────────────────────────────────┐
│                   Your Application                   │
│                                                      │
│  ┌─────────────┐                                    │
│  │  Component  │ ──────────▶ analytics.trackEvent() │
│  └─────────────┘                    │               │
│                                     ▼               │
│                          AnalyticsManager           │
│                         /     │      \              │
│                        ▼      ▼       ▼             │
│                  Provider Provider Provider         │
│                    (you implement these)            │
└─────────────────────────────────────────────────────┘
```

## Next Steps

1. **[Create a custom provider](custom-analytics-provider)** - Implement your preferred analytics service
2. **[Server-side analytics](server-side-analytics)** - Track events from API routes and server actions

### Related Documentation

- [Environment Variables](/help/configuration/environment-variables) - Configure analytics API keys
- [Deployment](/help/going-to-production/deployment) - Enable analytics in production
- [Monitoring](/help/monitoring) - Error tracking alongside analytics

**Next:** [Creating a Custom Analytics Provider →](custom-analytics-provider)
