Lewati ke konten utama

SDK TypeScript

Satu paket dengan enam titik masuk. Impor yang sesuai dengan runtime Anda, dan build dengan tree shaking meninggalkan sisanya di luar bundel Anda.

Tempat diterbitkan

@prodantix/sdk on npm.

Instal

Bash
bun add @prodantix/sdk

Titik masuk

Setiap subpath menyertakan build ESM dan CommonJS sendiri beserta tipenya sendiri. Root bersifat netral terhadap runtime, dan sisanya menambahkan apa yang dibutuhkan satu runtime tertentu.

SubpathWhat it exports
@prodantix/sdkProdantixClient, createClient, evaluateFlag, FlagsClient, MessagesClient
@prodantix/sdk/webcreateWebClient, installAutocapture, installLinkCarry, installSessionReplay, WebTransport
@prodantix/sdk/nodecreateNodeClient, readSharedIdentity
@prodantix/sdk/cspprodantixConnectSrc, prodantixImgSrc, prodantixScriptSrc
@prodantix/sdk/chatmountChat, ChatClient, ChatPanel, resolveAppearance
@prodantix/sdk/messengerfetchMessengerConfig, cachedMessengerConfig, MESSENGER_CACHE_KEY

@prodantix/sdk

Klien, pengevaluasi flag, serta antarmuka penyimpanan dan transport. Tidak ada di sini yang menyentuh DOM, jadi Anda bisa memasok penyimpanan, transport, jam, atau pabrik id sendiri dan menjalankannya di mana saja.

TypeScript
import { createClient, MemoryStorage } from '@prodantix/sdk';

const prodantix = createClient({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.api.prodantix.com',
  storage: new MemoryStorage(),
});

prodantix.capture('order.completed', { properties: { amount: 4200, currency: 'XAF' } });
await prodantix.flush();

@prodantix/sdk/web

Perkabelan peramban di atas klien yang sama: penyimpanan di local storage, pengiriman lewat beacon saat halaman disembunyikan, serta autocapture pageview dan klik. Session replay tetap mati sampai Anda memberinya host replay.

TypeScript
import { createWebClient } from '@prodantix/sdk/web';

const prodantix = createWebClient({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.api.prodantix.com',
  flagsHost: 'https://api.prodantix.com',
  cookieDomain: 'example.com',
  autocaptureOptions: { clicks: true, pageviews: true },
});

prodantix.identify('user-42', { set: { plan: 'pro' } });

if (await prodantix.isFeatureEnabled('new-checkout')) {
  // ...
}

// Every per-flag read records one $feature_flag_called exposure.
const variant = await prodantix.getVariant('new-checkout');
if (variant?.key === 'treatment') {
  // ...
}

// A flag targeting a cohort reads this user's memberships from the store;
// pass them yourself to skip the lookup.
if (await prodantix.isFeatureEnabledLocal('members', { cohorts: ['<cohort id>'] })) {
  // ...
}

Di web, id anonim dan sesi pengunjung tersimpan dalam satu cookie pihak pertama di domain terdaftar Anda, sehingga xyz.com, app.xyz.com, dan console.xyz.com melihat satu orang yang sama: kunjungan pemasaran, pendaftaran, dan sesi pertama di aplikasi jatuh pada garis waktu yang sama begitu aplikasi mengidentifikasinya. Id yang teridentifikasi tetap per origin di local storage dan tidak pernah masuk ke cookie, karena setiap host di bawah domain itu dapat membacanya. Domain ditemukan dengan bertanya kepada peramban, atau ditetapkan lewat cookieDomain; situs yang subdomainnya milik tenant berbeda harus menetapkannya ke host-nya sendiri. Berikan sharedStorage agar tidak menulis cookie sama sekali, misalnya sampai persetujuan diberikan, dan local storage tetap menjadi cadangan saat cookie ditolak. Satu id sesi dibuat per kunjungan, diganti setelah tiga puluh menit tidak aktif atau dua puluh empat jam, dicap pada setiap event, dan dibagikan dengan session replay.

