React ラッパー
TypeScript SDK の上に載るプロバイダーと二つのフックです。ページごとにクライアントを一つだけ設置するため、React の Strict Mode でもイベントが二重になりません。
公開先
@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 API に二重のパッチが当たり、自動取得したイベントがすべて二重になるからです。
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 が変わるたびに再び呼び、SDK 自身の属性、すなわちアバター、メール、名前、電話を伴います。null は、その画面がセッションを確かめて誰もいなかったという意味です。プロバイダはクライアントがまだ識別済みである場合に限ってリセットし、それにより匿名 id が回るので、そのブラウザの次の訪問者はサインアウトした本人ではなくなります。サインアウトがハードナビゲーションで、値から 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 はそのページのクライアントを返します。サーバー上、エフェクトが走る前、プロバイダーの外では null です。useMessenger はウィジェットを開閉するハンドルを返し、プロジェクトの設定を読み込んで有効と分かるまでは null のままです。
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));
}