مستندات فنی

راهنمای نصب و API آلفانا

نصب SDK، پیکربندی، React Hooks، Tracker API، فیچر فلگ، A/B تست و راهنمای رشد و رفتار — به ترتیب فهرست کنار صفحه.

معرفی

آلفانا یک SDK رهگیری رفتار برای React، Next.js، Vanilla JS و وردپرس است. ناوبری SPA، زمان حضور، heatmap (با فیلتر مسیر اختیاری)، لاگ‌های زمان اجرا، ضربان نشست، فیچر فلگ، A/B تست و سیگنال‌هایی مثل rage click و U-turn — بدون اسکریپت شخص ثالث.

پکیج npm: alphana-sdkورودی‌ها alphana-sdk و alphana-sdk/react.

نقشه حرارتی

کلیک، موس و اسکرول با نمونه‌برداری؛ burst کلیک (rage) برای نقاط گیر.

زمان حضور

جمع زمان به میلی‌ثانیه به ازای هر مسیر.

ناوبری SPA

pushState / replaceState / popstate و تشخیص ترک سریع صفحه (U-turn).

فیچر فلگ

ارزیابی سمت سرور با هدف‌گیری روی ویژگی‌های کاربر پس از identify().

لاگ و خطا

console و خطاهای سراسری با ارسال به /logs/ingest.

حریم خصوصی

بدون کوکی تحلیلگر شخص ثالث؛ شناسه بازدیدکننده در مرورگر.

نصب

آخرین نسخه روی npm (alphana-sdk) منتشر می‌شود. با هر package manager نصب کنید:

bash
# npm
npm install alphana-sdk

# pnpm
pnpm add alphana-sdk

# yarn
yarn add alphana-sdk

# bun
bun add alphana-sdk

نصب با Script / Google Tag Manager

اگر نمی‌خواهید پکیج npm نصب کنید، نسخه CDN را با یک تگ script در head یا GTM Custom HTML قرار دهید. SDK از روی data-app-id و data-secret-key خودش را مقداردهی و شروع می‌کند.

html
<script
  async
  src="https://storage.alphana.ir/cdn/alphana-sdk/latest/alphana-sdk.js"
  data-app-id="YOUR_APP_ID"
  data-secret-key="YOUR_SECRET_KEY"
></script>

برای GTM یک Custom HTML Tag بسازید، همین کد را قرار دهید و Trigger را روی All Pages بگذارید.

امنیت نصب مرورگر: درخواست‌های SDK با Bearer token، appId و دامنه ثبت‌شده اپ اعتبارسنجی می‌شوند. اگر کسی همین snippet را در سایت دیگری اجرا کند، Origin/Referer آن دامنه با دامنه اپ شما match نمی‌شود و backend درخواست را رد می‌کند.

React / Vite

UserTrackerProvider را یک بار دور کل اپ بپیچید، معمولاً در main.tsx.

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>
);
bash
# .env.local
VITE_TRACKER_APP_ID=your_app_id_here
VITE_TRACKER_SECRET=your_secret_key_here

Next.js App Router

چون UserTrackerProvider از hooks استفاده می‌کند، باید در یک Client Component باشد.

گام ۱ — ساخت Providers component

tsx
// 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

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>
  );
}

گام ۳ — متغیرهای محیطی

bash
# .env.local
NEXT_PUBLIC_TRACKER_APP_ID=your_app_id_here
NEXT_PUBLIC_TRACKER_SECRET=your_secret_key_here

گام ۴ — ردیابی مسیر در App Router

برای ثبت هر تغییر مسیر، usePageView(usePathname()) را در یک Client Component صدا بزنید (مثلاً داخل همان Providers یا layout).

tsx
// app/navigation-tracker.tsx
'use client';
import { usePathname } from 'next/navigation';
import { usePageView } from 'alphana-sdk/react';

export function NavigationTracker() {
  usePageView(usePathname());
  return null;
}
tsx
// در layout یا providers، بعد از UserTrackerProvider:
import { NavigationTracker } from './navigation-tracker';
// ...
<Providers>
  <NavigationTracker />
  {children}
