JSPM

  • Created
  • Published
  • Downloads 748
  • Score
    100M100P100Q130196F
  • License MIT

Li2 Analytics & Conversion Tracking SDK

Package Exports

  • @li2/analytics
  • @li2/analytics/analytics
  • @li2/analytics/conversion
  • @li2/analytics/conversion/server
  • @li2/analytics/toolbar

Readme

@li2/analytics

Conversion tracking SDK for Li2.ai. Track leads and sales from your marketing campaigns with automatic click ID attribution.

Installation

npm install @li2/analytics
# or
pnpm add @li2/analytics
# or
yarn add @li2/analytics

Client-Side SDK

The client-side SDK automatically captures click IDs from URLs (?uid=...) and cookies, making it easy to track conversions in the browser. You don't need to pass clickId manually - it's auto-detected.

Note: If you need to track conversions on the server (e.g., after a webhook or server-side payment confirmation), use getClickId() to capture the click ID on the client and pass it to your server. See Server-Side SDK for details.

Installation Snippet

Add this snippet to your <head> tag. It loads the SDK asynchronously and queues any tracking calls made before the script loads.

<script>
  !(function (c, n) {
    c[n] = c[n] || function () { (c[n].q = c[n].q || []).push(arguments); };
    ["trackLead", "trackSale", "trackEvent", "identify"].forEach((t) => (c[n][t] = (...a) => c[n](t, ...a)));
    var s = document.createElement("script");
    s.defer = 1;
    s.src = "https://unpkg.com/@li2/analytics/dist/index.global.js";
    s.setAttribute("data-publishable-key", "li2_pk_...");
    document.head.appendChild(s);
  })(window, "li2Analytics");
</script>

Script Tag Usage

<script
  src="https://unpkg.com/@li2/analytics/dist/index.global.js"
  data-publishable-key="li2_pk_..."
></script>

<script>
  // Track a lead
  li2Analytics.trackLead({
    eventName: 'signup',
    customerExternalId: 'user_123',
    customerName: 'John Doe',
    customerEmail: 'john@example.com',
  })

  // Track a sale (click ID auto-detected from cookie/URL)
  li2Analytics.trackSale({
    customerExternalId: 'user_123',
    amount: 4999, // $49.99 in cents
    eventName: 'purchase',
    invoiceId: 'inv_abc123',
  })

  // Track a direct sale (no tracked link — pass clickId: "" explicitly)
  li2Analytics.trackSale({
    customerExternalId: 'user_123',
    amount: 2500,
    clickId: '', // Direct Sale — no link attribution
  })

  // Track a named event
  li2Analytics.trackEvent('button_clicked', { category: 'cta' })
</script>

Script Tag Attributes

