npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@surveyanalytica/clickstream-web

v1.0.0

Published

SurveyAnalytica Clickstream SDK for web — captures behavioral events and sends them to SA workflow engine

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-web

Or 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: true so 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() and setConsent(false) flush immediately.

Consent / GDPR

Call setConsent(false) before init() or at any point to stop tracking:

SAClickstream.setConsent(false);

This will:

  1. Emit a consent_rejected event and flush it immediately.
  2. Stop processing all future track(), page(), and identify() 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.js

License

MIT