</Providers>

Vanilla JS / TS

بدون هیچ فریم‌وری — فقط یک instance از UserTracker بسازید و init() صدا بزنید.

ts
import { UserTracker } from 'alphana-sdk';

const tracker = new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
});

// یک بار در شروع برنامه فراخوانی کنید
tracker.init();

// هنگام logout یا unmount
tracker.destroy();

وردپرس

برای سایت‌های وردپرس از افزونه Alphana Tracker استفاده کنید — بدون npm، فقط فایل ZIP و پنل مدیریت.

مراحل نصب

  1. در پیشخوان وردپرس: افزونه‌ها → افزودن → بارگذاری افزونه و فایل ZIP را انتخاب کنید؛ یا محتوای ZIP را در wp-content/plugins/alphana-tracker/ قرار دهید.
  2. افزونه را فعال کنید.
  3. به تنظیمات → Alphana Tracker بروید، App ID و Secret Key را از داشبورد آلفانا وارد کنید.
  4. گزینه فعال‌سازی رهگیری را علامت بزنید و ذخیره کنید. اسکریپت روی تمام صفحات عمومی سایت تزریق می‌شود.

تنظیمات کامل

تمام گزینه‌های قابل پاس دادن به TrackerConfig:

نامنوعتوضیح
appIdاجباریstringشناسه اپ از داشبورد آلفانا؛ برای کلود اجباری است.
secretKeyاجباریstringکلید SDK برای Bearer token. در مرورگر با appId و دامنه ثبت‌شده اعتبارسنجی می‌شود.
endpointstringآدرس رویدادها؛ پیش‌فرض https://api.alphana.ir/api/events. ارسال دسته‌ای: …/batch، ضربان: …/heartbeat.
sessionIdstringشناسه نشست ثابت؛ در غیر این صورت UUID خودکار.
trackNavigationbooleanردیابی pushState/replaceState/popstate و U-turn. پیش‌فرض: true
trackHeatmapbooleanheatmap + rage click. پیش‌فرض: true
trackTimebooleanزمان تجمعی به ازای هر مسیر. پیش‌فرض: true
heatmapPagesstring[]اگر پر شود، فقط این مسیرها heatmap می‌گیرند (مثل فهرست «Heatmap Pages» در پنل). خالی = همه مسیرها (محدودیت در سرور).
trackLogsbooleanconsole.info/warn/error، onerror، unhandledrejection → /logs/ingest. پیش‌فرض: true
mouseSampleRatenumber (0–1)درصد نمونه‌برداری رویداد موس/اسکرول. پیش‌فرض: 0.3
maxHeatmapPointsnumberحداکثر نقاط heatmap در حافظه به ازای هر مسیر. پیش‌فرض: 2000
batchSizenumberاندازه صف قبل از flush خودکار. پیش‌فرض: 20
flushIntervalnumber (ms)فاصله flush خودکار. پیش‌فرض: 5000
onEvent(event) => voidcallback هم‌زمان برای هر رویداد emit‌شده.

React Hooks

وقتی از alphana-sdk/react استفاده می‌کنید این hooks در دسترس هستند:

Hookخروجیتوضیح
useTracker()UserTracker | nullinstance tracker از context؛ بیرون از Provider برابر null است.
usePageView(path?)voidبا تغییر path، trackPageView را صدا می‌زند؛ بدون path کاری نمی‌کند (مثلاً فقط برای App Router).
usePageViews()PageView[]تمام pageview های session جاری.
useHeatmapData(path?, refreshMs?)HeatmapPoint[]نقاط heatmap برای مسیر؛ به‌روزرسانی با debounce (پیش‌فرض ۵۰۰ms).
useTimeSpent()Record<string, number>زمان تجمعی به میلی‌ثانیه به ازای هر مسیر.
useTrackRevenue()(payload) => voidتابع آماده برای ارسال purchase، subscription، renewal، upgrade یا refund از داخل React.
useTrackGoal()(payload) => voidتابع آماده برای ثبت هدف‌های تبدیل مثل signup_completed یا demo_requested.
useTrackJourneyStep()(payload) => voidتابع آماده برای ثبت milestoneهای محصول مثل onboarding_done یا plan_selected.
useFeatureFlags()Record<string, boolean>تمام فلگ‌های ارزیابی‌شده برای کاربر جاری. با هر بار identify() به‌روز می‌شود.
useFeatureFlagEnabled(key)booleantrue اگر فلگ مشخص‌شده برای کاربر جاری فعال باشد، در غیر این‌صورت false.

