Overview
Mixpanel is a product analytics platform that helps teams understand user behavior through event-based tracking, cohort analysis, and user journey mapping. Unlike traditional page-view analytics, Mixpanel focuses on tracking specific user actions and analyzing engagement patterns over time.
This comprehensive guide covers all installation methods for Mixpanel across web, mobile, and server environments, including framework-specific integrations and production deployment best practices.
Key Features
- Event-based analytics: Track specific user actions rather than just page views
- User profiles: Build comprehensive profiles with properties and behavior history
- Cohort analysis: Segment users based on behavior and properties
- Funnels and retention: Analyze conversion paths and user retention over time
- A/B testing: Run experiments and measure impact on key metrics
- Real-time data: Query and visualize data with minimal lag
Deployment Considerations
Before installing Mixpanel, evaluate these architectural decisions:
- Installation method: JavaScript snippet, npm package, tag manager, or mobile SDK
- Project tokens: Separate tokens for development, staging, and production
- Identity strategy: Anonymous tracking vs. user identification approach
- Event design: Define your event taxonomy and property naming conventions
- Proxy setup: Route requests through first-party domain to avoid ad blockers
- Privacy compliance: GDPR/CCPA requirements and consent management
- Data residency: US vs. EU data hosting based on regulatory requirements
Prerequisites
Account Setup
- Create Mixpanel account at mixpanel.com/register
- Create project for each environment (Development, Staging, Production)
- Obtain project tokens:
- Navigate to Project Settings → Project Details
- Copy the Project Token for each environment
- Configure project settings:
- Set timezone and data residency (US or EU)
- Enable/disable IP address geolocation
- Configure data retention policies
- Set up cross-project data copying if needed
Technical Requirements
- Web: Modern browsers (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)
- Mobile: iOS 12+ (Swift 5.0+) or Android 5.0+ (API level 21+)
- Server-side: Node.js 12+, Python 3.6+, Ruby 2.5+, Java 8+, PHP 7.2+
- Package managers: npm 6+, yarn 1.22+, CocoaPods 1.10+, Gradle 6+
Security Considerations
- Store project tokens in environment variables, never hard-code in repositories
- Use separate tokens per environment to prevent data mixing
- Implement proper consent management for GDPR/CCPA compliance
- Consider proxy setup to route tracking through first-party domain
- Regularly rotate API secrets for server-side integrations
- Use HTTPS for all tracking requests
JavaScript Library Installation
Snippet Installation (Recommended)
The most common installation method is embedding the Mixpanel JavaScript snippet in your HTML <head>:
<!-- Start Mixpanel -->
<script type="text/javascript">
(function(f,b){if(!b.__SV){var e,g,i,h;window.mixpanel=b;b._i=[];b.init=function(e,f,c){function g(a,d){var b=d.split(".");2==b.length&&(a=a[b[0]],d=b[1]);a[d]=function(){a.push([d].concat(Array.prototype.slice.call(arguments,0)))}}var a=b;"undefined"!==typeof c?a=b[c]=[]:c="mixpanel";a.people=a.people||[];a.toString=function(a){var d="mixpanel";"mixpanel"!==c&&(d+="."+c);a||(d+=" (stub)");return d};a.people.toString=function(){return a.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(" ");
for(h=0;h<i.length;h++)g(a,i[h]);var j="set set_once union unset remove delete".split(" ");a.get_group=function(){function b(c){d[c]=function(){call2_args=arguments;call2=[c].concat(Array.prototype.slice.call(call2_args,0));a.push([e,call2])}}for(var d={},e=["get_group"].concat(Array.prototype.slice.call(arguments,0)),c=0;c<j.length;c++)b(j[c]);return d};b._i.push([e,f,c])};b.__SV=1.2;e=f.createElement("script");e.type="text/javascript";e.async=!0;e.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===f.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";g=f.getElementsByTagName("script")[0];g.parentNode.insertBefore(e,g)}})(document,window.mixpanel||[]);
// Initialize with your project token
mixpanel.init("YOUR_PROJECT_TOKEN", {
debug: false,
track_pageview: true,
persistence: "localStorage"
});
</script>
<!-- End Mixpanel -->
Placement: Insert in <head> section before other analytics tools to ensure early initialization.
Environment-specific tokens:
<!-- Server-side template example (Node.js/EJS) -->
<script>
mixpanel.init("<%= process.env.MIXPANEL_PROJECT_TOKEN %>", {
debug: <%= process.env.NODE_ENV === 'development' %>,
track_pageview: true,
persistence: "localStorage"
});
</script>
Configuration Options
Customize Mixpanel behavior during initialization:
mixpanel.init("YOUR_PROJECT_TOKEN", {
// Enable debug mode (logs to console)
debug: false,
// Automatically track page views
track_pageview: true,
// Data persistence: 'cookie' or 'localStorage'
persistence: "localStorage",
// Persistence name prefix
persistence_name: "mp_",
// Cookie domain for cross-subdomain tracking
cookie_domain: "example.com",
// Secure cookies (HTTPS only)
secure_cookie: true,
// Cross-site tracking
cross_site_cookie: false,
// Cross-subdomain cookie
cross_subdomain_cookie: true,
// Disable persistence entirely
disable_persistence: false,
// Disable cookie usage
disable_cookie: false,
// Custom API host for proxying
api_host: "https://api.mixpanel.com",
// Batch requests
batch_requests: true,
batch_size: 50,
batch_flush_interval_ms: 5000,
// IP address tracking
ip: true,
// Property blacklist
property_blacklist: [],
// Opt out by default (require opt-in)
opt_out_tracking_by_default: false,
// Respect Do Not Track
respect_dnt: false,
// Ignore UTM parameters
ignore_dnt: false,
// Disable notifications
disable_notifications: true,
// Custom library name
loaded: function(mixpanel) {
console.log("Mixpanel loaded successfully");
}
});
Consent Management Integration
Implement GDPR/CCPA compliance with opt-in/opt-out tracking:
// Initialize without tracking
mixpanel.init("YOUR_PROJECT_TOKEN", {
opt_out_tracking_by_default: true,
loaded: function(mixpanel) {
// Check for existing consent
if (hasAnalyticsConsent()) {
mixpanel.opt_in_tracking();
}
}
});
// When user provides consent
function onConsentGranted() {
mixpanel.opt_in_tracking();
// Optionally identify user at this point
if (currentUser) {
mixpanel.identify(currentUser.id);
}
}
// When user revokes consent
function onConsentRevoked() {
mixpanel.opt_out_tracking();
mixpanel.reset(); // Clear local data
}
// Check opt-out status
if (mixpanel.has_opted_out_tracking()) {
console.log("User has opted out of tracking");
}
NPM Package Installation
For modern JavaScript applications using build tools:
npm install mixpanel-browser
# or
yarn add mixpanel-browser
Basic Implementation
import mixpanel from 'mixpanel-browser';
// Initialize Mixpanel
mixpanel.init('YOUR_PROJECT_TOKEN', {
debug: process.env.NODE_ENV === 'development',
track_pageview: true,
persistence: 'localStorage',
api_host: process.env.MIXPANEL_API_HOST || 'https://api.mixpanel.com'
});
// Track events
mixpanel.track('Page Viewed', {
page: 'Home',
section: 'Hero'
});
// Identify users
mixpanel.identify('user_123');
// Set user properties
mixpanel.people.set({
$name: 'John Doe',
$email: 'john@example.com',
plan: 'Premium',
signupDate: new Date().toISOString()
});
// Track with user properties
mixpanel.track('Purchase Completed', {
revenue: 49.99,
currency: 'USD',
productId: 'prod_123',
category: 'Digital Products'
});
Environment-Specific Configuration
// config/mixpanel.js
const mixpanelConfig = {
development: {
token: process.env.MIXPANEL_DEV_TOKEN,
config: {
debug: true,
track_pageview: true,
api_host: 'http://localhost:3000/mixpanel-proxy',
disable_notifications: true
}
},
staging: {
token: process.env.MIXPANEL_STAGING_TOKEN,
config: {
debug: false,
track_pageview: true,
batch_requests: true
}
},
production: {
token: process.env.MIXPANEL_PROD_TOKEN,
config: {
debug: false,
track_pageview: true,
batch_requests: true,
batch_size: 50,
secure_cookie: true,
api_host: 'https://analytics.yourdomain.com/mixpanel'
}
}
};
const env = process.env.NODE_ENV || 'development';
const { token, config } = mixpanelConfig[env];
mixpanel.init(token, config);
export default mixpanel;
Google Tag Manager Deployment
Deploy Mixpanel through GTM for centralized tag management.
Setup Steps
Create Custom HTML Tag:
- Tag Type: Custom HTML
- Tag Name: "Mixpanel - Initialization"
Insert Mixpanel Snippet:
<script>
(function(f,b){/* ... full Mixpanel snippet ... */})(document,window.mixpanel||[]);
mixpanel.init("{{Mixpanel Project Token}}", {
debug: {{Debug Mode}},
track_pageview: false, // Handle manually
persistence: "localStorage",
batch_requests: true
});
</script>
Create GTM Variables:
- Variable Name:
Mixpanel Project Token - Variable Type: Lookup Table
- Input Variable:
{{Environment}} - Output:
dev→your_dev_tokenstaging→your_staging_tokenproduction→your_prod_token
- Variable Name:
Configure Trigger:
- Trigger Type: Page View - Window Loaded
- Fire On: All Pages
Create Event Tracking Tags:
Page View Tag:
<script>
if (window.mixpanel) {
mixpanel.track('Page Viewed', {
page: {{Page Path}},
title: {{Page Title}},
referrer: {{Referrer}}
});
}
</script>
Custom Event Tag:
<script>
if (window.mixpanel) {
mixpanel.track({{Event Name}}, {
category: {{Event Category}},
label: {{Event Label}},
value: {{Event Value}}
});
}
</script>
React Integration
Using Mixpanel Hook
Create a custom hook for Mixpanel tracking:
// hooks/useMixpanel.js
import { useEffect } from 'react';
import mixpanel from 'mixpanel-browser';
// Initialize once
if (process.env.REACT_APP_MIXPANEL_TOKEN) {
mixpanel.init(process.env.REACT_APP_MIXPANEL_TOKEN, {
debug: process.env.NODE_ENV === 'development',
track_pageview: false, // Handle manually
persistence: 'localStorage'
});
}
export const useMixpanel = () => {
const track = (eventName, properties = {}) => {
mixpanel.track(eventName, {
...properties,
timestamp: new Date().toISOString()
});
};
const identify = (userId) => {
mixpanel.identify(userId);
};
const setUserProperties = (properties) => {
mixpanel.people.set(properties);
};
const setUserPropertiesOnce = (properties) => {
mixpanel.people.set_once(properties);
};
const incrementUserProperty = (property, amount = 1) => {
mixpanel.people.increment(property, amount);
};
const trackCharge = (amount, properties = {}) => {
mixpanel.people.track_charge(amount, properties);
};
const reset = () => {
mixpanel.reset();
};
const timeEvent = (eventName) => {
mixpanel.time_event(eventName);
};
const registerSuperProperties = (properties) => {
mixpanel.register(properties);
};
const registerSuperPropertiesOnce = (properties) => {
mixpanel.register_once(properties);
};
return {
track,
identify,
setUserProperties,
setUserPropertiesOnce,
incrementUserProperty,
trackCharge,
reset,
timeEvent,
registerSuperProperties,
registerSuperPropertiesOnce
};
};
Usage in Components
// components/Dashboard.js
import { useEffect } from 'react';
import { useMixpanel } from '../hooks/useMixpanel';
function Dashboard() {
const mixpanel = useMixpanel();
useEffect(() => {
mixpanel.track('Dashboard Viewed', {
referrer: document.referrer
});
}, []);
const handleFeatureClick = (feature) => {
mixpanel.track('Feature Clicked', {
feature: feature.name,
category: feature.category
});
};
return (
<div>
{/* Dashboard content */}
</div>
);
}
React Router Integration
// src/App.js
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useMixpanel } from './hooks/useMixpanel';
function App() {
const location = useLocation();
const mixpanel = useMixpanel();
useEffect(() => {
mixpanel.track('Page Viewed', {
path: location.pathname,
search: location.search,
hash: location.hash
});
}, [location, mixpanel]);
return (
<Router>
{/* Your routes */}
</Router>
);
}
React Context Provider
// context/MixpanelContext.js
import { createContext, useContext, useEffect } from 'react';
import mixpanel from 'mixpanel-browser';
const MixpanelContext = createContext(null);
export const MixpanelProvider = ({ children, token, config }) => {
useEffect(() => {
mixpanel.init(token, config);
}, [token, config]);
const value = {
track: (event, properties) => mixpanel.track(event, properties),
identify: (userId) => mixpanel.identify(userId),
people: mixpanel.people,
reset: () => mixpanel.reset(),
timeEvent: (event) => mixpanel.time_event(event),
register: (properties) => mixpanel.register(properties)
};
return (
<MixpanelContext.Provider value={value}>
{children}
</MixpanelContext.Provider>
);
};
export const useMixpanel = () => {
const context = useContext(MixpanelContext);
if (!context) {
throw new Error('useMixpanel must be used within MixpanelProvider');
}
return context;
};
// src/index.js
import { MixpanelProvider } from './context/MixpanelContext';
ReactDOM.render(
<MixpanelProvider
token={process.env.REACT_APP_MIXPANEL_TOKEN}
config={{ debug: false, track_pageview: true }}
>
<App />
</MixpanelProvider>,
document.getElementById('root')
);
Vue.js Integration
Vue 3 Plugin
// plugins/mixpanel.js
import mixpanel from 'mixpanel-browser';
export default {
install: (app, options) => {
mixpanel.init(options.token, options.config || {});
// Add to global properties
app.config.globalProperties.$mixpanel = mixpanel;
// Add convenience methods
app.config.globalProperties.$track = (event, properties) => {
mixpanel.track(event, properties);
};
app.config.globalProperties.$identify = (userId, properties) => {
mixpanel.identify(userId);
if (properties) {
mixpanel.people.set(properties);
}
};
// Provide for composition API
app.provide('mixpanel', mixpanel);
}
};
Register Plugin:
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import mixpanelPlugin from './plugins/mixpanel';
const app = createApp(App);
app.use(mixpanelPlugin, {
token: import.meta.env.VITE_MIXPANEL_TOKEN,
config: {
debug: import.meta.env.DEV,
track_pageview: true,
persistence: 'localStorage'
}
});
app.mount('#app');
Usage (Options API):
<template>
<button @click="handlePurchase">Buy Now</button>
</template>
<script>
export default {
methods: {
handlePurchase() {
this.$track('Purchase Initiated', {
productId: this.product.id,
price: this.product.price,
currency: 'USD'
});
}
},
mounted() {
this.$track('Product Page Viewed', {
productId: this.product.id
});
}
};
</script>
Usage (Composition API):
<script setup>
import { inject, onMounted } from 'vue';
const mixpanel = inject('mixpanel');
onMounted(() => {
mixpanel.track('Component Mounted');
});
const handleClick = () => {
mixpanel.track('Button Clicked');
};
</script>
Vue Router Integration
// router/index.js
import { createRouter } from 'vue-router';
import mixpanel from 'mixpanel-browser';
const router = createRouter({
// ... routes
});
router.afterEach((to, from) => {
mixpanel.track('Page Viewed', {
path: to.path,
name: to.name,
from: from.path
});
});
export default router;
Angular Integration
Service-Based Approach
// services/mixpanel.service.ts
import { Injectable } from '@angular/core';
import mixpanel from 'mixpanel-browser';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root'
})
export class MixpanelService {
constructor() {
this.initialize();
}
private initialize(): void {
if (environment.mixpanelToken) {
mixpanel.init(environment.mixpanelToken, {
debug: !environment.production,
track_pageview: false, // Manual tracking
persistence: 'localStorage',
batch_requests: environment.production
});
}
}
track(event: string, properties?: Record<string, any>): void {
mixpanel.track(event, properties);
}
identify(userId: string): void {
mixpanel.identify(userId);
}
setUserProperties(properties: Record<string, any>): void {
mixpanel.people.set(properties);
}
setUserPropertiesOnce(properties: Record<string, any>): void {
mixpanel.people.set_once(properties);
}
incrementProperty(property: string, amount: number = 1): void {
mixpanel.people.increment(property, amount);
}
trackCharge(amount: number, properties?: Record<string, any>): void {
mixpanel.people.track_charge(amount, properties);
}
timeEvent(event: string): void {
mixpanel.time_event(event);
}
registerSuperProperties(properties: Record<string, any>): void {
mixpanel.register(properties);
}
registerSuperPropertiesOnce(properties: Record<string, any>): void {
mixpanel.register_once(properties);
}
alias(alias: string, original?: string): void {
mixpanel.alias(alias, original);
}
reset(): void {
mixpanel.reset();
}
optInTracking(): void {
mixpanel.opt_in_tracking();
}
optOutTracking(): void {
mixpanel.opt_out_tracking();
}
hasOptedOutTracking(): boolean {
return mixpanel.has_opted_out_tracking();
}
}
Environment Configuration:
// environments/environment.prod.ts
export const environment = {
production: true,
mixpanelToken: 'YOUR_PROD_TOKEN'
};
// environments/environment.ts
export const environment = {
production: false,
mixpanelToken: 'YOUR_DEV_TOKEN'
};
Usage in Components:
// components/checkout/checkout.component.ts
import { Component, OnInit } from '@angular/core';
import { MixpanelService } from '../../services/mixpanel.service';
@Component({
selector: 'app-checkout',
templateUrl: './checkout.component.html'
})
export class CheckoutComponent implements OnInit {
constructor(private mixpanel: MixpanelService) {}
ngOnInit(): void {
this.mixpanel.track('Checkout Page Viewed');
this.mixpanel.timeEvent('Checkout Completed');
}
completePurchase(order: any): void {
this.mixpanel.track('Checkout Completed', {
orderId: order.id,
revenue: order.total,
items: order.items.length,
paymentMethod: order.paymentMethod
});
this.mixpanel.trackCharge(order.total, {
orderId: order.id
});
this.mixpanel.incrementProperty('totalPurchases', 1);
}
}
Router Event Tracking
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { MixpanelService } from './services/mixpanel.service';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
constructor(
private router: Router,
private mixpanel: MixpanelService
) {}
ngOnInit(): void {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) => {
this.mixpanel.track('Page Viewed', {
path: event.urlAfterRedirects,
url: event.url
});
});
}
}
Next.js Integration
App Router (Next.js 13+)
// lib/mixpanel.ts
import mixpanel, { Mixpanel } from 'mixpanel-browser';
let instance: Mixpanel | null = null;
export const getMixpanel = (): Mixpanel => {
if (typeof window !== 'undefined' && !instance) {
mixpanel.init(process.env.NEXT_PUBLIC_MIXPANEL_TOKEN || '', {
debug: process.env.NODE_ENV === 'development',
track_pageview: false,
persistence: 'localStorage'
});
instance = mixpanel;
}
return instance!;
};
export default getMixpanel;
// components/MixpanelProvider.tsx
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import getMixpanel from '@/lib/mixpanel';
export default function MixpanelProvider({
children
}: {
children: React.ReactNode
}) {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
const mixpanel = getMixpanel();
mixpanel.track('Page Viewed', {
path: pathname,
search: searchParams.toString()
});
}, [pathname, searchParams]);
return <>{children}</>;
}
// app/layout.tsx
import MixpanelProvider from '@/components/MixpanelProvider';
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<MixpanelProvider>
{children}
</MixpanelProvider>
</body>
</html>
);
}
Server Actions Integration
// app/actions.ts
'use server';
import { Mixpanel } from 'mixpanel';
const mixpanel = Mixpanel.init(process.env.MIXPANEL_TOKEN || '');
export async function trackServerEvent(
distinctId: string,
event: string,
properties?: Record<string, any>
) {
mixpanel.track(event, {
distinct_id: distinctId,
...properties
});
}
Mobile SDKs
iOS (Swift)
Installation via CocoaPods:
# Podfile
platform :ios, '13.0'
target 'YourApp' do
use_frameworks!
pod 'Mixpanel-swift', '~> 4.0'
end
pod install
Initialize:
// AppDelegate.swift
import UIKit
import Mixpanel
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
#if DEBUG
Mixpanel.initialize(token: "DEV_TOKEN", trackAutomaticEvents: true)
#else
Mixpanel.initialize(token: "PROD_TOKEN", trackAutomaticEvents: true)
#endif
Mixpanel.mainInstance().loggingEnabled = true
return true
}
}
Track Events:
// Track event
Mixpanel.mainInstance().track(event: "Purchase Completed", properties: [
"revenue": 49.99,
"currency": "USD",
"productId": "prod_123"
])
// Identify user
Mixpanel.mainInstance().identify(distinctId: "user_123")
// Set user properties
Mixpanel.mainInstance().people.set(properties: [
"$name": "John Doe",
"$email": "john@example.com",
"plan": "Premium"
])
// Set properties once
Mixpanel.mainInstance().people.setOnce(properties: [
"signupDate": Date()
])
// Increment property
Mixpanel.mainInstance().people.increment(property: "totalPurchases", by: 1)
// Track charge
Mixpanel.mainInstance().people.trackCharge(amount: 49.99, properties: [
"orderId": "order_123"
])
// Time events
Mixpanel.mainInstance().time(event: "Video Watched")
// ... later
Mixpanel.mainInstance().track(event: "Video Watched", properties: [
"videoId": "video_456"
])
Android (Kotlin)
Installation via Gradle:
// build.gradle (app level)
dependencies {
implementation 'com.mixpanel.android:mixpanel-android:7.+'
}
Add permissions:
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Initialize:
// MainApplication.kt
import android.app.Application
import com.mixpanel.android.mpmetrics.MixpanelAPI
class MainApplication : Application() {
companion object {
lateinit var mixpanel: MixpanelAPI
}
override fun onCreate() {
super.onCreate()
val token = if (BuildConfig.DEBUG) {
"DEV_TOKEN"
} else {
"PROD_TOKEN"
}
mixpanel = MixpanelAPI.getInstance(this, token, true)
}
}
Track Events:
// Track event
MainApplication.mixpanel.track("Purchase Completed", JSONObject(mapOf(
"revenue" to 49.99,
"currency" to "USD",
"productId" to "prod_123"
)))
// Identify user
MainApplication.mixpanel.identify("user_123")
// Set user properties
MainApplication.mixpanel.people.set(JSONObject(mapOf(
"\$name" to "John Doe",
"\$email" to "john@example.com",
"plan" to "Premium"
)))
// Set properties once
MainApplication.mixpanel.people.setOnce(JSONObject(mapOf(
"signupDate" to System.currentTimeMillis()
)))
// Increment property
MainApplication.mixpanel.people.increment("totalPurchases", 1.0)
// Track charge
MainApplication.mixpanel.people.trackCharge(49.99, JSONObject(mapOf(
"orderId" to "order_123"
)))
// Time events
MainApplication.mixpanel.timeEvent("Video Watched")
// ... later
MainApplication.mixpanel.track("Video Watched", JSONObject(mapOf(
"videoId" to "video_456"
)))
React Native
npm install mixpanel-react-native
# iOS only:
cd ios && pod install && cd ..
Initialize:
// App.js
import { Mixpanel } from 'mixpanel-react-native';
const mixpanel = new Mixpanel("YOUR_TOKEN", true);
const App = () => {
useEffect(() => {
mixpanel.init();
}, []);
return <YourApp mixpanel={mixpanel} />;
};
Track Events:
// Track event
mixpanel.track('Purchase Completed', {
revenue: 49.99,
currency: 'USD',
productId: 'prod_123'
});
// Identify user
mixpanel.identify('user_123');
// Set user properties
mixpanel.getPeople().set({
'$name': 'John Doe',
'$email': 'john@example.com',
'plan': 'Premium'
});
// Track charge
mixpanel.getPeople().trackCharge(49.99, {
orderId: 'order_123'
});
// Time events
mixpanel.timeEvent('Video Watched');
// ... later
mixpanel.track('Video Watched', {
videoId: 'video_456'
});
Server-Side Tracking
Node.js
npm install mixpanel
const Mixpanel = require('mixpanel');
const mixpanel = Mixpanel.init('YOUR_PROJECT_TOKEN', {
host: 'api.mixpanel.com',
protocol: 'https'
});
// Track event
mixpanel.track('Order Completed', {
distinct_id: 'user_123',
revenue: 149.99,
currency: 'USD',
orderId: 'order_789',
items: 3,
time: new Date()
});
// Set user properties
mixpanel.people.set('user_123', {
$name: 'John Doe',
$email: 'john@example.com',
plan: 'Enterprise',
mrr: 499
});
// Set properties once
mixpanel.people.set_once('user_123', {
signupDate: new Date()
});
// Increment property
mixpanel.people.increment('user_123', 'totalOrders', 1);
// Track charge
mixpanel.people.track_charge('user_123', 149.99, {
orderId: 'order_789',
time: new Date()
});
// Import historical data
mixpanel.import('Event Name', new Date('2024-01-01'), {
distinct_id: 'user_123',
property: 'value'
});
// Batch tracking for efficiency
const batch = mixpanel.import_batch([
{ event: 'Event 1', properties: { distinct_id: 'user_1' } },
{ event: 'Event 2', properties: { distinct_id: 'user_2' } }
]);
Python
pip install mixpanel
from mixpanel import Mixpanel
from datetime import datetime
mp = Mixpanel('YOUR_PROJECT_TOKEN')
# Track event
mp.track('user_123', 'Subscription Upgraded', {
'previousPlan': 'Pro',
'newPlan': 'Enterprise',
'revenue': 299.99,
'time': datetime.now().isoformat()
})
# Set user properties
mp.people_set('user_123', {
'$name': 'John Doe',
'$email': 'john@example.com',
'plan': 'Enterprise',
'industry': 'Technology'
})
# Set properties once
mp.people_set_once('user_123', {
'signupDate': datetime.now().isoformat()
})
# Increment property
mp.people_increment('user_123', {
'totalPurchases': 1,
'lifetimeValue': 299.99
})
# Track charge
mp.people_track_charge('user_123', 299.99, {
'orderId': 'order_789',
'time': datetime.now().isoformat()
})
# Append to list property
mp.people_append('user_123', {
'products': 'Product XYZ'
})
PHP
composer require mixpanel/mixpanel-php
<?php
require 'vendor/autoload.php';
$mp = Mixpanel::getInstance("YOUR_PROJECT_TOKEN");
// Track event
$mp->track("Order Completed", array(
"distinct_id" => "user_123",
"revenue" => 149.99,
"currency" => "USD",
"orderId" => "order_789"
));
// Identify and set user properties
$mp->people->set("user_123", array(
'$name' => "John Doe",
'$email' => "john@example.com",
'plan' => "Enterprise"
));
// Set properties once
$mp->people->setOnce("user_123", array(
'signupDate' => date('c')
));
// Increment property
$mp->people->increment("user_123", "totalOrders", 1);
// Track charge
$mp->people->trackCharge("user_123", 149.99, array(
'orderId' => "order_789",
'time' => time()
));
?>
Proxy Setup
Route Mixpanel requests through your domain to avoid ad blockers:
Nginx Configuration
# /etc/nginx/sites-available/yoursite.conf
location /mp {
proxy_pass https://api.mixpanel.com;
proxy_set_header Host api.mixpanel.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
# Handle CORS
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
}
Client Configuration
mixpanel.init('YOUR_TOKEN', {
api_host: 'https://yourdomain.com/mp'
});
Cloudflare Worker Proxy
// Cloudflare Worker
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
// Rewrite to Mixpanel API
url.hostname = 'api.mixpanel.com'
url.protocol = 'https:'
const modifiedRequest = new Request(url.toString(), {
method: request.method,
headers: request.headers,
body: request.body
})
return await fetch(modifiedRequest)
}
Verification Steps
1. Live View
- Navigate to Live View in Mixpanel dashboard
- Perform test events on your site/app
- Verify events appear in real-time (within 60 seconds)
- Check event properties and user profiles
2. Console Debugging
Enable debug mode:
mixpanel.init('YOUR_TOKEN', { debug: true });
Check browser console for Mixpanel logs showing tracked events and network requests.
3. User Profile Verification
// Track test event with unique identifier
const testId = 'test_' + Date.now();
mixpanel.identify(testId);
mixpanel.people.set({
testProperty: 'verification',
timestamp: new Date().toISOString()
});
mixpanel.track('Test Event', {
testId: testId
});
Navigate to Users → Explore → Search for test ID to verify profile creation.
4. Network Inspection
Use browser DevTools Network tab:
- Look for requests to
api.mixpanel.comor your proxy - Verify
dataparameter contains base64-encoded event data - Check for 200 OK responses
Troubleshooting
Events Not Appearing
Check initialization:
console.log(mixpanel.config); // Should show initialized config
console.log(mixpanel.get_distinct_id()); // Should return distinct ID
Common issues:
- Ad blockers: Mixpanel domain blocked
- Solution: Use first-party proxy or test in incognito mode
- Project token mismatch: Wrong environment token
- Solution: Verify token matches project in dashboard
- CORS errors: Cross-origin request blocked
- Solution: Ensure proper CORS headers or use proxy
- Opt-out enabled: User opted out of tracking
- Solution: Check
mixpanel.has_opted_out_tracking()
- Solution: Check
Identity Not Persisting
Check storage:
// Check localStorage
console.log(localStorage.getItem('mp_' + 'YOUR_TOKEN' + '_mixpanel'));
// Check cookies
console.log(document.cookie);
Common issues:
- Storage disabled: Browser blocking localStorage/cookies
- Solution: Test in different browser or adjust privacy settings
- Persistence mode: Incorrect persistence configuration
- Solution: Try switching between 'localStorage' and 'cookie'
- Cross-domain: Identity not shared across domains
- Solution: Configure cookie_domain properly
People Profiles Not Updating
Requirements:
- Must call
identify()beforepeople.set() - User must be identified (not anonymous)
// Wrong order
mixpanel.people.set({ plan: 'Premium' });
mixpanel.identify('user_123');
// Correct order
mixpanel.identify('user_123');
mixpanel.people.set({ plan: 'Premium' });
Security Best Practices
1. Token Management
// Never hard-code tokens
mixpanel.init('abc123def456');
// Use environment variables
mixpanel.init(process.env.MIXPANEL_TOKEN);
2. PII Handling
Avoid sending sensitive data:
// Bad: Sending full email
mixpanel.people.set({ email: 'user@example.com' });
// Good: Hash or pseudonymize
mixpanel.people.set({
emailHash: sha256('user@example.com'),
emailDomain: 'example.com'
});
3. Consent Implementation
// Opt out by default
mixpanel.init('TOKEN', {
opt_out_tracking_by_default: true
});
// Opt in when consent granted
function onConsentGranted() {
mixpanel.opt_in_tracking();
}
4. Server-Side Security
// Use API secret for server-side requests
const Mixpanel = require('mixpanel');
const mixpanel = Mixpanel.init('TOKEN', {
secret: process.env.MIXPANEL_API_SECRET
});
Performance Optimization
1. Batch Requests
mixpanel.init('TOKEN', {
batch_requests: true,
batch_size: 50,
batch_flush_interval_ms: 5000
});
2. Selective Tracking
// Only track critical events
const criticalEvents = ['Purchase', 'Signup', 'Login'];
function trackIfCritical(event, properties) {
if (criticalEvents.includes(event)) {
mixpanel.track(event, properties);
}
}
3. Debounce High-Frequency Events
import { debounce } from 'lodash';
const trackScroll = debounce(() => {
mixpanel.track('Page Scrolled', {
depth: window.scrollY
});
}, 1000);
window.addEventListener('scroll', trackScroll);
Advanced Features
Super Properties
Register properties that apply to all events:
// Register super properties
mixpanel.register({
appVersion: '2.5.0',
platform: 'web',
environment: 'production'
});
// Register once (won't overwrite existing)
mixpanel.register_once({
firstVisit: new Date().toISOString()
});
// All subsequent events include these properties
mixpanel.track('Button Clicked'); // Includes appVersion, platform, etc.
Group Analytics
Track account-level properties:
// Set group
mixpanel.set_group('company', 'company_123');
// Set group properties
mixpanel.get_group('company', 'company_123').set({
name: 'Acme Corp',
plan: 'Enterprise',
seats: 100
});
// Track with group context
mixpanel.track('Feature Used'); // Automatically includes company group
Aliasing
Link anonymous and identified users:
// User browses anonymously
const anonId = mixpanel.get_distinct_id();
// User signs up
const userId = 'user_123';
mixpanel.alias(userId, anonId);
mixpanel.identify(userId);
// Now all anonymous events are linked to user_123
Event Timing
Measure duration of actions:
// Start timer
mixpanel.time_event('Video Watched');
// ... user watches video ...
// Track event (includes duration automatically)
mixpanel.track('Video Watched', {
videoId: 'video_456',
videoTitle: 'Product Demo'
});
// Event will include a 'duration' property in seconds
Configuration Recommendations
Event Naming: Use the Object Action pattern consistently: Song Played, Cart Updated, Signup Completed. Mixpanel event names are case-sensitive — standardize on Title Case. Limit to 30-50 core events and use properties for granularity. Document all events in Mixpanel's Lexicon (Data Management → Lexicon).
Identity Strategy: Call mixpanel.identify(userId) at login. Before login, Mixpanel auto-assigns a distinct_id. On identify, Mixpanel links pre-login anonymous activity to the identified user. For cross-device tracking, call identify with the same user ID on each device. Never call alias() in new implementations — it's legacy behavior for Mixpanel Original ID Merge only.
Data Residency: Choose US (api.mixpanel.com) or EU (api-eu.mixpanel.com) during project creation. EU data center stores all data in Frankfurt (AWS eu-central-1). Set via mixpanel.init('TOKEN', { api_host: 'https://api-eu.mixpanel.com' }). This cannot be changed after project creation.
Proxy Setup: Route events through your domain (mixpanel.init('TOKEN', { api_host: 'https://analytics.yourdomain.com' })) to bypass ad blockers. Proxy to api.mixpanel.com (or api-eu.mixpanel.com for EU). This typically recovers 10-20% of blocked events.
Data Warehouse Export: Use Mixpanel's data pipeline to export raw events to BigQuery, Snowflake, or S3. Configure in Project Settings → Data Pipeline. Events export within 24 hours. For real-time needs, use Mixpanel's Export API or webhook integrations.