LiveLayerTracker
The visitor tracking class. Resolves a stable identity (FingerprintJS + localStorage fallback), then optionally auto-tracks page views, clicks, scroll depth. Conversations carry the same visitor ID, so your CRM sees one continuous timeline.
import { LiveLayerTracker } from "@livelayer/sdk";
const tracker = new LiveLayerTracker({
agentId: "agt_abc123",
apiBase: "https://livelayer.app",
autoTrack: true,
autoTrackClicks: true,
});
const visitor = await tracker.init();
// → { id: "vis_abc123", isReturning: true, sessionCount: 4 }
For the script-tag version (drop-in HTML), see Visitor tracking.
Constructor
interface TrackerConfig {
agentId: string;
apiBase?: string;
autoTrack?: boolean;
autoTrackClicks?: boolean;
}
| Name | Type | Description |
|---|---|---|
| agentId* | string | Required for scoping events to your account. Match the agentId you use elsewhere. |
| apiBase | string | API base URL. Default: same origin. |
| autoTrack | boolean | Auto-track page views and SPA navigation. Default: true. |
| autoTrackClicks | boolean | Auto-track clicks on interactive elements. Default: true. |
Methods
async init(): Promise<VisitorInfo | null>
identify(attributes: Partial<VisitorAttrs>): void
track(eventName: string, data?: Record<string, unknown>): void
destroy(): void
| Name | Type | Description |
|---|---|---|
| init | () => Promise<VisitorInfo | null> | Bootstrap the tracker. Resolves visitor identity, sets up auto-tracking. Returns visitor info or null if blocked entirely. |
| identify | (attrs) => void | Attach attributes to the current visitor (email, name, plan, custom fields). Subsequent events carry these. |
| track | (name, data?) => void | Track a custom event with optional payload. |
| destroy | () => void | Clean up: flush pending events, remove auto-track listeners. Call on logout or unmount. |
Visitor info shape
interface VisitorInfo {
id: string; // "vis_abc123"
isReturning: boolean; // True on subsequent sessions
sessionCount: number; // Total resolved sessions for this visitor
}
Common patterns
React app — boot once, reuse
"use client";
import { LiveLayerTracker, type VisitorInfo } from "@livelayer/sdk";
import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
const Ctx = createContext<{ tracker: LiveLayerTracker | null; visitor: VisitorInfo | null }>({
tracker: null,
visitor: null,
});
export function TrackerProvider({ children, agentId }: { children: ReactNode; agentId: string }) {
const [tracker, setTracker] = useState<LiveLayerTracker | null>(null);
const [visitor, setVisitor] = useState<VisitorInfo | null>(null);
useEffect(() => {
const t = new LiveLayerTracker({ agentId });
t.init().then((v) => {
setTracker(t);
setVisitor(v);
});
return () => t.destroy();
}, [agentId]);
return <Ctx.Provider value={{ tracker, visitor }}>{children}</Ctx.Provider>;
}
export function useTracker() {
return useContext(Ctx);
}
Use it from any component:
const { tracker, visitor } = useTracker();
if (visitor?.isReturning) {
// Show "Welcome back" banner
}
const onCheckout = () => {
tracker?.track("checkout_started", { plan: "pro", amount: 29 });
};
Identify after login
When you know who the user is, attach attributes:
async function onLogin(user: { email: string; name: string; plan: string }) {
tracker.identify({
email: user.email,
name: user.name,
plan: user.plan,
});
}
The visitor ID stays the same; the new attributes attach to it. Conversations from this point forward carry these attributes through the agent transcript and your dashboard.
Track custom events alongside auto-tracking
// Auto-tracking captures page views and clicks automatically.
// Add domain-specific events on top.
tracker.track("watched_demo_video", {
videoId: "intro-2026",
durationSeconds: 47,
});
tracker.track("started_trial", {
source: "homepage_hero_cta",
});
Opting out
Visitors who opt out (e.g., GDPR consent banner choice):
tracker.destroy();
This stops sending events and removes all auto-track listeners. Re-init when the visitor opts back in.
Do Not Track is respected automatically — no events fire when navigator.doNotTrack === "1".
Excluding sensitive elements
Mark any element with data-ll-private="true" to exclude it from auto-tracked clicks:
<section data-ll-private="true">
<input name="ssn" />
<button>Save</button> <!-- Click on this won't be tracked -->
</section>
Event batching and delivery
- Events are queued client-side.
- Flush triggers: every 5 seconds, OR when the queue reaches 50 events, OR when the page unloads.
- Failed POSTs retry with exponential backoff: 1s, 2s, 4s, 8s.
- Events that can't be delivered after 5 retries are dropped (no permanent buffer).
Read next
- Script-tag visitor tracking — drop-in HTML version
LiveKitSession— agent session that carries visitor ID through