メインコンテンツへスキップ

クライアントライブラリ

フレームワークアダプター

React ラッパー

TypeScript SDK の上に載るプロバイダーと二つのフックです。ページごとにクライアントを一つだけ設置するため、React の Strict Mode でもイベントが二重になりません。

公開先

@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 API に二重のパッチが当たり、自動取得したイベントがすべて二重になるからです。

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

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