مثال

tsx
import { useTracker, useTimeSpent, useHeatmapData } from 'alphana-sdk/react';

export function DebugPanel() {
  const tracker = useTracker();
  const timeByPath = useTimeSpent(); // Record<path, ms>
  const points = useHeatmapData();

  if (!tracker) return null;

  return (
    <div>
      <p>مسیرهای با زمان ثبت‌شده: {Object.keys(timeByPath).length}</p>
      <p>نقاط heatmap (این صفحه): {points.length}</p>
      <button type="button" onClick={() => tracker.flush()}>ارسال فوری</button>
    </div>
  );
}

Tracker API

متدهای عمومی روی instance UserTracker:

متدتوضیح
init()شروع ردیابی. در SSR no-op است. مقدار this را برمی‌گرداند.
destroy()توقف listenerها و تایمرها؛ ارسال بهترین تلاش برای صف باقی‌مانده.
flush()ارسال فوری صف رویدادها به /batch (بدون await).
trackPageView(path?)ثبت دستی pageview برای مسیر داده‌شده یا مسیر جاری.
identify(props)ادغام ویژگی‌های کاربر برای هدف‌گیری فلگ؛ دوباره fetchFlags.
trackRevenue(payload)ثبت خرید، اشتراک، تمدید، ارتقا یا refund همراه با attribution فعلی.
trackGoal(payload)ثبت هدف تبدیل مثل signup_completed، lead یا trial_started.
trackJourneyStep(payload)ثبت milestone سفارشی در مسیر کاربر مثل onboarding_done.
getFlags() / isFeatureEnabled(key)خواندن فلگ‌های ارزیابی‌شده.
onFlagsChange(fn) / fetchFlags()اشتراک در تغییر فلگ یا درخواست مجدد ارزیابی.
subscribe(fn)subscriber رویداد؛ تابع unsubscribe برمی‌گرداند.
getSession()snapshot نشست (شامل visitorId).
getPageViews()تمام pageviewهای نشست جاری.
getTimeSpent()Record مسیر → میلی‌ثانیه تجمعی.
getHeatmapData(path?)با path: آرایه نقاط؛ بدون آرگومان: Record همه مسیرها.
ts
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();

فیچر فلگ — معرفی

فیچر فلگ (Feature Flag) به شما امکان می‌دهد بدون دیپلوی مجدد، قابلیت‌های مختلف را برای کاربران مختلف فعال یا غیرفعال کنید. SDK آلفانا این قابلیت را به صورت built-in ارائه می‌دهد.

بدون دیپلوی

فلگ را از داشبورد تغییر دهید — تغییر بلافاصله برای کاربران اعمال می‌شود.

هدف‌گیری دقیق

فلگ را بر اساس email، plan، country یا هر property دیگری هدف‌گیری کنید.

real-time

بعد از identify() فلگ‌ها بلافاصله دوباره ارزیابی می‌شوند.

kill switch

یک قابلیت مشکل‌دار را فوری غیرفعال کنید بدون نیاز به rollback.

پلن موردنیاز: فیچر فلگ فقط در پلن‌های حرفه‌ای، اقتصادی و ویژه در دسترس است.

ساخت فلگ در داشبورد

در داشبورد به بخش فیچر فلگ‌ها بروید و روی فلگ جدید کلیک کنید.

