JSPM

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

Li2 Analytics SDK for conversion tracking

Package Exports

  • @li2/analytics
  • @li2/analytics/click-tracker
  • @li2/analytics/pageview
  • @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", "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
  li2Analytics.trackSale({
    customerExternalId: 'user_123',
    amount: 4999, // $49.99 in cents
    eventName: 'purchase',
    invoiceId: 'inv_abc123',
  })
</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"])

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

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

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)

const result = await li2.trackSale({
  clickId: 'abc123', // Required for server-side tracking
  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)
}

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
  const result = await li2.trackSale({
    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
isTrackingAvailable() Check if click ID is available
getClickId() Get the current click ID
enablePageviewTracking(config) Enable pageview tracking programmatically
trackPageview(options) Manually track a pageview
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)

TrackLead Parameters

Parameter Type Required Description
clickId string Server only Click ID for attribution
eventName string Yes Name of the lead event
customerExternalId string Yes 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
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)

License

MIT