@surveyanalytica/clickstream-web
v1.0.0
Published
SurveyAnalytica Clickstream SDK for web — captures behavioral events and sends them to SA workflow engine
Maintainers
Readme
@surveyanalytica/clickstream-web
SurveyAnalytica Clickstream SDK for web. Captures behavioral events (page views, custom events, identity transitions) and sends them to the SA workflow engine for real-time personalization and automation.
Installation
npm install @surveyanalytica/clickstream-webOr via CDN (UMD, no build step required):
<script src="https://unpkg.com/@surveyanalytica/clickstream-web/dist/index.umd.js"></script>Quick Start
Vanilla JavaScript
<script src="https://unpkg.com/@surveyanalytica/clickstream-web/dist/index.umd.js"></script>
<script>
SAClickstream.init("your-workflow-id", "your-api-key", {
saEndpoint: "https://api.surveyanalytica.com",
rootDomain: "yourdomain.com", // optional, enables cross-subdomain identity
});
// Track a custom event
SAClickstream.track("button_click", { buttonId: "cta-hero", plan: "pro" });
// Identify a known user after login
SAClickstream.identify("contact-uuid-from-your-system");
</script>Next.js / React
Initialize once at the app level (e.g. _app.js, layout.jsx, or a useEffect in your root component):
import SAClickstream from "@surveyanalytica/clickstream-web";
import { useEffect } from "react";
export default function App({ Component, pageProps }) {
useEffect(() => {
SAClickstream.init("your-workflow-id", "your-api-key", {
saEndpoint: process.env.NEXT_PUBLIC_SA_ENDPOINT,
rootDomain: "yourdomain.com",
// autoPage: false // set false if you want to call page() manually
});
}, []);
return <Component {...pageProps} />;
}Track events from any component:
import SAClickstream from "@surveyanalytica/clickstream-web";
function PricingButton() {
return (
<button
onClick={() =>
SAClickstream.track("pricing_click", { plan: "enterprise" })
}
>
Get Started
</button>
);
}Identify after login:
async function handleLogin(email, password) {
const user = await loginApi(email, password);
SAClickstream.identify(user.contactId);
}ES Module (bundler / Vite)
import SAClickstream from "@surveyanalytica/clickstream-web";
SAClickstream.init("wf_abc123", "key_xyz", {
saEndpoint: "https://api.surveyanalytica.com",
});
SAClickstream.track("page_load", { experiment: "variant-b" });CommonJS (Node.js / SSR)
const { SAClickstream } = require("@surveyanalytica/clickstream-web");
// All browser APIs are guarded — safe to import in SSR contexts.
// init() will no-op when window/document are unavailable.
SAClickstream.init("wf_abc123", "key_xyz", {
saEndpoint: "https://api.surveyanalytica.com",
});API Reference
| Method | Signature | Description |
|--------|-----------|-------------|
| init | init(workflowId, apiKey, options) | Initialize the SDK. Must be called before any other method. |
| track | track(event, properties?) | Track a custom event with optional properties. |
| page | page(properties?) | Track a page view. Called automatically on navigation unless autoPage: false. |
| identify | identify(contactId) | Associate the current visitor with a known contact ID. |
| setConsent | setConsent(given) | Grant (true) or revoke (false) tracking consent. |
init(workflowId, apiKey, options)
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| workflowId | string | Yes | SA workflow ID that receives clickstream events. |
| apiKey | string | Yes | SA API key, sent as the code request header. |
| options.saEndpoint | string | Yes | Base URL of your SA backend (e.g. https://api.surveyanalytica.com). |
| options.rootDomain | string | No | Root domain for cross-subdomain cookie sharing (e.g. "example.com"). Cookie is set as domain=.example.com. |
| options.autoPage | boolean | No | Auto-track page views via history.pushState / popstate. Defaults to true. |
Identity & uid_transition
The SDK assigns each visitor an anonymous UUID stored in both localStorage (sa_id) and a 1-year cookie (sa_id). When rootDomain is provided, the cookie is set with domain=.rootDomain so it is shared across all subdomains.
?sa_cid= URL parameter: If a URL contains ?sa_cid=<contactId> when init() is called (e.g. from a tracked email link), the SDK automatically emits a uid_transition event from the stored anonymous ID to the new contact ID, then stores the new ID.
identify(contactId): Call this after a user logs in. The SDK emits a uid_transition event from the current ID to the new one, stores the new ID, and immediately flushes any queued events.
uid_transition event shape:
{
"type": "uid_transition",
"oldId": "anon-uuid",
"newId": "contact-uuid",
"sessionId": "session-uuid",
"ts": "2026-05-20T10:00:00.000Z"
}Batching & Reliability
- Events are batched and flushed when the queue reaches 20 events or after a 500 ms debounce, whichever comes first.
- All fetches use
keepalive: trueso events are sent even when the user navigates away. - On failure, the SDK retries with exponential backoff: 1 s → 2 s → 4 s (3 attempts max). After 3 failures the batch is silently dropped.
identify()andsetConsent(false)flush immediately.
Consent / GDPR
Call setConsent(false) before init() or at any point to stop tracking:
SAClickstream.setConsent(false);This will:
- Emit a
consent_rejectedevent and flush it immediately. - Stop processing all future
track(),page(), andidentify()calls for the current session.
Re-enable tracking with setConsent(true).
Building from Source
git clone <repo>
cd clickstream-web
npm install
npm run build # outputs dist/index.esm.js, dist/index.cjs.js, dist/index.umd.jsLicense
MIT