فیلدتوضیح
keyشناسه ماشینی فلگ — فقط حروف کوچک انگلیسی، اعداد، خط‌تیره یا زیرخط. مثال: new-checkout
descriptionتوضیح اختیاری برای یادآوری هدف فلگ.
فعال/غیرفعالوضعیت کلی فلگ. اگر غیرفعال باشد برای هیچ کاربری true نمی‌شود.
شرط‌های هدف‌گیریاختیاری. اگر تعریف شود، همه شرط‌ها باید برقرار باشند (AND). بدون شرط یعنی برای همه فعال است.

استفاده در SDK

React Hooks

ساده‌ترین روش — از hooks اختصاصی استفاده کنید:

tsx
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)، ابتدا کاربر را شناسایی کنید:

tsx
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,       // 'trial' | 'pro' | ...
        country: user.country, // 'IR' | 'US' | ...
      });
    }
  }, [user, tracker]);

  return <>{children}</>;
}

Vanilla JS

ts
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 است و فقط در پلن‌های زیر در دسترس است:

پلنفیچر فلگ
آزمایشی (۱۴ روز)✗ غیرفعال
پایه✗ غیرفعال
حرفه‌ای✓ فعال
اقتصادی✓ فعال
ویژه✓ فعال

A/B تست — معرفی

A/B تست به شما امکان می‌دهد چند نسخه از UI یا جریان کاربر (واریانت) را هم‌زمان اجرا کنید و نرخ تبدیل هر نسخه را با یک هدف تبدیل (Goal) مقایسه کنید. تخصیص واریانت از طریق API انجام می‌شود؛ رهگیری رفتار و محاسبه تبدیل با همان SDK آلفانا (pageview و کلیک) انجام می‌گیرد.

تخصیص پایدار

هر visitorId همیشه همان واریانت را می‌گیرد (hash قطعی).

وزن ترافیک

مثلاً ۵۰٪ کنترل و ۵۰٪ واریانت B — مجموع وزن‌ها باید ۱۰۰ باشد.

هدف تبدیل

بازدید صفحه یا کلیک روی المنت — مثل قیف تبدیل.

گزارش در داشبورد

شرکت‌کننده، تبدیل، نرخ و Uplift نسبت به واریانت کنترل.

جریان کار: (۱) آزمایش را در داشبورد بسازید و وضعیت را running کنید — (۲) SDK را با secretKey نصب و init() کنید — (۳) با useAbVariant / tracker.getAbVariant() UI را عوض کنید — (۴) رویدادهای کاربر برای محاسبه Goal ثبت می‌شوند.

Endpoint ارزیابی

http
POST https://api.alphana.ir/api/ab-tests/evaluate
Authorization: Bearer <APP_SECRET_KEY>
Origin: https://your-registered-domain.com
Content-Type: application/json

اگر endpoint ترکر را https://api.alphana.ir/api/events گذاشته‌اید، آدرس evaluate برابر است با: https://api.alphana.ir/api/ab-tests/evaluate

در مرورگر، backend علاوه بر Bearer token، دامنه Origin / Referer را با دامنه ثبت‌شده اپ تطبیق می‌دهد.

ساخت آزمایش در داشبورد

در داشبورد به A/B تست بروید و آزمایش جدید را بزنید.

فیلدتوضیح
keyشناسه SDK — فقط a-z، 0-9، خط‌تیره و زیرخط. مثال: checkout-cta-test
variants۲ تا ۸ واریانت؛ هر کدام key، نام و weight (٪). مجموع weight = 100
goalرویداد تبدیل: بازدید صفحه یا کلیک
statusdraft (پیش‌نویس) | running (فعال برای SDK) | paused
conversionWindowHoursپنجره زمانی پس از اولین رویداد کاربر برای شمارش تبدیل (پیش‌فرض ۱۶۸ ساعت)
countByvisitor (یکتا) یا session
مهم: تا وقتی وضعیت running نباشد، endpoint evaluate واریانت برنمی‌گرداند. اولین واریانت در لیست به‌عنوان کنترل برای محاسبه Uplift استفاده می‌شود.

A/B تست — Vanilla JS / TS

با secretKey در کانفیگ ترکر، SDK پس از init() به‌صورت خودکار واریانت‌ها را از /ab-tests/evaluate می‌گیرد.

