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
- A ClickStream account at einstein.clickstream.com with at least one site created.
- An API key (
cs_live_…orcs_test_…) minted from the dashboard. You paste the key once into thedata-keyattribute; no secrets leave the SDK bundle. - 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:
- In your Shopify admin, open Online Store → Themes → Customize, then the three-dot menu → Edit code.
- Open
layout/theme.liquid. - Paste the script tag in the
<head>block, using your tracking subdomain:
Register{% comment %} ClickStream first-party analytics {% endcomment %} <script src="https://t.{{ shop.permanent_domain }}/sdk.js" data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" async ></script>t.{shop}.myshopify.comin the dashboard the same way you would any other first-party hostname. - 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
- Open the dashboard, pick your site, and watch the Live Sessions panel.
- Load any page on your site in an incognito tab. You should see a session appear within 1–2 seconds.
- If nothing arrives after 30 seconds:
- Open DevTools → Network and filter for your tracking domain. Look for 200 responses on
/sdk.jsand/v1/events; a 403 means the Origin doesn't match your configured domains. - Confirm the API key in
data-keymatches the key shown in the dashboard. - Confirm the loading origin is listed in the site's Allowed Domains — wildcards like
*.example.comare supported. - Re-run
dig +short t.example.comand confirm the answer points at ClickStream (see First-party tracking for the expected value).
- Open DevTools → Network and filter for your tracking domain. Look for 200 responses on
Next steps
- First-party tracking (required) — end-to-end CNAME + SSL provisioning walkthrough.
- Signals API — read live scores from page code.
- Signals Feed (WebSocket) — real-time stream of every labeled event (Scale+).
- Event schema — exact shape of every event the SDK emits.
- API keys + auth — permission scopes + rotation.
- Rate limits — per-tier caps.