Install ClickStream

Every ClickStream tenant installs through its own first-party tracking domain. You add a CNAME on t.yourdomain.com → ClickStream, we verify it and provision SSL, then your SDK loads from your own hostname. We don't sell direct access to our collector or SDK CDN endpoints — first-party is the only supported mode.

This page assumes you've already run through the dashboard signup and DNS provisioning flow described in First-party tracking (required). If you haven't: do that first — the SDK's domain gate will reject events sent to a hostname that isn't registered to your API key.

What you need before you start

  1. A ClickStream account at einstein.clickstream.com with at least one site created.
  2. An API key (cs_live_… or cs_test_…) minted from the dashboard. You paste the key once into the data-key attribute; no secrets leave the SDK bundle.
  3. A first-party tracking subdomain (e.g. t.example.com) that's already verified and active in the dashboard. The green "Active" badge next to the hostname is the gate.

Script tag (recommended — all stacks)

Paste this into your site's <head>:

<script
  src="https://t.example.com/sdk.js"
  data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  async
></script>

Replace t.example.com with your registered tracking domain. The SDK loader is domain-scoped — the collector verifies the request origin against the domains configured for your API key and rejects mismatches. Put this tag on every page; the SDK handles SPA route changes internally.

That's it. Pageview / click / session events start flowing to the dashboard within seconds.

NPM / pnpm / yarn (modern bundlers)

For build-tool-managed apps, install the package and initialize once near your entry point:

pnpm add @clickstream/sdk
import { IdentityTracker } from '@clickstream/sdk';

const tracker = new IdentityTracker({
  apiKey: 'cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  endpoint: 'https://t.example.com', // your first-party tracking domain — required
});

await tracker.init();

tracker.trackEvent({ name: 'signup_started', category: 'conversion' });
await tracker.identify('user@example.com');

The endpoint option is mandatory for the NPM path. Point it at the same t.example.com hostname you use for the script-tag install — events sent to an unregistered hostname are rejected with 403 domain_not_allowed.

Exports: IdentityTracker (main class), COOKIE_NAMES, STORAGE_KEYS, and helper types. The SDK is tree-shakable; only the classes you import land in your bundle. The behavioral trackers (hover intent, clipboard, mouse dynamics, form-field intelligence, tab visibility, …) load via dynamic import() and only when the corresponding config flag is enabled.

Minimal core — 2 KB gzipped

If you want the smallest possible footprint and are willing to trade away identity resolution, session replay, consent banner, fingerprinting, and the 8 behavioral trackers, import from /core instead:

import { IdentityTrackerCore } from '@clickstream/sdk/core';

const tracker = new IdentityTrackerCore({
  apiKey: 'cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  endpoint: 'https://t.example.com',
});
tracker.init();
tracker.trackEvent({ name: 'signup_clicked' });

The trackEvent / trackPageview signatures are drop-in compatible with the full IdentityTracker, so moving up a tier is a one-line import change. Full reference: Core tracker.

React — @clickstream/react

pnpm add @clickstream/react @clickstream/signals
// app/providers.tsx (or similar root component)
'use client';

import { ClickStreamProvider } from '@clickstream/react';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ClickStreamProvider
      apiKey={process.env.NEXT_PUBLIC_CLICKSTREAM_KEY!}
      endpoint="https://t.example.com"
    >
      {children}
    </ClickStreamProvider>
  );
}
'use client';

import { useVisitor, useIdentify, useTrack } from '@clickstream/react';

export function SignupButton() {
  const visitor = useVisitor();
  const identify = useIdentify();
  const track = useTrack();

  const isHighIntent = (visitor?.scores.intent ?? 0) >= 70;

  return (
    <button
      onClick={async () => {
        track({ name: 'signup_clicked' });
        await identify('user@example.com');
      }}
    >
      {isHighIntent ? 'Start free trial' : 'Sign up'}
    </button>
  );
}

Full reference: React adapter.

Next.js (App Router) — @clickstream/next

Next.js apps get both the React provider for client components AND a server-side adapter for Server Components / Route Handlers / edge middleware.

pnpm add @clickstream/next @clickstream/react @clickstream/signals
// middleware.ts — optional edge prefetch of VisitorContext
import { clickStreamMiddleware } from '@clickstream/next/middleware';

export default clickStreamMiddleware({
  apiKey: process.env.CLICKSTREAM_API_KEY!,
  endpoint: 'https://t.example.com',
  prefetch: true,
});

export const config = { matcher: ['/pricing', '/cart', '/checkout/:path*'] };
// app/pricing/page.tsx — Server Component
import { getServerVisitor } from '@clickstream/next/server';

export default async function PricingPage() {
  const { visitor } = await getServerVisitor({
    apiKey: process.env.CLICKSTREAM_API_KEY!,
    endpoint: 'https://t.example.com',
  });
  if (visitor && visitor.scores.intent >= 70) return <HighIntentOffer />;
  return <DefaultPricing />;
}

Full reference: Next.js adapter.

Vue.js

Vue apps use the script-tag install — the browser SDK exposes window.Clickstream as a global. Wrap it in an idiomatic composable:

<!-- public/index.html -->
<script
  src="https://t.example.com/sdk.js"
  data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  async
></script>
// src/composables/useClickstream.ts
import { onMounted, ref } from 'vue';

export function useClickstream() {
  const tracker = ref<any>(null);
  onMounted(() => {
    const cs = (window as any).Clickstream;
    if (!cs?.tracker) {
      console.warn('[clickstream] SDK loader not yet ready');
      return;
    }
    tracker.value = cs.tracker;
  });
  return tracker;
}

Use tracker.value?.trackEvent({ name: 'signup' }) inside components. A dedicated @clickstream/vue adapter is on the roadmap.

Shopify

Online Store 2.0 stores use the Liquid theme editor:

  1. In your Shopify admin, open Online Store → Themes → Customize, then the three-dot menu → Edit code.
  2. Open layout/theme.liquid.
  3. Paste the script tag in the <head> block, using your tracking subdomain:
    {% comment %} ClickStream first-party analytics {% endcomment %}
    <script
      src="https://t.{{ shop.permanent_domain }}/sdk.js"
      data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      async
    ></script>
    
    Register t.{shop}.myshopify.com in the dashboard the same way you would any other first-party hostname.
  4. Save. Shopify deploys to live immediately.

Shopify App developers: install @clickstream/sdk in your app code and call tracker.init() inside the iframe's load hook. Pair with Shopify App Proxy for server-side order events; contact support for the signed-payload integration pattern.

Plain HTML (no bundler)

The script-tag install works as-is. If you need to reach the tracker from legacy inline handlers:

<script>
  window.addEventListener('clickstream:ready', (e) => {
    window.cs = e.detail.tracker;
  });
</script>
<script
  src="https://t.example.com/sdk.js"
  data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  async
></script>

<button onclick="cs?.trackEvent({ name: 'download_pressed' })">Download</button>

Verifying the install

  1. Open the dashboard, pick your site, and watch the Live Sessions panel.
  2. Load any page on your site in an incognito tab. You should see a session appear within 1–2 seconds.
  3. If nothing arrives after 30 seconds:
    • Open DevTools → Network and filter for your tracking domain. Look for 200 responses on /sdk.js and /v1/events; a 403 means the Origin doesn't match your configured domains.
    • Confirm the API key in data-key matches the key shown in the dashboard.
    • Confirm the loading origin is listed in the site's Allowed Domains — wildcards like *.example.com are supported.
    • Re-run dig +short t.example.com and confirm the answer points at ClickStream (see First-party tracking for the expected value).

Next steps