معرفی
آلفانا یک SDK رهگیری رفتار کاربران برای اپلیکیشنهای React، Next.js و Vanilla JS است. تمام دادهها — ناوبری، زمان حضور، نقشه حرارتی و لاگها — بدون کوکی و بدون شخص ثالث جمعآوری میشوند.
رکورد کلیک، موس و اسکرول با نمونهبرداری قابل تنظیم.
اندازهگیری دقیق time-on-page به ازای هر مسیر.
ردیابی خودکار pushState و popstate بدون نیاز به کد اضافه.
ارسال full-page screenshot هر ۵ دقیقه برای heatmap overlay.
جمعآوری console.error، onerror و unhandledrejection.
بدون کوکی، بدون ذخیره IP، سازگار با GDPR.
نصب
پکیج را با هر package manager که استفاده میکنید نصب کنید:
# npm
npm install alphana-sdk
# pnpm
pnpm add alphana-sdk
# yarn
yarn add alphana-sdk
# bun
bun add alphana-sdkReact / Vite
UserTrackerProvider را یک بار دور کل اپ بپیچید، معمولاً در main.tsx.
// main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { UserTrackerProvider } from 'alphana-sdk/react';
import App from './App';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<UserTrackerProvider
config={{
appId: import.meta.env.VITE_TRACKER_APP_ID,
secretKey: import.meta.env.VITE_TRACKER_SECRET,
}}
>
<App />
</UserTrackerProvider>
</StrictMode>
);# .env.local
VITE_TRACKER_APP_ID=your_app_id_here
VITE_TRACKER_SECRET=your_secret_key_hereNext.js App Router
چون UserTrackerProvider از hooks استفاده میکند، باید در یک Client Component باشد.
گام ۱ — ساخت Providers component
// app/providers.tsx
'use client';
import { UserTrackerProvider } from 'alphana-sdk/react';
import type { ReactNode } from 'react';
export function Providers({ children }: { children: ReactNode }) {
return (
<UserTrackerProvider
config={{
appId: process.env.NEXT_PUBLIC_TRACKER_APP_ID!,
secretKey: process.env.NEXT_PUBLIC_TRACKER_SECRET!,
}}
>
{children}
</UserTrackerProvider>
);
}گام ۲ — استفاده در layout.tsx
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="fa" dir="rtl">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}گام ۳ — متغیرهای محیطی
# .env.local
NEXT_PUBLIC_TRACKER_APP_ID=your_app_id_here
NEXT_PUBLIC_TRACKER_SECRET=your_secret_key_hereVanilla JS / TS
بدون هیچ فریموری — فقط یک instance از UserTracker بسازید و init() صدا بزنید.
import { UserTracker } from 'alphana-sdk';
const tracker = new UserTracker({
appId: 'YOUR_APP_ID',
secretKey: 'YOUR_SECRET_KEY',
});
// یک بار در شروع برنامه فراخوانی کنید
tracker.init();
// هنگام logout یا unmount
tracker.destroy();تنظیمات کامل
تمام گزینههای قابل پاس دادن به TrackerConfig:
| نام | نوع | توضیح |
|---|---|---|
appIdاجباری | string | شناسه اپ از داشبورد آلفانا. |
secretKeyاجباری | string | کلید مخفی SDK — به عنوان Bearer token ارسال میشود. |
endpoint | string | آدرس API. فقط در خودمیزبانی تغییر دهید. پیشفرض: https://api.alphana.ir/api/events |
trackNavigation | boolean | ردیابی تغییر مسیر SPA. پیشفرض: true |
trackHeatmap | boolean | جمعآوری داده موس/کلیک/اسکرول. پیشفرض: true |
trackTime | boolean | اندازهگیری زمان حضور در هر صفحه. پیشفرض: true |
trackLogs | boolean | گرفتن console.error و window.onerror. پیشفرض: true |
trackSnapshots | boolean | ارسال اسکرینشات صفحه هر ۵ دقیقه. نیاز به `html2canvas`. پیشفرض: true |
snapshotIntervalMs | number (ms) | فاصله زمانی بین اسکرینشاتها. پیشفرض: 300000 (۵ دقیقه) |
mouseSampleRate | number (0–1) | درصد نمونهبرداری رویداد موس. پیشفرض: 0.3 |
maxHeatmapPoints | number | حداکثر نقاط heatmap در حافظه. پیشفرض: 2000 |
batchSize | number | اندازه batch قبل از flush خودکار. پیشفرض: 20 |
flushInterval | number (ms) | فاصله flush خودکار به میلیثانیه. پیشفرض: 5000 |
onEvent | (event) => void | callback برای هر رویداد emitشده. |
خودمیزبانی
تمام کد بکاند، داشبورد، و این landing page در GitHub موجود است. برای راهاندازی:
گام ۱ — Clone و تنظیم متغیرها
git clone https://github.com/teokamalipour/alphana-sdk.git
cd alphana-sdk
cp .env.example .env
# سپس .env را با مقادیر واقعی ویرایش کنیدگام ۲ — اجرا با Docker Compose
docker compose up -dاین دستور MongoDB، بکاند NestJS و داشبورد React را راهاندازی میکند.
گام ۳ — تغییر endpoint در SDK
new UserTracker({
appId: 'YOUR_APP_ID',
secretKey: 'YOUR_SECRET_KEY',
// آدرس سرور خودتان را اینجا بگذارید
endpoint: 'https://your-server.com/api/events',
})React Hooks
وقتی از alphana-sdk/react استفاده میکنید این hooks در دسترس هستند:
| Hook | خروجی | توضیح |
|---|---|---|
useTracker() | UserTracker | دسترسی به instance اصلی tracker. |
usePageView() | PageView | null | داده pageview صفحه جاری. |
usePageViews() | PageView[] | تمام pageview های session جاری. |
useHeatmapData() | HeatmapPoint[] | نقاط heatmap صفحه جاری. |
useTimeSpent() | number (s) | زمان حضور در صفحه جاری (ثانیه). |
useFeatureFlags() | Record<string, boolean> | تمام فلگهای ارزیابیشده برای کاربر جاری. با هر بار identify() بهروز میشود. |
useFeatureFlagEnabled(key) | boolean | true اگر فلگ مشخصشده برای کاربر جاری فعال باشد، در غیر اینصورت false. |
مثال
import { useTracker, useTimeSpent, useHeatmapData } from 'alphana-sdk/react';
export function DebugPanel() {
const tracker = useTracker();
const timeSpent = useTimeSpent(); // ثانیه
const points = useHeatmapData(); // HeatmapPoint[]
return (
<div>
<p>زمان حضور: {timeSpent}s</p>
<p>نقاط heatmap: {points.length}</p>
<button onClick={() => tracker.flush()}>ارسال فوری</button>
</div>
);
}فیچر فلگ — معرفی
فیچر فلگ (Feature Flag) به شما امکان میدهد بدون دیپلوی مجدد، قابلیتهای مختلف را برای کاربران مختلف فعال یا غیرفعال کنید. SDK آلفانا این قابلیت را به صورت built-in ارائه میدهد.
فلگ را از داشبورد تغییر دهید — تغییر بلافاصله برای کاربران اعمال میشود.
فلگ را بر اساس email، plan، country یا هر property دیگری هدفگیری کنید.
بعد از identify() فلگها بلافاصله دوباره ارزیابی میشوند.
یک قابلیت مشکلدار را فوری غیرفعال کنید بدون نیاز به rollback.
ساخت فلگ در داشبورد
در داشبورد به بخش فیچر فلگها بروید و روی فلگ جدید کلیک کنید.
| فیلد | توضیح |
|---|---|
key | شناسه ماشینی فلگ — فقط حروف کوچک انگلیسی، اعداد، خطتیره یا زیرخط. مثال: new-checkout |
description | توضیح اختیاری برای یادآوری هدف فلگ. |
فعال/غیرفعال | وضعیت کلی فلگ. اگر غیرفعال باشد برای هیچ کاربری true نمیشود. |
شرطهای هدفگیری | اختیاری. اگر تعریف شود، همه شرطها باید برقرار باشند (AND). بدون شرط یعنی برای همه فعال است. |
استفاده در SDK
React Hooks
سادهترین روش — از hooks اختصاصی استفاده کنید:
import {
useFeatureFlagEnabled,
useFeatureFlags,
} from 'alphana-sdk/react';
// بررسی یک فلگ خاص
function CheckoutButton() {
const showNewCheckout = useFeatureFlagEnabled('new-checkout');
if (showNewCheckout) {
return <NewCheckout />;
}
return <OldCheckout />;
}
// دریافت همه فلگها
function DebugFlags() {
const flags = useFeatureFlags();
// { 'new-checkout': true, 'promo-banner': false, ... }
return <pre>{JSON.stringify(flags, null, 2)}</pre>;
}شناسایی کاربر
برای استفاده از شرطهای هدفگیری (مثل email یا plan)، ابتدا کاربر را شناسایی کنید:
import { useTracker } from 'alphana-sdk/react';
function AuthWrapper({ user }) {
const tracker = useTracker();
useEffect(() => {
if (user && tracker) {
// properties به عنوان شرطهای هدفگیری استفاده میشوند
tracker.identify({
email: user.email,
plan: user.plan, // 'free' | 'pro' | ...
country: user.country, // 'IR' | 'US' | ...
});
}
}, [user, tracker]);
return <>{children}</>;
}Vanilla JS
const tracker = new UserTracker({
appId: 'YOUR_APP_ID',
secretKey: 'YOUR_SECRET_KEY',
}).init();
// شناسایی کاربر
tracker.identify({ email: 'user@example.com', plan: 'pro' });
// بررسی فلگ
if (tracker.isFeatureEnabled('new-checkout')) {
showNewCheckout();
}
// گوش دادن به تغییرات فلگ
const unsub = tracker.onFlagsChange((flags) => {
console.log('flags updated:', flags);
});
// دریافت همه فلگها
const allFlags = tracker.getFlags();
// { 'new-checkout': true, 'promo-banner': false }شرطهای هدفگیری
هر فلگ میتواند یک یا چند شرط داشته باشد. تمام شرطها باید برقرار باشند (AND). اگر شرطی تعریف نشود، فلگ برای همه فعال است.
| operator | توضیح | مثال |
|---|---|---|
equals | مقدار دقیقاً برابر باشد (case-insensitive) | email equals user@example.com |
contains | مقدار شامل رشته مشخصشده باشد | email contains @mycompany.com |
is_in | مقدار در لیست جداشده با کاما باشد | plan is_in pro,economy,special |
userProperties که از طریق tracker.identify({...}) ارسال میکنید ارزیابی میشوند. اگر identify() فراخوانی نشده باشد، تمام شرطها به عنوان عدم تطابق در نظر گرفته میشوند.پلنهای پشتیبانیکننده
فیچر فلگ یک قابلیت premium است و فقط در پلنهای زیر در دسترس است:
| پلن | فیچر فلگ |
|---|---|
| رایگان | ✗ غیرفعال |
| پایه | ✗ غیرفعال |
| حرفهای | ✓ فعال |
| اقتصادی | ✓ فعال |
| ویژه | ✓ فعال |
Tracker API
متدهای عمومی روی instance UserTracker:
| متد | توضیح |
|---|---|
init() | شروع ردیابی. در SSR no-op است. مقدار this را برمیگرداند. |
destroy() | توقف تمام event listenerها و timerها و ارسال رویدادهای باقیمانده. |
flush() | ارسال فوری تمام رویدادها از صف. |
trackPageView(path?) | ثبت دستی یک pageview برای مسیر مشخص (یا مسیر جاری). |
subscribe(fn) | اضافه کردن subscriber. تابع unsubscribe را برمیگرداند. |
getSession() | اطلاعات session جاری. |
getPageViews() | تمام pageviewهای session جاری. |
getHeatmapData(path?) | نقاط heatmap برای یک مسیر یا تمام مسیرها. |
import { UserTracker } from 'alphana-sdk';
const tracker = new UserTracker({ appId: 'id', secretKey: 'key' });
// گوش دادن به رویدادها
تراکرمستقیم آغاز کنید
const unsubscribe = tracker.subscribe((event) => {
console.log(event.type, event);
});
tracker.init();
// هر جا که نیاز به ارسال فوری دارید
tracker.flush();
// لغو اشتراک
// unsubscribe();