ts
import { UserTracker } from 'alphana-sdk';

const tracker = new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
  endpoint: 'https://api.alphana.ir/api/events',
}).init();

tracker.onAbTestsChange((variants) => {
  const variant = variants['checkout-cta-test'];
  const cta = document.getElementById('cta')!;
  if (variant === 'variant-b') {
    cta.className = 'btn-blue';
    cta.textContent = 'خرید الان';
  } else {
    cta.className = 'btn-green';
    cta.textContent = 'ادامه خرید';
  }
});

async function runCheckoutExperiment() {
  await tracker.fetchAbTests(['checkout-cta-test']);
  if (tracker.isAbVariant('checkout-cta-test', 'variant-b')) {
    document.getElementById('cta')!.className = 'btn-blue';
  } else {
    document.getElementById('cta')!.className = 'btn-green';
  }
}

void runCheckoutExperiment();
نکته: تخصیص بر اساس visitorId نشست ثابت می‌ماند. درخواست‌های مرورگر با secret، appId و دامنه ثبت‌شده اپ کنترل می‌شوند؛ با این حال اگر کلید را جایی عمومی paste کرده‌اید، آن را rotate کنید.

A/B تست — React / Vite

مثل Feature Flagها از hookهای آماده SDK استفاده کنید — نیازی به fetch دستی نیست.

tsx
// main.tsx — Provider مثل بخش Feature Flag
import { UserTrackerProvider } from 'alphana-sdk/react';

<UserTrackerProvider
  config={{
    appId: import.meta.env.VITE_TRACKER_APP_ID,
    secretKey: import.meta.env.VITE_TRACKER_SECRET,
    endpoint: 'https://api.alphana.ir/api/events',
  }}
>
  <App />
</UserTrackerProvider>
tsx
// components/CheckoutCta.tsx
import {
  useAbVariant,
  useIsAbVariant,
  useAbTests,
} from 'alphana-sdk/react';

export function CheckoutCta() {
  const variant = useAbVariant('checkout-cta-test');
  const isVariantB = useIsAbVariant('checkout-cta-test', 'variant-b');

  // variant === null تا زمان بارگذاری اول evaluate
  if (variant == null) {
    return <button className="btn-skeleton">...</button>;
  }

  if (isVariantB) {
    return <button className="btn-blue">خرید الان</button>;
  }
  return <button className="btn-green">ادامه خرید</button>;
}

// همه واریانت‌ها:
function DebugPanel() {
  const variants = useAbTests();
  return <pre>{JSON.stringify(variants, null, 2)}</pre>;
}
bash
# .env.local (فقط برای توسعه — secret را در کلاینت production نگذارید)
VITE_TRACKER_APP_ID=your_app_id
VITE_TRACKER_SECRET=your_secret_key_here

A/B تست — Next.js App Router

در Client Component از همان hookهای React SDK استفاده کنید.UserTrackerProvider را در layout قرار دهید.

گام ۱ — Provider در layout

tsx
// app/providers.tsx
'use client';
import { UserTrackerProvider } from 'alphana-sdk/react';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <UserTrackerProvider
      config={{
        appId: process.env.NEXT_PUBLIC_TRACKER_APP_ID!,
        secretKey: process.env.NEXT_PUBLIC_TRACKER_SECRET!,
        endpoint: 'https://api.alphana.ir/api/events',
      }}
    >
      {children}
    </UserTrackerProvider>
  );
}

گام ۲ — Client Component

tsx
'use client';
import { useAbVariant, useIsAbVariant } from 'alphana-sdk/react';

export function CheckoutCta() {
  const variant = useAbVariant('checkout-cta-test');
  const isVariantB = useIsAbVariant('checkout-cta-test', 'variant-b');

  if (variant == null) {
    return <button className="btn-skeleton">...</button>;
  }

  if (isVariantB) {
    return <button className="btn-blue">خرید الان</button>;
  }
  return <button className="btn-green">ادامه خرید</button>;
}
bash
# .env.local
NEXT_PUBLIC_TRACKER_APP_ID=your_app_id
NEXT_PUBLIC_TRACKER_SECRET=your_secret_key
Production: نصب مستقیم مرورگر با appId، secret و دامنه ثبت‌شده guard می‌شود. اگر مدل امنیتی سخت‌گیرانه‌تری می‌خواهید، می‌توانید endpoint ترکر را به یک Route Handler داخلی که رویدادها و evaluate را پروکسی می‌کند اشاره دهید.

