رفتن به محتوای اصلی

Next.js App Router

نصب SDK آلفانا در Next.js با Client Provider و ثبت navigationهای App Router.

در Next.js App Router، SDK آلفانا باید در Client Component اجرا شود؛ چون UserTrackerProvider و Hookهای SDK به محیط مرورگر و React Hookها نیاز دارند.

Provider را در سطحی پایدار از Application Tree قرار دهید تا Tracker فقط یک‌بار initialize شود و با هر Route دوباره ساخته نشود.

فقط credentialهای App که برای SDK مرورگر طراحی شده‌اند در متغیرهای NEXT_PUBLIC_ قرار می‌گیرند. Account API Key با پیشوند alphana_api_ نباید در Client یا متغیرهای عمومی قرار بگیرد.

ساخت Provider#

tsx
// app/providers.tsx

"use client";

import type { ReactNode } from "react";
import { UserTrackerProvider } from "alphana-sdk/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>
  );
}

Environment Variableها:

env
NEXT_PUBLIC_TRACKER_APP_ID=YOUR_APP_ID
NEXT_PUBLIC_TRACKER_SECRET=YOUR_APP_SECRET

این دو مقدار باید متعلق به همان Appی باشند که در داشبورد آلفانا ساخته‌اید.

اضافه کردن Provider به Layout#

tsx
// app/layout.tsx

import type { ReactNode } from "react";
import { Providers } from "./providers";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="fa">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

layout.tsx می‌تواند Server Component باقی بماند. فقط Componentی که Provider و Hookهای SDK را اجرا می‌کند باید "use client" داشته باشد.

ثبت Navigationهای Client-side#

در App Router، تغییر Route معمولاً بدون reload کامل صفحه انجام می‌شود. برای اینکه Pageviewها با مسیر واقعی کاربر هماهنگ بمانند، pathname فعلی را به usePageView() بدهید:

tsx
"use client";

import { usePathname } from "next/navigation";
import { usePageView } from "alphana-sdk/react";

export function NavigationTracker() {
  const pathname = usePathname();

  usePageView(pathname);

  return null;
}

هر بار که pathname تغییر کند، Pageview جدید ثبت می‌شود. این موضوع برای تحلیل Journey، Session و Attribution مهم است.

NavigationTracker باید داخل UserTrackerProvider Render شود:

tsx
// app/providers.tsx

"use client";

import type { ReactNode } from "react";
import { UserTrackerProvider } from "alphana-sdk/react";
import { NavigationTracker } from "./navigation-tracker";

export function Providers({ children }: { children: ReactNode }) {
  return (
    <UserTrackerProvider
      config={{
        appId: process.env.NEXT_PUBLIC_TRACKER_APP_ID!,
        secretKey: process.env.NEXT_PUBLIC_TRACKER_SECRET!,
      }}
    >
      <NavigationTracker />
      {children}
    </UserTrackerProvider>
  );
}

یک ساختار پیشنهادی:

text
app/
├── layout.tsx
├── providers.tsx
├── navigation-tracker.tsx
└── ...

استفاده از Hookهای آلفانا#

بعد از قرار گرفتن Provider در ریشه App، Client Componentهای زیر آن می‌توانند از Hookهای alphana-sdk/react استفاده کنند.

برای مثال، ثبت Goal بعد از تکمیل ثبت‌نام:

tsx
"use client";

import { useTrackGoal } from "alphana-sdk/react";

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

  return (
    <button
      onClick={() =>
        trackGoal({
          key: "signup_completed",
        })
      }
    >
      ادامه
    </button>
  );
}

همین الگو برای Revenue، Journey Step، Feature Flag و سایر APIهای React SDK قابل استفاده است.

فهرست کامل Hookها در React Hooks قرار دارد.

مرز Client و Server#

SDK آلفانا برای collection رفتار کاربر در مرورگر اجرا می‌شود. بنابراین UserTrackerProvider، usePageView() و سایر Hookهای SDK فقط باید در Client Componentها استفاده شوند.

Account API Key با پیشوند زیر:

text
alphana_api_...

نباید در متغیرهای:

text
NEXT_PUBLIC_

قرار بگیرد؛ چون Next.js آن‌ها را وارد JavaScript سمت Client می‌کند.

Credentialهای SDK:

env
NEXT_PUBLIC_TRACKER_APP_ID=...
NEXT_PUBLIC_TRACKER_SECRET=...

اما Account API Key باید فقط در Server نگهداری شود:

env
ALPHANA_API_KEY=alphana_api_...

و از Server Component، Route Handler، Server Action یا سایر بخش‌های امن سمت Server استفاده شود.

جلوگیری از initialize چندباره#

Provider را در Layout یا سطحی قرار دهید که هنگام Navigationهای عادی App Router unmount نشود.

اگر Provider داخل Page یا Componentی باشد که با هر Route عوض می‌شود، Tracker ممکن است چندبار ساخته شود یا lifecycle آن تکرار شود.

هدف این است که در طول Session یک instance پایدار از Tracker داشته باشید و فقط Pageviewها و Eventهای جدید روی همان instance ثبت شوند.

بررسی نصب#

بعد از راه‌اندازی Provider و Navigation Tracker، چند Route داخلی را بدون reload کامل باز کنید و Network مرورگر را بررسی کنید.

باید درخواست‌های collection SDK را ببینید:

text
POST /api/collect

همچنین با تغییر Route باید Pageview جدید ثبت شود. برای مثال:

text
/
/pricing
/signup
/dashboard

اگر فقط Pageview اولیه ثبت می‌شود، بررسی کنید که NavigationTracker داخل UserTrackerProvider باشد و مقدار usePathname() هنگام Navigation تغییر کند.