Перейти к основному содержимому

Клиентские библиотеки

Адаптеры фреймворков

Обёртка для React

Провайдер и два хука поверх SDK для 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 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));
}