pageview و کلیک‌ها برای Goal از همان ترکر ثبت می‌شوند — آزمایش را در داشبورد با Goal رویداد (مثلاً click روی دکمه CTA) تعریف کنید.

هدف تبدیل (Goal)

تبدیل از روی داده‌های نشست (همان رویدادهای SDK) محاسبه می‌شود؛ نیازی به فراخوانی جداگانه «conversion» نیست. Goal باید با رفتار واقعی کاربران هم‌خوان باشد.

نوع Goalفیلدهامثال
page_viewpath + pathMatchمسیر /order/complete با contains
clickelementLabel + labelMatch (+ path اختیاری)کلیک روی دکمه با label «پرداخت»

pathMatch

مقدارمعنی
containsمسیر شامل رشته باشد
exactمسیر دقیقاً برابر
starts_withمسیر با پیشوند شروع شود
regexتطابق عبارت منظم
کیفیت داده: برای page_view از usePageView در SPA/Next استفاده کنید تا مسیرها درست ثبت شوند. برای click، label المنت (مثلاً متن دکمه یا data-attribute) باید با elementLabel در Goal هم‌خوان باشد.

پلن‌های پشتیبانی‌کننده

A/B تست در پلن‌های زیر فعال است (محدودیت تعداد آزمایش در داشبورد):

پلنA/B تستحداکثر آزمایش
آزمایشی (۱۴ روز)✗ غیرفعال
پایه✗ غیرفعال
حرفه‌ای✓ فعال۱۰
اقتصادی✓ فعال۳۰
ویژه✓ فعالنامحدود

Growth Analytics — معرفی

قابلیت‌های رشد آلفانا روی همان نصب SDK ساخته می‌شوند. SDK به صورت خودکار pageview، referrer، UTM و click idها را ثبت می‌کند؛ تیم شما فقط باید کاربران را با identify() شناسایی کند و رویدادهای درآمدی را با trackRevenue() ارسال کند.

UTM

تحلیل source، medium، campaign، term، content و click idها برای هر نشست.

Attribution

نگهداری first-touch و last-touch برای نسبت دادن تبدیل و درآمد به کانال‌ها.

Revenue

ثبت خرید، اشتراک، تمدید، ارتقا و refund کنار رفتار کاربر.

Segments

ساخت گروه‌های پویا از کاربران بر اساس رفتار، کمپین، کشور، پلن یا ویژگی‌ها.

Cohorts

دیدن عملکرد گروه‌های زمانی کاربران و مقایسه رشد، بازگشت یا ریزش.

اصل مهم: برای گزارش‌های دقیق، لینک‌های کمپین باید UTM استاندارد داشته باشند، کاربر بعد از ورود شناسایی شود و درآمد با transactionId یکتا ثبت شود.

UTM و Attribution

وقتی کاربر با لینک کمپین وارد سایت می‌شود، SDK پارامترهای UTM و click idها را از URL می‌خواند و به عنوان touchpoint ذخیره می‌کند. اولین touchpoint برای first-touch نگه داشته می‌شود و آخرین touchpoint برای last-touch به‌روزرسانی می‌شود.

لینک استاندارد کمپین

text
https://example.com/pricing?utm_source=google&utm_medium=cpc&utm_campaign=spring_sale&utm_content=hero_cta&utm_term=analytics

تیم مارکتینگ باید این پارامترها را در تمام لینک‌های تبلیغاتی، ایمیل‌ها، شبکه‌های اجتماعی و همکاری‌های affiliate استفاده کند:

