First-party tracking (required)
First-party tracking is mandatory. Every ClickStream install runs through a CNAME on your own domain (t.example.com) that we provision with SSL and route to our collector. We do not support direct public use of the collector or SDK CDN hostnames — every event you send and every bundle you load MUST go through a domain your tenant has registered and verified.
Why it matters in practice:
- Ad blockers cannot pattern-match a unique subdomain under your own brand. You recover the ~20–40 % of events most operators lose to EasyList and similar rules.
- Safari ITP doesn't clamp first-party cookies to 7 days. Your visitor identity persists at the browser's long-term maximum (~400 days).
- Corporate firewalls don't block the hostname because it looks like any other request to your own backend.
- Domain reputation stays with you — not a multi-tenant analytics vendor.
The setup is three steps, all guided by the dashboard:
- Add a CNAME record:
t.yourdomain.com→ ClickStream's collector. - Register the hostname in the dashboard. Our control plane polls DNS, provisions SSL via Cloudflare for SaaS, and flips the hostname to Active when the cert is live.
- Point the SDK at the new domain via the
data-keyscript tag or theendpointoption.
Step 1 — DNS CNAME
Add this record to your DNS provider's zone for your domain:
| Field | Value |
|---|---|
| Type | CNAME |
| Name | t (or analytics, data, tracking — whatever you prefer) |
| Target | the CNAME target shown in the dashboard when you start provisioning (copy it exactly) |
| TTL | Auto (or 3600) |
| Proxy | DNS-only on Cloudflare — "gray cloud", not "orange cloud" |
You do not point the CNAME at any ClickStream-owned hostname directly. The dashboard's provisioning flow gives you the correct Cloudflare for SaaS CNAME target for your tenant; paste it exactly.
Per-provider steps
Every provider's DNS UI is slightly different. The record itself is identical: a CNAME with the dashboard-supplied target, DNS-only on Cloudflare.
Cloudflare
- Cloudflare dashboard → your domain → DNS → Records.
- Add record → Type:
CNAME→ Name:t→ Target: paste the value from the ClickStream dashboard. - Proxy status: DNS only (click the orange cloud to make it gray).
- Save.
If your domain is already fully on Cloudflare with the orange-cloud proxy on, Error 1014 ("CNAME cross-user banned") would normally kick in. ClickStream uses Cloudflare for SaaS custom hostnames, which bypasses 1014 — but the proxy must be off on this specific CNAME record.
AWS Route 53
AWS Console → Route 53 → Hosted zones → yourdomain.com → Create record → Type: CNAME → Name: t → Value: paste from the ClickStream dashboard → Routing policy: Simple → TTL: 300 → Create records.
GoDaddy
GoDaddy → My Products → DNS next to your domain → Add under DNS Records → Type: CNAME → Name: t → Points to: paste from the dashboard → TTL: 1 hour → Save.
Namecheap
Namecheap → Domain List → Manage → Advanced DNS → Add New Record → Type: CNAME Record → Host: t → Value: paste from the dashboard → TTL: Automatic → save (green checkmark).
Google Domains / Squarespace Domains
Domain settings → DNS → Custom records → Host: t → Type: CNAME → TTL: 3600 → Data: paste from the dashboard → Save.
Step 2 — Register in the dashboard
- Open einstein.clickstream.com → Sites → Your Site → Tracking Domain.
- Enter the subdomain you just created (e.g.
t.example.com). - The dashboard polls DNS every 10 seconds for up to 5 minutes. When the CNAME resolves to the dashboard-supplied target, the status flips to "CNAME verified" and SSL provisioning begins automatically.
- SSL typically completes within 60 seconds. When the hostname shows Active, you're ready for Step 3.
If verification stalls:
- Orange cloud on Cloudflare. Turn the proxy off on the CNAME record itself; CF for SaaS requires direct DNS resolution.
- TTL hasn't elapsed. CNAME records can take 1–60 minutes to propagate across resolvers. Re-test with
dig +short t.example.comfrom a network the dashboard would reach (not just your local machine). - Wrong target. The target value is tenant-specific — copy it verbatim from the dashboard, do not hardcode anything from this docs page.
Step 3 — Point the SDK at the new domain
Script-tag install
<script
src="https://t.example.com/sdk.js"
data-key="cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
async
></script>
NPM install
const tracker = new IdentityTracker({
apiKey: 'cs_live_...',
endpoint: 'https://t.example.com',
});
React / Next.js adapters
<ClickStreamProvider apiKey="cs_live_..." endpoint="https://t.example.com">
{children}
</ClickStreamProvider>
clickStreamMiddleware({
apiKey: process.env.CLICKSTREAM_API_KEY!,
endpoint: 'https://t.example.com',
});
Per-platform specifics
WordPress
Two options:
- Plugin-free. Edit
header.phpin your theme (Appearance → Theme File Editor), paste the script tag right before</head>. This is the same spot Google Analytics usually lives. - Plugin-managed. Install a header/footer plugin (e.g. "Insert Headers and Footers" by WPBeginner). Paste the tag into Settings → Insert Headers and Footers → Scripts in Header. Survives theme upgrades.
Shopify
Covered end-to-end in Install → Shopify. Register t.{shop}.myshopify.com (or a custom domain you've assigned to the shop) the same way as any other first-party hostname.
Next.js
If you're on the App Router, the @clickstream/next adapter handles the server side — pass endpoint: 'https://t.example.com' to both clickStreamMiddleware and ClickStreamProvider. The client SDK and the server helpers must point at the same hostname so the first-party cookie (_cs_uid) is readable from both sides.
Plain HTML / static sites
Update the script src on every page. Static-site generators (Hugo, Eleventy, Astro, Jekyll, Next.js static export) let you put the tag in a shared header partial so it updates in one place.
Rotation — swapping the tracking domain later
You can change tracking domains with zero downtime:
- Provision the new CNAME + register it in the dashboard.
- Deploy SDK configs pointing at the new hostname.
- Wait 48 hours for browsers to pick up the new bundle (the SDK loader has a 5-minute edge cache; the bundle is 1-year-immutable under a content-hashed URL, so redirects aren't needed).
- Remove the old CNAME when dashboard traffic to it has drained.
Teardown — removing a tracking domain
When you remove the CNAME, browsers with cached SDK bundles keep hitting the old hostname until their cache expires. The collector returns 404 on the unregistered hostname; the SDK logs the failure and does not retry.
To drain cleanly:
- Swap the SDK endpoint to a working hostname (your next first-party domain, or pause the SDK entirely).
- Ship + verify traffic on the new endpoint.
- Remove the old CNAME after verifying no traffic remains.
See also
- Install — the SDK install flow that pulls from this domain
- API keys + auth — domain validation is part of the auth path
- Privacy & compliance — cookie lifetimes + consent flow tied to this domain