View as markdown

Visitor tracking

Beyond the conversation widget, the SDK ships a separate tracker that resolves a stable visitor identity, then auto-tracks page views, clicks, and scroll depth. Conversations carry the same visitor ID, so your CRM sees one continuous timeline whether the visitor talks to the agent or just browses.

Standalone tracker (script tag)

Drop the tracker on every page where you want visitor analytics:

html
<script
  src="https://livelayer.app/v1.js"
  data-agent-id="agt_abc123"
  data-tracker="auto">
</script>

When data-tracker="auto" is set, the SDK boots the tracker automatically on script load.

What gets tracked automatically

  • Page views — initial load + SPA navigation (pushState / popstate)
  • Clicks on interactive elements: links, buttons, [role="button"], [onclick]
  • Scroll depth (percentage) on page exit
  • Page exit — duration, final scroll depth

Events are batched (every 5 seconds or 50 events) and POSTed to /api/visitors/{visitorId}/events. Failed posts retry with exponential backoff.

Visitor identity

The tracker resolves a stable identity using a layered approach:

  1. FingerprintJS (best effort)

    The tracker dynamically imports @fingerprintjs/fingerprintjs and computes a device-level fingerprint. Survives across cookie clears.

  2. localStorage fallback

    If FingerprintJS is blocked (adblocker, privacy mode), the tracker falls back to a UUID stored in localStorage. Per-browser only.

  3. Server resolution

    Fingerprint + localStorage ID POST to /api/visitors/identify. The server returns { visitorId, isReturning, sessionCount }.

Identifying known visitors

When you know who the visitor is (signed-in user), call identify() to attach attributes:

ts
LiveLayer.identify({
  email: "jordan@acme.com",
  name: "Jordan Park",
  phone: "+1...",
  company: "Acme Inc",
  // Free-form custom attributes
  plan: "pro",
  signupAt: "2026-01-12",
});

Subsequent events (and the next conversation) carry these attributes.

Tracking custom events

ts
LiveLayer.track("clicked_pricing_cta", {
  plan: "pro",
  source: "homepage_hero",
});

LiveLayer.track("watched_demo_video", {
  videoId: "intro-2026",
  durationSeconds: 47,
});

Custom events show up alongside auto-tracked events in the visitor timeline.

Reading visitor state

ts
console.log(LiveLayer.visitor);
// { id: "vis_abc123", isReturning: true, sessionCount: 4 }

Useful for personalizing UI based on whether the visitor has been here before.

Configuration

html
<script
  src="https://livelayer.app/v1.js"
  data-agent-id="agt_abc123"
  data-tracker="auto"
  data-track-page-views="true"
  data-track-clicks="true"
  data-api-base="https://livelayer.app">
</script>
NameTypeDescription
data-tracker"auto" | "manual"auto = boot the tracker on script load. manual = expose LiveLayerTracker on window for hand-rolled init.
data-track-page-viewsbooleanAuto-track page views and SPA navigation. Default: true when tracker = auto.
data-track-clicksbooleanAuto-track clicks on interactive elements. Default: true.
data-api-basestringOverride the API base URL. Default: same origin as the script src.
  • The tracker respects Do Not Track headers — when navigator.doNotTrack === "1", automatic events are suppressed.
  • LiveLayer.optOut() clears localStorage and stops sending events for the rest of the page session.
  • Mark sensitive elements with data-ll-private="true" to exclude them from auto-tracked clicks.

Where this data appears

In the dashboard:

  • People page — visitor timeline with both events and conversations interleaved
  • Inbox — every conversation links back to its visitor's full event history
  • Analytics — funnel and retention reports built from event data