پارامترکاربرد
utm_sourceمنبع ترافیک مثل google، instagram، newsletter
utm_mediumنوع کانال مثل cpc، organic، email، referral
utm_campaignنام کمپین یا launch
utm_termکلمه کلیدی یا audience هدف
utm_contentنسخه خلاقه، جایگاه لینک یا CTA
gclid / fbclid / ttclid / msclkidشناسه کلیک پلتفرم‌های تبلیغاتی

کاری که تیم فنی باید انجام دهد

برای UTM و Attribution، نصب معمول SDK کافی است. اگر از Next.js App Router استفاده می‌کنید، حتماً usePageView() را طبق بخش Next.js فعال کنید تا تغییر مسیرهای SPA هم ثبت شوند.

Revenue — ثبت درآمد و تبدیل

گزارش Revenue زمانی دقیق می‌شود که بعد از پرداخت موفق، تمدید، ارتقای پلن یا refund، یک رویداد درآمدی ارسال کنید. این رویداد به first-touch و last-touch کاربر وصل می‌شود تا درآمد هر کمپین مشخص شود.

Vanilla JS / TS

ts
import { UserTracker } from 'alphana-sdk';

const tracker = new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
}).init();

// بعد از پرداخت موفق در checkout یا callback سمت کلاینت
tracker.trackRevenue({
  eventName: 'purchase',
  transactionId: 'order_12345',
  orderId: 'order_12345',
  amount: 1490000,
  currency: 'IRR',
  productId: 'pro-plan',
  planId: 'pro',
  coupon: 'SPRING20',
  status: 'paid',
  items: [
    { id: 'pro-plan', name: 'Pro Plan', quantity: 1, price: 1490000 },
  ],
  metadata: {
    billingPeriod: 'monthly',
  },
});

React

tsx
import { useTrackRevenue } from 'alphana-sdk/react';

export function PaymentSuccess({ order }: { order: Order }) {
  const trackRevenue = useTrackRevenue();

  useEffect(() => {
    trackRevenue({
      eventName: 'subscription',
      transactionId: order.id,
      amount: order.amount,
      currency: order.currency,
      planId: order.planSlug,
      status: 'paid',
    });
  }, [order, trackRevenue]);

  return <p>پرداخت با موفقیت انجام شد.</p>;
}
نکته برای تیم بک‌اند: اگر پرداخت فقط در سرور تأیید می‌شود، transactionId و مبلغ را از سرور به صفحه success منتقل کنید یا یک endpoint امن برای ارسال رویداد revenue در سمت سرور بسازید. transactionId باید یکتا باشد تا رویداد تکراری شمرده نشود.

Segments و Cohorts

سگمنت‌ها و کوهورت‌ها در داشبورد از داده‌هایی ساخته می‌شوند که SDK جمع‌آوری می‌کند: نشست‌ها، UTM، کشور، دستگاه، صفحات دیده‌شده، درآمد و ویژگی‌های کاربر. برای اینکه این بخش‌ها واقعاً مفید شوند، باید بعد از login یا signup کاربر را شناسایی کنید.

شناسایی کاربر و ویژگی‌های هدف‌گیری

ts
tracker.identify({
  id: user.id,
  email: user.email,
  plan: user.plan,          // trial | pro | enterprise
  role: user.role,          // admin | member
  country: user.country,    // IR | DE | ...
  companySize: user.companySize,
});

بعد از این مرحله می‌توانید در داشبورد سگمنت‌هایی مثل «کاربران پلن pro از Google Ads»، «کاربران ایران»، «کاربران newsletter که خرید نکرده‌اند» یا «کاربران دارای revenue» بسازید.

کوهورت‌ها چطور کار می‌کنند؟

کوهورت‌ها کاربران را بر اساس زمان اولین مشاهده، signup یا purchase گروه‌بندی می‌کنند. سپس می‌توانید ببینید هر گروه در هفته‌ها یا ماه‌های بعد چه تعداد نشست، بازگشت یا درآمد ایجاد کرده است.

چک‌لیست استفاده برای تیم‌ها

