Интеграция Mixpanel аналитики на сайт
Mixpanel — event-based аналитика с фокусом на поведение пользователей, а не на страницы. Вместо просмотров считают события: кто нажал, когда, с какими свойствами. Сильные стороны — retention-анализ, воронки, A/B-отчёты, и возможность строить когортные отчёты без SQL.
Установка SDK
Два варианта: NPM-пакет для SPA или CDN-скрипт для классических сайтов.
NPM:
npm install mixpanel-browser
// src/analytics/mixpanel.ts
import mixpanel from 'mixpanel-browser';
mixpanel.init(import.meta.env.VITE_MIXPANEL_TOKEN, {
debug: import.meta.env.DEV,
track_pageview: false, // управляем вручную
persistence: 'localStorage',
ignore_dnt: false,
batch_requests: true,
batch_flush_interval_ms: 5000,
});
export default mixpanel;
CDN для классических сайтов:
<script>
(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].concat([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||[]);
mixpanel.init('YOUR_TOKEN');
</script>
Трекинг событий
Mixpanel строится на трёх примитивах: track, identify, people.set.
// Базовые события
mixpanel.track('Page Viewed', {
page_title: document.title,
page_url: window.location.pathname,
referrer: document.referrer || 'direct',
});
// Событие с деталями
mixpanel.track('Button Clicked', {
button_text: 'Оставить заявку',
button_location: 'hero_section',
page: window.location.pathname,
});
// Форма отправлена
mixpanel.track('Form Submitted', {
form_name: 'contact_form',
has_phone: true,
source_page: window.location.pathname,
});
// Электронная коммерция
mixpanel.track('Purchase Completed', {
order_id: 'ORDER-789',
revenue: 14500,
currency: 'RUB',
items_count: 3,
category: 'software',
});
Идентификация пользователей
Без identify каждый сеанс — анонимный пользователь. После логина или заполнения формы с email нужно связать анонимный профиль с реальным:
// После успешного логина
function onUserLoggedIn(user: { id: string; email: string; name: string; plan: string }) {
mixpanel.identify(user.id);
mixpanel.people.set({
$email: user.email,
$name: user.name,
plan: user.plan,
created_at: new Date().toISOString(),
});
// Дополнительные свойства, которые пойдут во все будущие события
mixpanel.register({
user_id: user.id,
user_plan: user.plan,
});
}
// Если пользователь заполнил форму без регистрации
function onLeadFormSubmitted(email: string) {
mixpanel.alias(email); // свяжет анонимный ID с email
mixpanel.people.set({ $email: email });
}
Суперпроперти и контекст
Суперпроперти автоматически добавляются к каждому последующему событию — удобно для A/B-вариантов, версии приложения, языка:
// Устанавливаем один раз при инициализации
mixpanel.register({
app_version: '2.4.1',
locale: navigator.language,
ab_variant: getABVariant(),
device_type: /Mobi/.test(navigator.userAgent) ? 'mobile' : 'desktop',
});
// register_once — не перезапишет, если уже установлено
mixpanel.register_once({
first_visit_date: new Date().toISOString(),
landing_page: window.location.pathname,
utm_source: new URLSearchParams(window.location.search).get('utm_source') ?? 'direct',
});
Интеграция с React Router
// hooks/useMixpanelPageview.ts
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import mixpanel from '@/analytics/mixpanel';
export function useMixpanelPageview() {
const location = useLocation();
useEffect(() => {
mixpanel.track('Page Viewed', {
page_path: location.pathname,
page_search: location.search,
page_hash: location.hash,
});
}, [location.pathname]);
}
Server-side трекинг
Для событий, которые происходят только на бэкенде (оплата через webhook, активация аккаунта по email), используется Mixpanel HTTP API:
// app/Services/MixpanelService.php
class MixpanelService
{
private string $token;
private string $endpoint = 'https://api.mixpanel.com/track';
public function __construct()
{
$this->token = config('services.mixpanel.token');
}
public function track(string $event, string $distinctId, array $properties = []): bool
{
$data = [
'event' => $event,
'properties' => array_merge($properties, [
'token' => $this->token,
'distinct_id' => $distinctId,
'time' => time(),
'$insert_id' => uniqid('srv_', true),
]),
];
$response = Http::asForm()->post($this->endpoint, [
'data' => base64_encode(json_encode([$data])),
]);
return $response->body() === '1';
}
public function setPeopleProperties(string $distinctId, array $properties): bool
{
$data = [
'$token' => $this->token,
'$distinct_id' => $distinctId,
'$set' => $properties,
];
$response = Http::asForm()->post('https://api.mixpanel.com/engage', [
'data' => base64_encode(json_encode([$data])),
]);
return $response->body() === '1';
}
}
Экспорт данных и Lookup Tables
Для join-а данных (например, добавить категорию товара к событиям покупки) Mixpanel поддерживает Lookup Tables:
# Загрузка lookup table через API
curl -X POST 'https://api.mixpanel.com/lookup-tables/v1/TABLE_ID' \
-H 'Authorization: Basic BASE64_ENCODED_SERVICE_ACCOUNT' \
-F '[email protected]'
CSV-формат:
id,category,brand,price_tier
SKU-001,software,acme,enterprise
SKU-002,hardware,techco,smb
Отладка
// Включить debug-режим вручную
mixpanel.set_config({ debug: true });
// В консоли появятся логи каждого track-вызова:
// [Mixpanel] Sending request: POST https://api.mixpanel.com/track/...
// [Mixpanel] Response: 1
// Проверка очереди событий до инициализации
console.log(window.mixpanel);
Расширение Mixpanel в Chrome DevTools показывает все события в реальном времени без дополнительной настройки.
Сроки
Установка SDK и базовый трекинг событий — 4–6 часов. Полная настройка identify/alias, суперпропертей, server-side событий — 1–2 дня. Настройка воронок и дашбордов в личном кабинете — 4–8 часов отдельно.