Cookie tidak dapat melintasi domain terdaftar, jadi pengunjung yang mengikuti tautan dari satu situs ke situs lain akan menjadi dua pengunjung. Berikan linkedDomains, yang secara bawaan kosong, dan klien akan menghias tautan keluar ke domain tersebut, pada click dan auxclick, dengan parameter _pdx yang membawa tiga hal: id anonim, id sesi, dan saat sesi dimulai, sehingga jendela tiga puluh menit dan batas dua puluh empat jam tetap berlanjut melewati lompatan itu. Hanya id anonim yang ikut, tidak pernah id yang teridentifikasi, karena tujuannya sendiri yang mengidentifikasi orang itu. Tautan ke domain terdaftar yang sama, tautan yang sudah membawa _pdx, serta tautan mailto, tel, javascript dan tautan tanda pagar semuanya dibiarkan utuh. Setibanya, createWebClient membaca _pdx sebelum identitas dibangun, menuliskan id dan sesi yang dibawa ke penyimpanan bersama, lalu melepas parameter itu dengan history.replaceState sehingga ia tidak muncul di $current_url dan tidak ikut melaju; parameter yang tiga bagiannya tidak terbaca diabaikan dan alamatnya dibiarkan apa adanya. Jika host ini sudah memegang id anonim lain, klien mengirim $create_alias sehingga apa yang tercatat sebelumnya terlipat ke dalam id yang dibawa; dan host yang sudah mengidentifikasi seseorang tetap menyimpan orang itu: id yang dibawa menjadi id anonimnya, tidak pernah distinct id-nya.

TypeScript
import { createWebClient } from '@prodantix/sdk/web';

const prodantix = createWebClient({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.api.prodantix.com',
  linkedDomains: ['example.com', 'example-app.com'],
});

// A link to example-app.com now leaves as
// https://example-app.com/pricing?_pdx=<anonymousId>~<sessionId>~<startedAt>
// and the arriving page adopts it before it builds an identity of its own.

// The visitor's answer, from your own consent banner.
prodantix.setConsent({ identityLink: false });
prodantix.consent(); // { identityLink: false }

Jawaban pengunjung sendiri tentang penggabungan itu menumpang penyimpanan bersama yang sama, di bawah pdx..consent, sehingga setiap subdomain dan server yang membaca cookie melihat satu jawaban. Catat dengan setConsent({ identityLink: false }), baca kembali dengan consent(), dan semaikan lewat opsi consent bila aplikasi Anda sudah memegang jawabannya: spanduk persetujuan adalah milik Anda untuk dibuat, dan prodantix menghormati apa yang dikumpulkannya. Selama identityLink bernilai false, identify tidak mengirim id anonim untuk digabungkan ke orang tersebut, dan tautan ke domain yang terdaftar dibiarkan tanpa hiasan, sebab membawa id menyeberang adalah penggabungan yang sama lewat jalan lain. Tidak disetel atau true mengizinkan keduanya, tunduk pada pengaturan proyek itu sendiri di konsol, yang ditegakkan oleh state worker dan bukan oleh apa pun yang dikirim peramban. Mengubah jawaban berlaku pada identify berikutnya dan klik berikutnya; tidak ada yang sudah tergabung menjadi terurai.

@prodantix/sdk/node

Klien yang sama dengan bawaan sisi server. Event disangga lalu dikirim di latar belakang, jadi panggil shutdown sebelum proses berakhir atau batch terakhir tidak akan pernah terkirim.

TypeScript
import { createNodeClient } from '@prodantix/sdk/node';

// A node client streams flag changes over Socket.IO by default and refetches
// the snapshot on push; streamFlags: false leaves only the 30s poll.
const prodantix = createNodeClient({
  apiKey: process.env.PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.api.prodantix.com',
  streamFlags: true,
});

prodantix.capture('job.completed', { properties: { queue: 'emails' } });
await prodantix.shutdown();

Proses masuk yang berakhir dengan pengalihan di sisi server tidak menggambar halaman apa pun, sehingga identify milik peramban tidak pernah berjalan di sana. readSharedIdentity(cookieHeader, apiKey) membaca cookie yang ditulis klien web dan menjawab dengan id anonim, sesi tempatnya berada, serta persetujuan pengunjung, atau null bila cookie tidak ada atau bukan milik SDK ini. Lalu link(distinctId, anonymousId, traits) mengirim satu $identify yang seharusnya dikirim peramban, untuk id yang diberikan, tanpa menyentuh identitas klien ini sendiri. Login Bomdisoft memanggil keduanya saat proses masuk selesai, di dalam satu fungsi yang sudah dipanggil oleh kedelapan titik masuknya: di sanalah subject orang itu pertama kali diketahui di server sementara cookie masih menempel pada permintaan. Enam dari titik itu adalah server action tanpa objek permintaan, itulah sebabnya fungsi ini menerima string header cookie dan bukan sebuah permintaan. Lewati link bila jawaban yang terbaca adalah identityLink false.