تیمکار لازم
EngineeringSDK را نصب کند، appId/secretKey را تنظیم کند، identify و trackRevenue را در نقاط درست صدا بزند.
Marketingبرای همه کمپین‌ها UTM استاندارد و نام‌گذاری ثابت تعریف کند.
Productسگمنت‌ها، کوهورت‌ها و conversionهای مهم را مشخص کند.
Data / Growthمدل attribution، بازه گزارش‌گیری و تعریف revenue/refund را با تیم‌ها هماهنگ کند.
QAبا یک لینک UTM تستی وارد شود، login کند، پرداخت تستی بزند و داشبورد UTM/Revenue/Attribution را بررسی کند.
text
QA flow:
1. Open /?utm_source=qa&utm_medium=test&utm_campaign=growth_docs
2. Sign up or log in
3. Call tracker.identify({...})
4. Complete a test purchase
5. Verify Dashboard → UTM, Revenue, Attribution, Segments, Cohorts

Behavior Analytics — معرفی

بخش Behavior برای پاسخ به سه سؤال اصلی ساخته شده است: کاربران چه هدف‌هایی را کامل می‌کنند، از چه مسیرهایی عبور می‌کنند و آیا دوباره برمی‌گردند یا نه. Pageview و visitorId به صورت خودکار ثبت می‌شوند؛ تیم فنی فقط باید هدف‌ها و milestoneهای مهم را نام‌گذاری و ارسال کند.

Goals

رویدادهای تبدیل مثل signup، lead، trial_start یا activation.

Journeys

صفحات ورود، انتقال بین صفحات و milestoneهای سفارشی محصول.

Retention

بازگشت کاربران در نشست‌های بعدی بر اساس visitorId و identify.

Goals — ثبت هدف‌های تبدیل

Goal یعنی یک نتیجه مهم برای کسب‌وکار یا محصول؛ مثل ثبت‌نام کامل، ارسال فرم دمو، شروع trial، افزودن به سبد یا تکمیل onboarding. تیم محصول ابتدا goal key را در داشبورد، صفحه Goals تعریف می‌کند؛ سپس تیم فنی همان key را در SDK ارسال می‌کند.

ts
tracker.trackGoal({
  key: 'signup_completed',
  name: 'Signup completed',
  value: 1,
  metadata: {
    source: 'pricing_page',
  },
});
tsx
import { useTrackGoal } from 'alphana-sdk/react';

export function SignupSuccess() {
  const trackGoal = useTrackGoal();

  useEffect(() => {
    trackGoal({ key: 'signup_completed', name: 'Signup completed' });
  }, [trackGoal]);

  return <p>ثبت‌نام کامل شد.</p>;
}
پیشنهاد نام‌گذاری: کلید goal را ثابت، انگلیسی و snake_case نگه دارید؛ مثل demo_requested یا trial_started.

Journeys — مسیر کاربران

آلفانا مسیر کاربران را از pageviewهای خودکار می‌سازد. اگر در محصول milestoneهایی دارید که الزاماً تغییر URL ندارند، آن‌ها را با trackJourneyStep() ثبت کنید.

ts
tracker.trackJourneyStep({
  key: 'plan_selected',
  label: 'Plan selected',
  metadata: {
    plan: 'pro',
  },
});

برای SPAها و Next.js App Router، طبق بخش نصب Next.js مطمئن شوید کهusePageView() روی تغییر مسیرها اجرا می‌شود؛ در غیر این صورت journey فقط اولین pageview را دارد.

Retention — بازگشت کاربران

Retention از نشست‌های تکراری یک visitor ساخته می‌شود. SDK به صورت خودکار visitorId را در مرورگر نگه می‌دارد، اما برای دقت بیشتر بین دستگاه‌ها یا بعد از login، حتماً identify() را صدا بزنید.

ts
tracker.identify({
  id: user.id,
  email: user.email,
  plan: user.plan,
});

تیم محصول باید بازه تحلیل را مشخص کند: retention روزانه برای محصول‌های پرتکرار، هفتگی برای SaaS و ماهانه برای خریدهای با فاصله بیشتر مناسب‌تر است.