Attribute Description
data-publishable-key Your publishable API key (li2_pk_...)
data-api-url Custom API endpoint (default: https://api.li2.ai)
data-debug Enable debug logging (presence enables, no value needed)
data-cookie-options JSON object for cookie customization (see below)
data-outbound JSON array of domains for outbound link tracking (e.g., ["partner.com"])
data-pageview "true" to enable automatic pageview tracking
data-clicks "true" to enable automatic click tracking (heatmap data)

By default, the SDK stores the click ID in a cookie scoped to the current domain with a 30-day expiration. Use data-cookie-options for cross-domain tracking or custom expiration.

<script
  src="https://unpkg.com/@li2/analytics/dist/index.global.js"
  data-publishable-key="li2_pk_..."
  data-cookie-options='{"domain":".example.com","expiresInDays":60}'
></script>
Property Type Default Description
domain string (current domain) Cookie domain for cross-subdomain tracking (e.g., .example.com)
expiresInDays number 30 Days until the cookie expires
path string "/" Cookie path

Cross-domain tracking example: If users land on www.example.com but convert on app.example.com, set domain to .example.com to share the click ID across subdomains.

Automatically append click IDs to outbound links and iframes pointing to specified domains. This is useful for tracking conversions across multiple domains or passing attribution data to partner sites.

Key Benefits:

  • Reduced bundle size - Only loads when configured (separate module)
  • Automatic tracking - No manual link modification needed
  • Dynamic content support - Tracks links added after page load
  • SPA compatible - Works with client-side routing

Script Tag Usage

Add the data-outbound attribute with a JSON array of domains to track:

<script
  src="https://unpkg.com/@li2/analytics/dist/index.global.js"
  data-publishable-key="li2_pk_..."
  data-outbound='["partner.com", "checkout.example.com"]'
></script>

The SDK will automatically:

  1. Find all <a> and <iframe> elements pointing to the specified domains
  2. Append the click ID as a uid query parameter
  3. Monitor for dynamically added links (SPAs, AJAX content)

Module Import Usage

import { init } from '@li2/analytics'

init({
  publishableKey: 'li2_pk_...',
  outbound: ['partner.com', 'checkout.example.com'],
})

Example

Before tracking:

<a href="https://partner.com/signup">Sign up</a>

After tracking (automatic):

<a href="https://partner.com/signup?uid=abc123xyz">Sign up</a>

The partner site can then read the uid parameter and use it for server-side conversion tracking.

How It Works

  1. Domain matching: Links are tracked if their hostname ends with any configured domain
  2. Normalization: www. prefixes are automatically stripped for matching
  3. Deduplication: Each link is only modified once to avoid duplicate parameters
  4. Periodic scanning: New links are detected every 2 seconds
  5. History API support: Links are re-scanned on navigation in SPAs

Note: The outbound module is loaded dynamically only when the outbound option is configured, keeping your bundle size minimal when not needed.

Pageview Tracking

Automatically track every page visit on your website, including SPA (React, Vue, Angular) navigation. Pageview data powers funnel analytics and drop-off analysis.

Key Benefits:

  • MPA + SPA support - Works with traditional sites and single-page apps
  • Automatic session management - Visitor and session IDs with 30-min timeout
  • Batched delivery - Events buffered and sent every 5s to minimize requests
  • Lazy-loaded - Only loads when enabled, keeping your bundle minimal

Script Tag Usage

Add data-pageview="true" to enable automatic pageview tracking:

<script
  src="https://unpkg.com/@li2/analytics/dist/index.global.js"
  data-publishable-key="li2_pk_..."
  data-pageview="true"
></script>

Configuration Attributes

Attribute Default Description
data-pageview "false" Enable pageview tracking
data-pageview-spa "auto" SPA mode: "auto", "manual", or "disabled"
data-pageview-hash "false" Track hash changes as separate pageviews
data-pageview-exclude "" Comma-separated URL patterns to exclude (e.g., "/admin/*,/api/**")
data-pageview-timeout "30" Session timeout in minutes
data-pageview-batch "5000" Batch send interval in milliseconds
data-pageview-search-params "q,query,search,s,keyword" URL params to detect as search queries
data-pageview-cookie-less "false" Use only localStorage (no cookies)

Programmatic Usage

// Enable pageview tracking programmatically
li2Analytics.enablePageviewTracking({
  spaMode: 'auto',
  excludePatterns: ['/admin/*'],
  sessionTimeout: 30,
});

// Manually track a pageview
li2Analytics.trackPageview({
  pageUrl: 'https://example.com/products',
  pageTitle: 'Products',
});

// Control tracking
li2Analytics.pageview.disable();
li2Analytics.pageview.enable();
li2Analytics.pageview.newSession();

How It Works

  1. Page detection: Intercepts History API (pushState, replaceState) and popstate events for SPA navigation
  2. Session management: Assigns persistent visitor_id (localStorage + cookie) and session_id (sessionStorage) with configurable timeout
  3. Batching: Buffers pageview events and flushes every 5 seconds via fetch, or immediately via sendBeacon on page unload
  4. Click ID linking: Automatically links pageviews to Li2 click IDs for attribution

Click Tracking

Automatically capture every click on your page to power heatmaps and rage click detection in the Li2 dashboard. Uses a single delegated listener and batched delivery — zero impact on page performance.

Key Benefits:

  • Zero-config - One attribute enables it all
  • Automatic deduplication - Rapid repeated clicks are deduplicated (50ms window)
  • Element metadata - Captures tag, text, class, ID, and CSS selector path
  • Rage click detection - Backend automatically detects frustration patterns
  • Lazy-loaded - Module only loads when enabled

Script Tag Usage

Add data-clicks="true" to enable automatic click tracking:

<script
  src="https://unpkg.com/@li2/analytics/dist/index.global.js"
  data-publishable-key="li2_pk_..."
  data-pageview="true"
  data-clicks="true"
></script>

Configuration Attributes

Attribute Default Description
data-clicks "false" Enable click tracking
data-clicks-exclude "" CSS selector for elements to exclude (e.g., ".no-track, #sensitive")
data-clicks-batch "5000" Batch send interval in milliseconds

Note: Click tracking shares session config with pageview tracking. Set data-pageview-timeout, data-pageview-cookieless, etc. once and both modules use the same session.

Programmatic Usage

import { init } from '@li2/analytics'

const sdk = init({ publishableKey: 'li2_pk_...' })

await sdk.enableClickTracking({
  excludeSelector: '.no-track',
  batchInterval: 3000,
})

Event Tracking

Track named custom events (button clicks, form submissions, feature usage) that appear in your Li2 funnel analytics and event rules. Events flow through the same pipeline as pageviews — no extra setup needed.

Key Benefits:

  • Funnel compatible - Events appear as steps in your funnel builder
  • Event rules - Power automated tagging and retroactive classification
  • Auto-init - Starts pageview pipeline automatically if not already running
  • Category support - Group events for easier filtering

Script Tag Usage

<script>
  // Track a button click
  li2Analytics.trackEvent('cta_clicked')

  // Track with a category
  li2Analytics.trackEvent('video_played', { category: 'engagement' })

  // Track form submission
  document.querySelector('#signup-form').addEventListener('submit', () => {
    li2Analytics.trackEvent('form_submitted', { category: 'conversion' })
  })
</script>

Module Import Usage

import { trackEvent } from '@li2/analytics'

// Track a named event
await trackEvent('plan_selected', { category: 'onboarding' })

How It Works

Events are sent through the pageview pipeline with an event_name field set. This means:

  1. They are scoped to the current page URL and session
  2. They appear in funnel builder as matchable steps (type: "event")
  3. They trigger any matching event rules in the Li2 dashboard
  4. They are stored alongside pageview data for unified analysis

Module Import Usage

import { init, trackLead, trackSale } from '@li2/analytics'

// Initialize with your publishable key
init({
  publishableKey: 'li2_pk_...',
  debug: true, // optional: enable console logging
})

// Track a lead conversion
const leadResult = await trackLead({
  eventName: 'signup',
  customerExternalId: 'user_123',
  customerName: 'John Doe',
  customerEmail: 'john@example.com',
})

if (leadResult.success) {
  console.log('Lead tracked:', leadResult.customerId)
}

// Track a sale conversion
const saleResult = await trackSale({
  customerExternalId: 'user_123',
  amount: 4999, // Amount in cents ($49.99)
  eventName: 'purchase',
  paymentProcessor: 'stripe',
  invoiceId: 'inv_abc123',
  currency: 'usd',
})

if (saleResult.success) {
  console.log('Sale tracked:', saleResult.saleEventId)
}

Utility Functions

import { isTrackingAvailable, getClickId } from '@li2/analytics'

// Check if a click ID is available for attribution
if (isTrackingAvailable()) {
  console.log('Click ID:', getClickId())
}

// Use getClickId() to pass the click ID to your server for server-side tracking
const clickId = getClickId() // Returns null if no click ID is available

Dashboard Overlays

The SDK includes two dashboard-powered overlays that your team can activate directly from the Li2 dashboard — no additional developer configuration required.

Heatmap Overlay

Visualize where users are clicking on any page. Activated from the Heatmap section of your dashboard via the "View on site" button. When activated, a floating toolbar appears on your page showing:

  • A Gaussian KDE heatmap rendered over your live page
  • Click counts and opacity controls
  • Device type filtering (desktop / tablet / mobile)

The SDK detects the ?li2_heatmap URL parameter and automatically loads the heatmap module. No code changes needed.

Visual Event Tagger

Tag DOM elements as named events directly on your live site — without writing code. Activated from the Event Rules section of your dashboard via the "Tag Events on Site" button.

When active, hovering over any element highlights it. Clicking it opens a panel where you can name the event and save it as an event rule. Tagged events appear immediately in your funnel builder and analytics.

The SDK detects the ?li2_tagger URL parameter and loads the tagger module automatically.

Security note: Both overlays require a time-limited session token generated by the dashboard. Direct URL access without a valid token shows an error.

Server-Side SDK

The server-side SDK is for use in Node.js, Next.js API routes, server actions, and other backend environments. It requires an API key for authentication.

Passing Click ID from Client to Server

Unlike the client-side SDK, the server cannot auto-detect the click ID. You need to capture it on the client and include it in your server requests:

// Client-side: capture the click ID
import { getClickId } from '@li2/analytics'

const clickId = getClickId()

// Include clickId when calling your server
fetch('/api/checkout', {
  method: 'POST',
  body: JSON.stringify({ clickId, ...otherData }),
})

Setup

import { initServer } from '@li2/analytics'

const li2 = initServer({
  apiKey: 'li2_sk_...', // Your secret API key
  debug: true, // optional: enable console logging
})

Track Lead (Server-Side)

// clickId must be captured from the client and passed to your server
const result = await li2.trackLead({
  clickId: 'abc123', // Required for server-side tracking
  eventName: 'signup',
  customerExternalId: 'user_123',
  customerName: 'John Doe',
  customerEmail: 'john@example.com',
  metadata: {
    plan: 'pro',
    source: 'landing_page',
  },
})

if (result.success) {
  console.log('Lead tracked:', result.customerId)
}

Track Sale (Server-Side)

// Attributed sale — linked to a tracked visit
const result = await li2.trackSale({
  clickId: 'abc123', // Click ID from the client
  customerExternalId: 'user_123',
  amount: 9900, // Amount in cents ($99.00)
  eventName: 'subscription',
  paymentProcessor: 'stripe',
  invoiceId: 'inv_xyz789',
  currency: 'usd',
  metadata: {
    plan: 'annual',
    coupon: 'SAVE20',
  },
})

if (result.success) {
  console.log('Sale tracked:', result.saleEventId)
}

For sales that happen without a tracked link (e.g., in-store, phone, manual entry), pass an explicit empty string for clickId:

const result = await li2.trackSale({
  clickId: '', // Empty string = Direct Sale (no link attribution)
  customerExternalId: 'user_123',
  amount: 5000,
  customerEmail: 'john@example.com',
  customerName: 'John Doe',
})

Important: clickId must be explicitly provided. Omitting it entirely returns an error. Pass "" for Direct Sale or a valid click ID for attributed sale.

Next.js Example

// app/api/checkout/route.ts
import { initServer } from '@li2/analytics'

const li2 = initServer({ apiKey: process.env.LI2_API_KEY! })

export async function POST(request: Request) {
  const { clickId, userId, amount, invoiceId } = await request.json()

  // Track the sale after successful payment
  // clickId from client, or "" for direct sale
  const result = await li2.trackSale({
    clickId: clickId ?? '',
    customerExternalId: userId,
    amount,
    invoiceId,
    paymentProcessor: 'stripe',
  })

  return Response.json({ success: result.success })
}

API Reference

Client-Side

Function Description
init(config) Initialize the SDK with configuration
trackLead(params) Track a lead conversion event
trackSale(params) Track a sale conversion event
trackEvent(eventName, options?) Track a named custom event
trackPageview(options?) Manually track a pageview
identify(params) Link an anonymous visitor to a known customer
isTrackingAvailable() Check if click ID is available
getClickId() Get the current click ID
enablePageviewTracking(config?) Enable pageview tracking programmatically
enableClickTracking(options?) Enable click tracking programmatically
pageview.disable() Pause pageview tracking
pageview.enable() Resume pageview tracking
pageview.newSession() Force a new session

Server-Side

Function Description
initServer(config) Create a server-side SDK instance
trackLead(params) Track a lead (clickId required)
trackSale(params) Track a sale (clickId required — pass "" for Direct Sale)
identify(params) Link anonymous visitor to customer (clickId required)

TrackLead Parameters

Parameter Type Required Description
clickId string Server only Click ID for attribution
eventName string Yes Name of the lead event
customerExternalId string No Your unique customer identifier
customerName string No Customer's name
customerEmail string No Customer's email
customerAvatar string No URL to customer's avatar
metadata object No Additional data (max 10,000 chars)

TrackSale Parameters

Parameter Type Required Description
clickId string Server only Click ID for attribution. Pass "" for Direct Sale (no link).
customerExternalId string Yes Your unique customer identifier
amount number Yes Amount in smallest currency unit
eventName string No Name of sale event (default: "Purchase")
paymentProcessor string No Payment processor (e.g., "stripe")
invoiceId string No Your invoice/transaction ID
currency string No Currency code (default: "usd")
customerName string No Customer's name
customerEmail string No Customer's email
metadata object No Additional data (max 10,000 chars)

TrackEvent Parameters

Parameter Type Required Description
eventName string Yes Name of the event (e.g., "cta_clicked")
options.category string No Event category for grouping

EnableClickTracking Options

Option Type Default Description
excludeSelector string null CSS selector for elements to exclude
batchInterval number 5000 Batch flush interval in ms
sessionTimeout number 30 Session timeout in minutes
cookieLessMode boolean false Use localStorage only (no cookies)
cookieDomain string Cookie domain for cross-subdomain tracking

License

MIT