TypeScript
import { createNodeClient, readSharedIdentity } from '@prodantix/sdk/node';

const prodantix = createNodeClient({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.api.prodantix.com',
});

// At sign-in completion, where the person is known and the browser's
// cookie is still on the request.
export const completeSignIn = (sub: string, cookieHeader: string): void => {
  const shared = readSharedIdentity(cookieHeader, PRODANTIX_PUBLIC_KEY);
  if (shared !== null && shared.consent?.identityLink !== false) {
    prodantix.link(sub, shared.anonymousId);
  }
};

@prodantix/sdk/csp

Sumber content security policy yang dibutuhkan sebuah aplikasi untuk menjangkau Prodantix. Modul ini tidak mengimpor apa pun dari React maupun peramban, sehingga berkas konfigurasi build bisa membacanya langsung.

TypeScript
import { prodantixConnectSrc, prodantixImgSrc, prodantixScriptSrc } from '@prodantix/sdk/csp';

const hosts = {
  ingest: 'https://eu.api.prodantix.com',
  edge: 'https://eu.edge.prodantix.com',
  replay: 'https://eu.replay.prodantix.com',
};

const policy = [
  `connect-src ${prodantixConnectSrc(hosts)}`,
  `script-src ${prodantixScriptSrc(hosts)}`,
  `img-src ${prodantixImgSrc(hosts, ["'self'", 'data:'])}`,
].join('; ');

Widget dukungan menampilkan foto tim Anda dari edge dan menggambar berkas yang dikirim pengunjung dari alamat blob:, jadi img-src pada kebijakan membutuhkan keduanya. prodantixImgSrc menambahkannya ke sumber gambar yang sudah Anda izinkan. Tanpa keduanya, peramban memblokir gambar tersebut dan hanya memberitahukannya di konsolnya sendiri.

@prodantix/sdk/chat

Widget dukungan. Pasang, dan Anda mendapat handle yang membuka, menutup, memusnahkan, serta mengidentifikasi pengguna. Ia dirender di dalam shadow root tertutup, sehingga gaya halaman induk tidak pernah menjangkaunya.

TypeScript
import { mountChat } from '@prodantix/sdk/chat';

const messenger = mountChat({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.edge.prodantix.com',
  distinctId: prodantix.distinctId,
});

document.querySelector('#help')?.addEventListener('click', () => messenger.open());

Setiap pesan pengunjung membawa tempat pesan itu ditulis. Panel membaca location dan document.title pada saat pengiriman lalu mengirim host, path, dan title, dengan path berupa pathname saja: tidak pernah kueri dan tidak pernah fragmen, karena tautan reset, tautan ajaib, atau kepulangan dari checkout membawa tokennya di sana, dan kotak masuk agen bukan tempatnya. Panel tidak menggambar satu pun dari itu, sehingga utas pengunjung tetap berisi kata-katanya sendiri, dan jawaban edge kembali ke SDK juga menghilangkannya, sehingga halaman yang membaca utasnya sendiri tidak dapat melihat apa yang dilihat konsol. Tempat ia terlihat adalah kotak masuk, sebagai satu baris redup di bawah pesan masuk.

@prodantix/sdk/messenger

Pembaca pengaturan di balik widget: ia mengambil konfigurasi messenger sebuah proyek, menyimpannya di cache, dan melaporkan apakah proyek itu mengaktifkan messenger. Cuplikan yang berjalan sendiri dibangun terpisah dan tidak dapat dijangkau lewat subpath ini.

TypeScript
import { fetchMessengerConfig } from '@prodantix/sdk/messenger';

const config = await fetchMessengerConfig({
  apiKey: PRODANTIX_PUBLIC_KEY,
  host: 'https://eu.edge.prodantix.com',
});

if (config?.enabled) {
  // the project has the messenger switched on
}