تخطَّ إلى المحتوى الرئيسي

محوّلات أطر العمل

غلاف React

مزوّد وخطّافان فوق حزمة TypeScript. يثبّت عميلًا واحدًا لكل صفحة، فلا يضاعف وضع React الصارم أحداثك.

مكان النشر

@prodantix/react on npm. It wraps @prodantix/sdk, so install both.

التثبيت

Bash
bun add @prodantix/sdk @prodantix/react
ExportWhat it is
ProdantixProviderCreates the client once per page and provides it
useProdantixThe client for the page, or null
useMessengerA handle that opens and closes the widget, or null
prodantixConfigThe config when both key and host are present, else null
skipReasonWhy this mount will send nothing, or null
resetProdantixForTestClears the once-per-page install, for tests

المزوّد

ركّب ProdantixProvider مرة واحدة قرب الجذر. ينشئ عميل الويب عند أول تركيب ثم يعيد استخدامه، لأن إنشاء عميل ثانٍ سيرقّع واجهة History مرتين ويضاعف كل حدث ملتقط تلقائيًا.

TypeScript
import { ProdantixProvider } from '@prodantix/react';

export const Providers = ({ children }: { children: ReactNode }) => (
  <ProdantixProvider
    options={{
      apiKey: process.env.NEXT_PUBLIC_PRODANTIX_KEY,
      host: 'https://eu.api.prodantix.com',
      messengerHost: 'https://eu.edge.prodantix.com',
    }}
  >
    {children}
  </ProdantixProvider>
);
لا يظهر المراسل إلا إذا مرّرت messengerHost وكان المشروع قد فعّله من لوحة التحكم. وبلا إعدادات ولا نسخة مخزّنة لا يُرسم شيء، لأن مشغّلًا افتراضيًا سيكون تخمينًا مرسومًا على صفحة عميل.

تسمية الشخص الذي سجّل الدخول

يخبر person المزوّدَ بمن سجّل الدخول، كخاصية لا كاستدعاء، فيصل الدخول والخروج إلى العميل كما هما من قيم. وله ثلاث حالات، كل واحدة تقول شيئًا مختلفًا. فـ undefined تعني أن هذه الواجهة لا تعرف بعد، لأن المصادقة ما زالت تتحمّل، فلا يفعل المزوّد شيئًا. ووجود قيمة يعني التعريف: يستدعي المزوّد identify عند أول قيمة، ويعيد الاستدعاء كلما تغيّر distinctId، حاملًا سمات المكتبة نفسها، أي الصورة والبريد والاسم والهاتف. أما null فتعني أن الواجهة سألت الجلسة فلم تجد أحدًا، فيعيد المزوّد ضبط العميل إن كان، وإن كان فقط، ما يزال معرَّفًا، وهو ما يدوّر المعرّف المجهول حتى لا يكون الزائر التالي على ذلك المتصفح هو الشخص الذي خرج. وهذه القاعدة هي ما يجعل الخروج يثبت حيث يكون الخروج تنقّلًا كاملًا ولا يُعرض فيه أبدًا انتقال من قيمة إلى null. وهي أيضًا سبب ألا تعني null أبدًا حالة التحميل: فشخص مسجَّل يعيد تحميل الصفحة كان سيُعاد ضبطه قبل أن تتحمّل المصادقة. أما الواجهة التي لا تسأل أي جلسة، كصفحة تسويقية أو صفحة توثيق، فتمرّر undefined، والخاصية الغائبة تُقرأ أصلًا على أنها undefined.

TypeScript
import { ProdantixProvider } from '@prodantix/react';

export const Providers = ({ children }: { children: ReactNode }) => {
  const { session, status } = useSession();

  // undefined while auth hydrates, null once it has resolved to nobody,
  // the subject once it has resolved to someone.
  const person = status === 'loading' ? undefined : session ? { distinctId: session.sub } : null;

  return (
    <ProdantixProvider
      options={{
        apiKey: process.env.NEXT_PUBLIC_PRODANTIX_KEY,
        host: 'https://eu.api.prodantix.com',
        person,
      }}
    >
      {children}
    </ProdantixProvider>
  );
};

الخطّافان

يعيد useProdantix عميل الصفحة، أو قيمة فارغة على الخادم وقبل تنفيذ التأثير وخارج المزوّد. ويعطي useMessenger مقبضًا لفتح الأداة وإغلاقها، ويبقى فارغًا حتى تُقرأ إعدادات المشروع وتقول إنه مفعّل.

TypeScript
import { useMessenger, useProdantix } from '@prodantix/react';

export const HelpButton = () => {
  const prodantix = useProdantix();
  const messenger = useMessenger();

  // Both are null until the provider effect has run, so neither is assumed.
  return (
    <button
      onClick={() => {
        prodantix?.capture('help.opened');
        messenger?.open();
      }}
      type="button"
    >
      Get help
    </button>
  );
};

حين لا يرسل شيئًا

التطبيق يُشحن كما هو حتى مع تعطيل Prodantix، فغياب المفتاح أو المضيف ليس خطأ. يخبرك prodantixConfig إن كانت القيمتان موجودتين، ويقول skipReason في سطر واحد لماذا لن يرسل هذا التركيب شيئًا، بدل العودة صامتًا.

TypeScript
import { prodantixConfig, skipReason } from '@prodantix/react';

const env = {
  host: process.env.NEXT_PUBLIC_PRODANTIX_HOST,
  key: process.env.NEXT_PUBLIC_PRODANTIX_KEY,
};

// null when either value is missing: the app runs with Prodantix switched off.
if (prodantixConfig(env) === null) {
  console.warn(skipReason(env, null));
}