To integrate Mixpanel with Bolt.new, install `mixpanel-browser` via npm and initialize it with your Project Token. The browser SDK sends events directly from the user's browser to Mixpanel's servers over HTTPS, so it works in both the Bolt WebContainer preview and production. Call mixpanel.track() to record events and mixpanel.identify() to link sessions to users. Mixpanel's free plan includes 20 million events per month.
Mixpanel Product Analytics in Bolt.new: Understand What Users Actually Do
Mixpanel is a product analytics platform built around a simple idea: track every meaningful thing users do in your app, then ask questions about that data. Unlike Google Analytics (which focuses on traffic sources and page views), Mixpanel focuses on user actions within your product — which features they use, how they move through your onboarding flow, which cohorts retain best, and where they drop off. This makes Mixpanel particularly valuable for SaaS products, mobile apps, and any application where understanding in-app behavior matters more than knowing which Google search led someone to your site.
For Bolt.new developers, Mixpanel is an excellent choice because the browser SDK (`mixpanel-browser`) installs as a standard npm package and sends data directly from the user's browser to Mixpanel's servers. The WebContainer does not need to proxy or forward these requests — they go over HTTPS from the browser, bypassing the WebContainer's server-side networking layer entirely. You can add Mixpanel to your Bolt app, test it in the WebContainer preview, verify events fire in Mixpanel's Live Events feed, and iterate on your tracking plan before deploying to production.
Mixpanel's free plan is generous for early-stage apps: 20 million tracked events per month, unlimited retained history, and access to all core analytics features including funnels, retention, flows, and cohort analysis. There is no time limit on the free plan. Paid plans start when you need advanced features like Data Pipelines (BigQuery/Snowflake export), Group Analytics, or higher event volumes.
Integration method
Mixpanel's browser SDK (`mixpanel-browser`) communicates directly from the user's browser to Mixpanel's API servers over HTTPS — no server-side proxy required for standard event tracking. This means it works in Bolt's WebContainer preview out of the box. For server-side use cases like importing historical data, querying Mixpanel's Data Export API, or sending events from backend processes, use a Next.js API route with Mixpanel's server-side SDK and keep credentials server-only.
Prerequisites
- A Mixpanel account (free at mixpanel.com) with a project created and a Project Token copied from Settings → Project Settings
- A Bolt.new project — Vite (React) or Next.js both work for the browser SDK
- For user-level analytics: an authentication system in your app (Supabase Auth, Clerk, or similar) so you can call mixpanel.identify()
- For the Data Export API: a Mixpanel Service Account created in Settings → Service Accounts (requires at least a Growth plan for full API access)
Step-by-step guide
Install and Initialize mixpanel-browser
Install and Initialize mixpanel-browser
The `mixpanel-browser` package is Mixpanel's official browser-side SDK. It is a pure JavaScript package with no native module dependencies, so it installs and runs cleanly in Bolt's WebContainer. After initialization, the SDK automatically tracks a set of super properties (browser, OS, screen resolution, $current_url) on every event without any additional configuration. Your Mixpanel Project Token is the only credential needed for the browser SDK. Find it in Mixpanel Settings (gear icon bottom-left) → Project Settings → Project Token. It is safe to use as a VITE_ variable or NEXT_PUBLIC_ variable because it only identifies your project for data ingestion — it cannot be used to read or delete your analytics data. Keep your Mixpanel Service Account credentials (for the Data Export API) server-side only. Initialize Mixpanel once in your app's entry point. The init() call accepts your Project Token and an optional config object. Key config options: debug: true enables verbose console logging during development (shows every event being sent), track_pageview: true enables automatic page view tracking (useful for Vite apps; for Next.js with client-side routing, disable this and handle manually), and persistence: 'localStorage' stores the distinct_id across page refreshes (the default and recommended setting). After calling init(), Mixpanel creates an anonymous distinct_id for the current user and stores it in localStorage. All events from this browser session are associated with this anonymous ID until you call mixpanel.identify() with a real user ID. This means analytics data is captured even for logged-out or anonymous users, and the timeline is preserved when an anonymous user later signs up.
Install mixpanel-browser in my Bolt.new project and initialize it. Create lib/mixpanel.ts that exports an initialized Mixpanel instance. Read the project token from import.meta.env.VITE_MIXPANEL_TOKEN. In development (import.meta.env.DEV), enable debug mode. Export helper functions: track(eventName, properties), identify(userId, userProperties), and reset(). Initialize Mixpanel at app startup in main.tsx (Vite) or in a MixpanelProvider component for Next.js. Add VITE_MIXPANEL_TOKEN=YOUR_PROJECT_TOKEN to .env as a placeholder.
Paste this in Bolt.new chat
1// lib/mixpanel.ts2import mixpanel from 'mixpanel-browser';34const TOKEN = import.meta.env.VITE_MIXPANEL_TOKEN as string;56let initialized = false;78export function initMixpanel() {9 if (!TOKEN) {10 console.warn('Mixpanel: VITE_MIXPANEL_TOKEN is not set');11 return;12 }13 if (initialized) return;1415 mixpanel.init(TOKEN, {16 debug: import.meta.env.DEV,17 track_pageview: true,18 persistence: 'localStorage',19 ignore_dnt: false, // respect Do Not Track header20 });2122 initialized = true;23}2425export function track(26 eventName: string,27 properties: Record<string, string | number | boolean> = {}28) {29 if (!initialized) return;30 mixpanel.track(eventName, properties);31}3233export function identify(userId: string, userProps?: Record<string, unknown>) {34 if (!initialized) return;35 mixpanel.identify(userId);36 if (userProps) {37 mixpanel.people.set(userProps);38 }39}4041export function reset() {42 if (!initialized) return;43 mixpanel.reset();44}Pro tip: Set debug: import.meta.env.DEV so Mixpanel logs each event to the browser console during development. You'll see messages like 'mixpanel.track: event_name' with the full property payload, making it easy to verify events fire correctly without switching to the Mixpanel dashboard.
Expected result: mixpanel-browser installs without errors in the Bolt WebContainer. After calling initMixpanel(), open the Mixpanel dashboard → Live Events. Visit your Bolt preview and you should see an $mp_web_page_view event appear within a few seconds.
Identify Users and Set Profile Properties
Identify Users and Set Profile Properties
Mixpanel tracks events against a 'distinct_id' — by default, an anonymous UUID assigned by the SDK. When a user logs in, you need to call mixpanel.identify(userId) to link the anonymous events to the real user account. This is critical for user-level analytics: cohort analysis, retention reports, and per-user funnels all require identified users. The identify() call accepts a string user ID. Use the same permanent user ID from your database (a UUID or auto-increment integer) — not an email address, since users can change emails. Mixpanel will merge the pre-login anonymous events with the identified user profile, creating a complete timeline from first visit through conversion and beyond. After calling identify(), call mixpanel.people.set() to add user properties to their Mixpanel profile. These properties become dimensions for segmentation: show me all sessions by users on the Pro plan, compare retention between users who completed onboarding vs. those who skipped it. People properties sync to the user profile in Mixpanel's People section. Use mixpanel.people.set_once() for properties that should never be overwritten — for example, the user's signup date. Calling set_once('$created', date) on every login won't overwrite the original signup date if it was already set. Use mixpanel.people.set() for mutable properties like plan or last_login that should update. When a user logs out, call mixpanel.reset() to generate a new anonymous distinct_id and clear the stored user state. This prevents subsequent anonymous browsing sessions from being attributed to the previous user.
Add Mixpanel user identification to my auth flow. When a user logs in via Supabase Auth (in the onAuthStateChange callback), call identify(user.id, { $email: user.email, $name: user.user_metadata?.full_name, plan: user.user_metadata?.plan || 'free', $created: user.created_at }). When they log out, call reset() from lib/mixpanel.ts. Import these functions in my auth context. Also track 'user_signed_in' and 'user_signed_out' events with the appropriate method.
Paste this in Bolt.new chat
1// In your auth context — after Supabase auth state change:2import { identify, track, reset } from '@/lib/mixpanel';34// On sign in:5identify(user.id, {6 $email: user.email,7 $name: user.user_metadata?.full_name ?? '',8 plan: user.user_metadata?.plan ?? 'free',9 $created: user.created_at,10 app_version: import.meta.env.VITE_APP_VERSION ?? '1.0.0',11});12track('user_signed_in', {13 method: session.user.app_metadata?.provider ?? 'email',14});1516// On sign out:17track('user_signed_out', {});18reset();1920// For incrementing numeric people properties (e.g., login count):21// import mixpanel from 'mixpanel-browser';22// mixpanel.people.increment('login_count');Pro tip: Mixpanel's reserved people properties start with $ (like $email, $name, $created). These automatically populate specific fields in the Mixpanel People dashboard. Custom properties (like plan, company, or feature_flags) use regular names without a $ prefix.
Expected result: After logging in, go to Mixpanel → People. Your user profile appears with the email, name, and plan properties you set. All future events from this browser are attributed to this user ID. The user_signed_in event appears in Live Events.
Track Key Business Events with Meaningful Properties
Track Key Business Events with Meaningful Properties
The most valuable Mixpanel setups track a focused set of events that represent actual business outcomes — not every click or hover. A good tracking plan starts with your conversion funnel and then adds the top 5-10 actions that correlate with retention and revenue. Each event should have a descriptive snake_case name that reads like a sentence in past tense: 'project_created', 'file_exported', 'subscription_upgraded', 'feature_enabled'. Properties add context that lets you filter and segment: a 'file_exported' event with format: 'pdf' tells you more than 'file_exported' alone. Mixpanel's super properties feature (mixpanel.register()) sets properties that are automatically attached to every subsequent event. This is useful for properties that apply globally: plan tier, app version, or A/B test variant. Set super properties at login after calling identify() and they persist in localStorage until reset() is called. For events that need precise timing or properties not available at the exact moment of tracking, use mixpanel.time_event('event_name') before the action starts, then call mixpanel.track('event_name', properties) when it completes. Mixpanel automatically adds a $duration property in seconds. This is useful for measuring how long users take to complete flows like onboarding or checkout. One architectural pattern that works well in React: create a centralized analytics.ts file that exports typed event-tracking functions. Instead of calling mixpanel.track() directly in components (which creates tight coupling to Mixpanel), components call analytics.signupCompleted() or analytics.projectCreated(). This makes it trivial to add Amplitude or Segment alongside Mixpanel later.
Create a centralized analytics tracking module in lib/analytics.ts that wraps Mixpanel events with TypeScript types. Export typed functions for: signupCompleted(method: string), onboardingStepCompleted(step: number, stepName: string), projectCreated(projectType: string, templateUsed: boolean), subscriptionUpgraded(fromPlan: string, toPlan: string, mrr: number), exportCompleted(format: string, itemCount: number), and featureEnabled(featureName: string). Each function should call the track function from lib/mixpanel.ts with the appropriate event name and properties.
Paste this in Bolt.new chat
1// lib/analytics.ts2import { track } from './mixpanel';34export const analytics = {5 signupCompleted: (method: 'email' | 'google' | 'github') =>6 track('signup_completed', { method }),78 onboardingStepCompleted: (step: number, stepName: string) =>9 track('onboarding_step_completed', { step_number: step, step_name: stepName }),1011 onboardingCompleted: (totalSteps: number, timeSpentSeconds: number) =>12 track('onboarding_completed', {13 total_steps: totalSteps,14 time_spent_seconds: timeSpentSeconds,15 }),1617 projectCreated: (projectType: string, templateUsed: boolean) =>18 track('project_created', { project_type: projectType, template_used: templateUsed }),1920 subscriptionUpgraded: (fromPlan: string, toPlan: string, mrr: number) =>21 track('subscription_upgraded', { from_plan: fromPlan, to_plan: toPlan, mrr }),2223 exportCompleted: (format: string, itemCount: number) =>24 track('export_completed', { format, item_count: itemCount }),2526 featureEnabled: (featureName: string) =>27 track('feature_enabled', { feature_name: featureName }),2829 searchPerformed: (query: string, resultsCount: number) =>30 track('search_performed', { query_length: query.length, results_count: resultsCount }),31};Pro tip: Avoid tracking the search query text itself (privacy) — track query_length and results_count instead. Similarly, track plan names and amounts but not payment card or personal identification details. Design your tracking plan with user privacy in mind from the start.
Expected result: Custom events appear in Mixpanel Live Events as they fire. Go to Mixpanel → Insights, select your events, and create a simple chart showing event counts over the last 7 days. Funnels can be built by combining any sequence of your tracked events.
Query Mixpanel Data via API for a Custom Dashboard
Query Mixpanel Data via API for a Custom Dashboard
Mixpanel's JQL (JavaScript Query Language) Data Export API and the newer Mixpanel Query API allow you to run analytics queries programmatically and display results in your own UI. This is useful for building internal dashboards that show key metrics without requiring team members to have Mixpanel accounts, or for embedding analytics data directly in your admin panel. Mixpanel API access uses Service Account authentication. Create a Service Account in Mixpanel Settings → Service Accounts → Create Service Account. Give it a name and copy the username and secret — the secret is shown only once. Store these as server-side environment variables. The Mixpanel Query API (api.mixpanel.com/api/query/insights) accepts requests structured like Mixpanel Insights queries. You specify the event name, date range, metric (total, unique users, DAU), and optional filters and breakdowns. Responses are JSON objects with time-series data. Important: Mixpanel's query APIs must be called from a server-side Next.js API route, not directly from the browser. The Service Account credentials give read access to all your analytics data and must stay server-side. Additionally, because Mixpanel's API uses HTTP Basic Auth with the service account credentials, calling it from the browser would expose those credentials in client-side code. Note on WebContainer: if you test this API route in the Bolt preview and encounter connection issues, it is likely a WebContainer HTTP constraint affecting the googleapis authentication flow. Deploy to Netlify or Bolt Cloud to test server-side API routes that require multi-step authentication flows.
Create a Next.js API route at app/api/mixpanel/events/route.ts that queries Mixpanel's API for event counts over the last 7 days. Use MIXPANEL_SERVICE_ACCOUNT_USERNAME and MIXPANEL_SERVICE_ACCOUNT_SECRET for authentication (HTTP Basic Auth), and MIXPANEL_PROJECT_ID for the project. Call GET https://data.mixpanel.com/api/2.0/jql with a query for the total count of signup_completed, project_created, and subscription_upgraded events. Return the counts in a structured JSON response. Create a simple MetricsDashboard React component that fetches and displays these numbers.
Paste this in Bolt.new chat
1// app/api/mixpanel/events/route.ts2import { NextResponse } from 'next/server';34export async function GET() {5 const username = process.env.MIXPANEL_SERVICE_ACCOUNT_USERNAME;6 const secret = process.env.MIXPANEL_SERVICE_ACCOUNT_SECRET;7 const projectId = process.env.MIXPANEL_PROJECT_ID;89 if (!username || !secret || !projectId) {10 return NextResponse.json(11 { error: 'Mixpanel credentials not configured' },12 { status: 500 }13 );14 }1516 const credentials = Buffer.from(`${username}:${secret}`).toString('base64');17 const fromDate = new Date();18 fromDate.setDate(fromDate.getDate() - 7);19 const from = fromDate.toISOString().split('T')[0];20 const to = new Date().toISOString().split('T')[0];2122 const events = ['signup_completed', 'project_created', 'subscription_upgraded'];2324 try {25 const results = await Promise.all(26 events.map(async (eventName) => {27 const url = new URL('https://data.mixpanel.com/api/2.0/segmentation');28 url.searchParams.set('project_id', projectId);29 url.searchParams.set('event', eventName);30 url.searchParams.set('from_date', from);31 url.searchParams.set('to_date', to);32 url.searchParams.set('type', 'general');3334 const res = await fetch(url.toString(), {35 headers: { Authorization: `Basic ${credentials}` },36 });3738 if (!res.ok) throw new Error(`Mixpanel API error: ${res.status}`);39 const data = await res.json() as { data: { values: Record<string, Record<string, number>> } };40 const total = Object.values(data.data?.values?.[eventName] ?? {}).reduce(41 (sum, v) => sum + (v as number),42 043 );44 return { event: eventName, total };45 })46 );4748 return NextResponse.json({ results, period: { from, to } });49 } catch (error: unknown) {50 const e = error as { message: string };51 return NextResponse.json({ error: e.message }, { status: 500 });52 }53}Pro tip: Mixpanel's API has rate limits: 60 queries per hour on the free plan, 3,000 per hour on paid plans. For a dashboard that multiple team members refresh, add server-side caching (cache responses for 15-60 minutes) to avoid hitting rate limits.
Expected result: After deploying to Netlify and setting MIXPANEL_SERVICE_ACCOUNT_USERNAME, MIXPANEL_SERVICE_ACCOUNT_SECRET, and MIXPANEL_PROJECT_ID, GET /api/mixpanel/events returns event counts for the last 7 days. The MetricsDashboard component displays these totals.
Common use cases
Measure Feature Adoption Across Your User Base
You've shipped three new features in your Bolt app and want to know which one users actually adopted. Track a feature_used event with a featureName property every time a user accesses each feature. Use Mixpanel's Insights report to see adoption rates over time and segment by user cohorts (new vs. returning, free vs. paid) to understand who uses each feature most.
Add Mixpanel event tracking to my Bolt app's feature usage. Install mixpanel-browser. Initialize Mixpanel with VITE_MIXPANEL_TOKEN. Create a lib/mixpanel.ts file with a trackEvent function. When a user opens the AI assistant panel, call trackEvent('feature_used', { feature: 'ai_assistant', plan: userPlan }). When they use the export function, call trackEvent('feature_used', { feature: 'export', format: fileFormat }). When they invite a team member, call trackEvent('feature_used', { feature: 'team_invite' }).
Copy this prompt to try it in Bolt.new
Build an Onboarding Funnel and Identify Drop-off
Your Bolt app has a 5-step onboarding flow: create account, verify email, complete profile, connect integration, invite team. Track a step_completed event at each step with a stepNumber and stepName property. Use Mixpanel's Funnels report to see the conversion rate between each step and identify where most users abandon. This directly tells you where to focus onboarding improvements.
Track my onboarding funnel in Mixpanel. I have a 5-step onboarding wizard. At each step completion, call mixpanel.track('onboarding_step_completed', { step_number: 1, step_name: 'profile_created', time_spent_seconds: elapsed }). At the end of onboarding, track 'onboarding_completed' with total time taken. If a user skips onboarding, track 'onboarding_skipped' with the step they were on. Import mixpanel from lib/mixpanel.ts in my OnboardingWizard component.
Copy this prompt to try it in Bolt.new
Cohort Analysis: Compare Retained vs Churned Users
Use Mixpanel's Retention report to understand what separates users who come back from users who don't. Track a session_started event every time a user opens the app and a key_action_completed event when they do something valuable. Mixpanel's retention analysis shows the correlation between early actions and long-term retention — helping you identify the 'aha moment' that predicts user success.
Set up Mixpanel retention tracking in my app. Track 'app_opened' on every session start (when the app loads and the user is authenticated). Track 'key_action' with an actionType property whenever users complete high-value actions: 'first_project_created', 'first_export', 'team_member_invited'. These are the actions I think correlate with retention. Also make sure I'm calling mixpanel.identify() with the user's ID when they log in so retention analysis is per-user, not per-browser.
Copy this prompt to try it in Bolt.new
Troubleshooting
Events do not appear in Mixpanel Live Events even though mixpanel.track() is called
Cause: The Project Token may be incorrect, Mixpanel may not be initialized before track() is called, or an ad blocker is blocking requests to mixpanel.com.
Solution: Check the browser console for Mixpanel debug messages (add debug: true to init options). Verify VITE_MIXPANEL_TOKEN is set correctly in .env — the token is in Mixpanel Settings → Project Settings → Project Token. Disable browser extensions and try in an incognito window. Check Network tab for blocked requests to api.mixpanel.com.
1// Verify initialization before tracking:2mixpanel.init(TOKEN, { debug: true }); // enable debug logs3mixpanel.track('test_event', { source: 'bolt_preview' });4// Look for: 'mixpanel.track: test_event' in browser consoleTypeError: Cannot read properties of undefined (reading 'track') — mixpanel is undefined
Cause: mixpanel-browser is being imported in a Server Component or executed during SSR in a Next.js project. The package requires a browser environment (window, document, localStorage).
Solution: Ensure initMixpanel() is only called inside a useEffect hook for Next.js, and that track() checks the initialized flag before calling mixpanel methods. Never import mixpanel-browser in a Server Component. Use the 'use client' directive on any component that uses Mixpanel.
1// Add typeof check for SSR safety:2export function track(eventName: string, properties = {}) {3 if (typeof window === 'undefined') return; // skip during SSR4 if (!initialized) return;5 mixpanel.track(eventName, properties);6}Mixpanel shows two user profiles for the same person — one anonymous, one identified
Cause: identify() was called after some events were tracked. Mixpanel creates an anonymous profile for the pre-login events and a separate identified profile after the identify() call when the merging process is slow or fails.
Solution: Mixpanel automatically merges the anonymous and identified profiles when identify() is called — this process takes a few minutes and should resolve the duplicate. If duplicates persist, check that identify() is called with the same user ID on every login. Enable Mixpanel's Identity Merge (v3) in Project Settings → Identity Merge for more reliable merging.
Mixpanel API route returns 401 Unauthorized after deployment
Cause: Service account credentials are not set in the hosting platform's environment variables, or the service account does not have access to the Mixpanel project.
Solution: In Netlify: Site Settings → Environment Variables, add MIXPANEL_SERVICE_ACCOUNT_USERNAME, MIXPANEL_SERVICE_ACCOUNT_SECRET, and MIXPANEL_PROJECT_ID. Trigger a redeploy. Verify the service account in Mixpanel Settings → Service Accounts has at least Analyst access to the project.
Best practices
- Track business outcomes (project_created, checkout_completed, feature_enabled) rather than low-level UI interactions — Mixpanel's autocapture handles clicks; your custom events should represent what users accomplished
- Call mixpanel.identify() with your database user ID immediately after login, then mixpanel.reset() on logout to prevent cross-user event attribution
- Use mixpanel.register() to set super properties (plan, app_version, ab_test_variant) that are automatically appended to every event without repeating them in each track() call
- Create a centralized analytics.ts file that wraps mixpanel.track() with typed functions — this makes it easy to add Segment or Amplitude later without changing every component
- Keep Mixpanel Service Account credentials in server-side environment variables only — never use VITE_ or NEXT_PUBLIC_ prefixes for API secrets
- Use debug: import.meta.env.DEV during development to see each event logged to the browser console, then set debug: false in production to reduce console noise
- Design your event tracking plan before implementation: define the 5-10 most important events and their properties in a spreadsheet before writing code
Alternatives
Amplitude has a similar feature set to Mixpanel with a slightly more generous free tier (10M events/month) and is preferred by some teams for its session replay and chart-building UX.
Google Analytics 4 is better for traffic attribution and SEO analysis (which search queries drive signups) while Mixpanel excels at in-product behavior analysis — many apps use both.
Segment is a data pipeline that forwards events to Mixpanel (and 300 other tools) from a single SDK integration — use Segment if you want Mixpanel data and also want to send the same events to a data warehouse or other analytics tools.
FullStory provides qualitative session replay (watch what individual users do) while Mixpanel provides quantitative aggregates (how many users reached step 3 of the funnel) — they are complementary, not competing.
Frequently asked questions
Does mixpanel-browser work in Bolt.new's WebContainer preview?
Yes. mixpanel-browser sends data directly from the user's browser to Mixpanel's API servers over HTTPS — it does not go through the WebContainer's server runtime. This means the SDK works identically in the Bolt preview and in production. You can verify events in Mixpanel's Live Events feed immediately after adding the SDK.
What is the difference between Mixpanel Project Token and Service Account credentials?
The Project Token is a public write-only key used by the browser SDK to send events to your Mixpanel project — it is safe to include in client-side code as a VITE_ variable. Service Account credentials (username + secret) are used to read data from Mixpanel's Query API — they must be kept server-side only in environment variables without VITE_ or NEXT_PUBLIC_ prefixes.
How do I test Mixpanel in development without polluting my production analytics?
Create a separate Mixpanel project for development and use its Project Token in your .env file for local development. In production, use the production project's token. Alternatively, use Mixpanel's debug mode (debug: true in init options) which logs events to the console without sending them to Mixpanel. You can also use Mixpanel's development environment property to filter dev events out of production charts.
Can I use Mixpanel with a Vite (non-Next.js) Bolt project?
Yes. mixpanel-browser works identically in Vite React and Next.js Bolt projects for all client-side tracking. Use import.meta.env.VITE_MIXPANEL_TOKEN for the project token in Vite. For the Query API dashboard, you need a backend — either a Next.js project or a separate API service, since Vite projects don't have server-side API routes built in.
Does Mixpanel support GDPR and CCPA compliance for European users?
Yes. Mixpanel supports GDPR compliance via their EU residency option (data stored in EU), right-to-erasure API, and opt-out mechanisms. Call mixpanel.opt_out_tracking() to stop tracking a user who declines consent. For GDPR compliance, gate your initMixpanel() call behind a cookie consent banner and only initialize after the user accepts analytics cookies.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation