Web (multi-package)
@sankofa/pulse
Behavior-triggered surveys rendered in-app. Trigger evaluation, custom rendering, and lifecycle event listeners for the web.
@sankofa/pulse runs the survey logic for the Pulse product in the browser. It evaluates triggers, manages eligibility, and exposes a PulseClient that your UI uses to show / dismiss surveys and listen for lifecycle events.
Rendering is your responsibility — the package ships the SurveyRenderer and SurveyState types so you can build a survey UI in React, plain HTML, or any framework. The companion @sankofa/react package ships a <SurveyModal> component that handles the most common case.
Install
npm install @sankofa/pulseRegister the plugin
import { Sankofa } from "@sankofa/browser";
import { pulsePlugin, getPulse } from "@sankofa/pulse";
Sankofa.init({
apiKey: "sk_live_...",
endpoint: "https://api.sankofa.dev",
plugins: [pulsePlugin()],
});
const pulse = getPulse()!;Show a survey
await pulse.show("srv_post_purchase_feedback");
// Programmatic dismiss
pulse.dismiss();Listen for lifecycle events
const unsubscribe = pulse.on("completed", (event) => {
console.log("Survey", event.surveyId, "completed");
});
// Lifecycle events: "shown", "completed", "dismissed"Bundle change events
When the engine publishes a new survey configuration, the SDK refetches eligibility. Listen for those updates:
const unsubscribe = pulse.onBundleChange((bundle) => {
console.log("Pulse bundle updated", bundle.surveys.length, "surveys");
});Rendering
The package exposes the SurveyRenderer interface and SurveyState type for custom UIs. The simplest path on the web is to use the React companion:
import { SurveyModal } from "@sankofa/react";
function App() {
return (
<>
{/* your app */}
<SurveyModal />
</>
);
}<SurveyModal> consumes the getPulse() client and renders the active survey. Style it via CSS variables that match Sankofa's brand.
Eligibility context
For surveys gated on user-state predicates not visible to the SDK (e.g. internal staff role), set additional context:
pulse.setContext({
tenantId: "acme",
plan: "pro",
userRole: "admin",
});The next handshake includes this context in the request, so cohort matching can include it.
API summary
| Symbol | Description |
|---|---|
pulsePlugin(options?) | Plugin to register at Sankofa.init. |
getPulse() | Returns the singleton Pulse client. |
pulse.show(surveyId, options?) | Show a survey. |
pulse.dismiss() | Dismiss the active survey. |
pulse.on(event, listener) | Subscribe to lifecycle events ("shown", "completed", "dismissed"). |
pulse.onBundleChange(listener) | Subscribe to bundle updates. |
pulse.setContext(ctx) | Set additional eligibility context. |
PulseClient (type) | The client interface. |
SurveyRenderer (type) | Interface for custom survey UIs. |
SurveyState (type) | The active survey state shape. |