غلاف React
مزوّد وخطّافان فوق حزمة TypeScript. يثبّت عميلًا واحدًا لكل صفحة، فلا يضاعف وضع React الصارم أحداثك.
مكان النشر
@prodantix/react on npm. It wraps @prodantix/sdk, so install both.
التثبيت
bun add @prodantix/sdk @prodantix/react| Export | What it is |
|---|---|
| ProdantixProvider | Creates the client once per page and provides it |
| useProdantix | The client for the page, or null |
| useMessenger | A handle that opens and closes the widget, or null |
| prodantixConfig | The config when both key and host are present, else null |
| skipReason | Why this mount will send nothing, or null |
| resetProdantixForTest | Clears the once-per-page install, for tests |
المزوّد
ركّب ProdantixProvider مرة واحدة قرب الجذر. ينشئ عميل الويب عند أول تركيب ثم يعيد استخدامه، لأن إنشاء عميل ثانٍ سيرقّع واجهة History مرتين ويضاعف كل حدث ملتقط تلقائيًا.
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>
);تسمية الشخص الذي سجّل الدخول
يخبر person المزوّدَ بمن سجّل الدخول، كخاصية لا كاستدعاء، فيصل الدخول والخروج إلى العميل كما هما من قيم. وله ثلاث حالات، كل واحدة تقول شيئًا مختلفًا. فـ undefined تعني أن هذه الواجهة لا تعرف بعد، لأن المصادقة ما زالت تتحمّل، فلا يفعل المزوّد شيئًا. ووجود قيمة يعني التعريف: يستدعي المزوّد identify عند أول قيمة، ويعيد الاستدعاء كلما تغيّر distinctId، حاملًا سمات المكتبة نفسها، أي الصورة والبريد والاسم والهاتف. أما null فتعني أن الواجهة سألت الجلسة فلم تجد أحدًا، فيعيد المزوّد ضبط العميل إن كان، وإن كان فقط، ما يزال معرَّفًا، وهو ما يدوّر المعرّف المجهول حتى لا يكون الزائر التالي على ذلك المتصفح هو الشخص الذي خرج. وهذه القاعدة هي ما يجعل الخروج يثبت حيث يكون الخروج تنقّلًا كاملًا ولا يُعرض فيه أبدًا انتقال من قيمة إلى null. وهي أيضًا سبب ألا تعني null أبدًا حالة التحميل: فشخص مسجَّل يعيد تحميل الصفحة كان سيُعاد ضبطه قبل أن تتحمّل المصادقة. أما الواجهة التي لا تسأل أي جلسة، كصفحة تسويقية أو صفحة توثيق، فتمرّر undefined، والخاصية الغائبة تُقرأ أصلًا على أنها undefined.
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 مقبضًا لفتح الأداة وإغلاقها، ويبقى فارغًا حتى تُقرأ إعدادات المشروع وتقول إنه مفعّل.
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 في سطر واحد لماذا لن يرسل هذا التركيب شيئًا، بدل العودة صامتًا.
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));
}