JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 4
  • Score
    100M100P100Q48137F
  • License MIT

Analytics SDK for Shoppi clients

Package Exports

  • @shoppi/analytics

Readme

Shoppi Analytics SDK

A lightweight, type-safe analytics SDK for tracking user interactions with e-commerce applications.

Features

  • Type-safe event tracking with TypeScript support
  • Specialized methods for common e-commerce events
  • Configurable batch processing and automatic retries
  • Flow context tracking for analyzing user journeys
  • Robust user identity management with persistent tracking
  • Automatic timestamp and client metadata handling
  • Minimal configuration required
  • Support for selector-based tracking with HTML data attributes

Table of Contents

Installation

npm install shoppi-analytics

Usage Methods

The SDK supports three modes of usage:

1. TypeScript

import { Analytics, FlowType } from 'shoppi-analytics';

const analytics = Analytics.init({
  apiKey: 'your-api-key',
  clientId: 'your-client-id',
  debug: true
});

analytics.trackProductDetailView({
  objectId: 'product-123',
  price: 99.99,
  category: 'clothing'
});

2. JavaScript (Node.js/Bundler)

// ESM import
import { Analytics } from 'shoppi-analytics';

// OR CommonJS require
const { Analytics } = require('shoppi-analytics');

const analytics = Analytics.init({
  apiKey: 'your-api-key',
  clientId: 'your-client-id'
});

analytics.trackProductClick({
  objectId: 'product-123',
  price: 99.99
});

3. Browser (Script Tag)

<script src="https://cdn.example.com/shoppi-analytics/dist/shoppi-analytics.js"></script>

<script>
  // Clean interface - no nested Analytics property needed
  const analytics = ShoppiAnalytics.init({
    apiKey: 'your-api-key',
    clientId: 'your-client-id'
  });
  
  // Track events
  analytics.trackProductClick({
    objectId: 'product-123',
    price: 99.99
  }, ShoppiAnalytics.FlowType.DIRECT);
</script>

Quick Start

Initialization

import { Analytics, AnalyticsConfig, FlowType } from 'shoppi-analytics';

const config: AnalyticsConfig = {
  apiKey: 'your-api-key',
  clientId: 'your-client-id',
  debug: true, // Optional, enables debug logging
  // Optional user tokens - recommended for user journey tracking
  userToken: {
    anonymousId: 'client-anon-id-123', // Client-provided anonymous user ID
    authenticatedId: 'user-456'         // Client-provided authenticated user ID
  }
};

// Initialize the SDK
const analytics = Analytics.init(config);

// Track events using selectors
analytics.trackProductClick(`[id="${product.id}"]`);

// Using flow-specific methods with selectors
analytics.trackSearchAddToCart(`[data-shoppi-object-id="${product.id}"][data-shoppi-price="${product.price}"]`);
analytics.trackOutfitAddToCart(`[data-shoppi-object-id="${outfitProduct.id}"][data-shoppi-price="${outfitProduct.price}"]`);
analytics.trackSimilarAddToCart(`[data-shoppi-object-id="${similarProduct.id}"][data-shoppi-price="${similarProduct.price}"]`);

// Or using properties
analytics.trackAddToCart({
  objectId: 'product-123',
  price: 99.99
}, FlowType.DIRECT);

User Identification

The SDK manages three types of user identifiers:

  1. anonymousId (optional): Client-provided identifier for anonymous users
  2. authenticatedId (optional): Client-provided identifier for authenticated users
  3. shoppiId (required, managed by SDK): Persistent identifier generated and stored by the SDK

You can set these during initialization or update them later:

// Set during initialization
const analytics = Analytics.init({
  // required config...
  userToken: {
    anonymousId: 'client-anon-id-123',
    authenticatedId: 'user-456'
  }
});

// Update later
analytics.setAnonymousId('new-anon-id');
analytics.setAuthenticatedId('new-auth-id');
analytics.setUserToken({
  anonymousId: 'another-anon-id',
  authenticatedId: 'another-auth-id'
});

Best Practices for User Identification

  1. Initialize with existing IDs when available

    // Retrieve IDs from storage or your authentication system
    const anonymousId = localStorage.getItem('your_anon_id_key');
    const authenticatedId = getAuthenticatedUser()?.id;
    
    // Initialize with existing IDs
    const analytics = Analytics.init({
      // Other config...
      userToken: {
        anonymousId,
        authenticatedId
      }
    });
  2. Generate and store client anonymous ID

    // Generate client-side anonymous ID if not already available
    let anonymousId = localStorage.getItem('your_anon_id_key');
    if (!anonymousId) {
      anonymousId = generateRandomId(); // Your ID generation method
      localStorage.setItem('your_anon_id_key', anonymousId);
    }
    
    const analytics = Analytics.init({
      // Other config...
      userToken: {
        anonymousId
      }
    });
  3. Update authenticated ID after login

    // After user login
    function onUserLogin(user) {
      // Update the authenticated ID while preserving anonymous ID
      analytics.setAuthenticatedId(user.id);
    }
  4. Keep both IDs after authentication

    • Always maintain both the anonymous ID and authenticated ID when a user logs in
    • This ensures consistent tracking across anonymous and authenticated sessions
  5. For SPAs and page reloads

    • Initialize analytics with the same user tokens on page changes
    • For single-page applications, initialize once with persistent tokens

Basic Usage

The SDK provides two approaches to tracking events:

Selector-based Tracking

Use CSS selectors to reference HTML elements with data attributes:

<!-- HTML element with data attributes -->
<div class="product-card" 
     id="product-123"
     data-shoppi-object-id="product-123"
     data-shoppi-price="99.99"
     data-shoppi-category="clothing"
     data-shoppi-title="Summer T-Shirt">
  <img src="product.jpg" alt="Product Image">
  <h3>Summer T-Shirt</h3>
  <p>$99.99</p>
</div>
// Track a product click when the element is clicked
document.getElementById('product-123').addEventListener('click', function() {
  analytics.trackProductClick(`[id="product-123"]`);
});

Properties-based Tracking

Directly pass properties as objects:

// Track a product view
analytics.trackProductDetailView({
  objectId: 'product-123',
  price: 99.99,
  category: 'clothing',
  title: 'Summer T-Shirt'
});

// Track adding to cart with specified flow
analytics.trackAddToCart({
  objectId: 'product-123',
  price: 99.99
}, FlowType.DIRECT);

// Using flow-specific methods
analytics.trackSearchAddToCart({
  objectId: 'product-123',
  price: 99.99
});

analytics.trackOutfitAddToCart({
  objectId: 'product-456',
  price: 149.99
});

analytics.trackSimilarAddToCart({
  objectId: 'product-789',
  price: 199.99
});

Data Attributes

The SDK supports automatic event tracking through HTML data attributes. All attributes should be prefixed with data-shoppi-.

Attribute Format

  • All attributes are prefixed with data-shoppi-
  • Property names are converted from kebab-case to camelCase automatically
  • Example: data-shoppi-object-id becomes objectId in the event properties
  • Values are automatically converted to appropriate types (numbers, booleans)

Required Attributes

Different events require different attributes:

  • Most events require data-shoppi-object-id
  • Search events require data-shoppi-query-id and data-shoppi-query
  • Conversion events require data-shoppi-flow
  • Purchase events also require data-shoppi-value and data-shoppi-currency

Example Elements

Product Detail:

<div class="product-detail" 
     id="product-123" 
     data-shoppi-object-id="product-123"
     data-shoppi-price="99.99"
     data-shoppi-category="clothing"
     data-shoppi-brand="BrandName"
     data-shoppi-title="Summer T-Shirt">
  <!-- Product content -->
</div>

Search Results:

<div class="search-results" 
     id="search-results" 
     data-shoppi-query-id="search-123"
     data-shoppi-query="summer t-shirt"
     data-shoppi-results-count="24">
  <!-- Search results content -->
</div>

Add to Cart Button:

<button id="add-to-cart" 
        data-shoppi-object-id="product-123"
        data-shoppi-price="99.99"
        data-shoppi-quantity="1"
        data-shoppi-flow="direct">
  Add to Cart
</button>

Event Types

The SDK supports different event types for tracking various user interactions:

View Events

Track when users view content like products, search results, or outfits.

// Track product detail view
analytics.trackProductDetailView({
  objectId: 'product-123',
  price: 99.99,
  category: 'clothing'
});

// Track search results view
analytics.trackSearchResultsView({
  queryId: 'search-456',
  query: 't-shirt',
  resultsCount: 24
});

// Track outfit view
analytics.trackOutfitView({
  objectId: 'outfit-789'
}, FlowType.OUTFIT);

// Track similar products view
analytics.trackSimilarProductsView({
  sourceObjectId: 'product-123'
});

// Track category page view
analytics.trackCategoryPageView({
  categoryId: 'men-clothing'
});

Click Events

Track when users click on interactive elements.

// Track product click
analytics.trackProductClick({
  objectId: 'product-123',
  price: 99.99
});

// Track search result click
analytics.trackSearchResultClick({
  objectId: 'product-123',
  queryId: 'search-456',
  position: 3
});

// Track outfit item click
analytics.trackOutfitItemClick({
  objectId: 'product-123',
  position: 2
}, FlowType.OUTFIT);

// Track similar product click
analytics.trackSimilarProductClick({
  objectId: 'product-456',
  sourceObjectId: 'product-123'
});

Search Events

Track search-related actions like queries, filtering, and sorting.

// Track search query
analytics.trackSearchQuery({
  queryId: 'search-456',
  query: 't-shirt'
});

// Track filter applied
analytics.trackFilterApplied({
  queryId: 'search-456',
  filters: {
    category: 'clothing',
    size: 'medium',
    color: 'blue'
  }
});

// Track sort changed
analytics.trackSortChanged({
  queryId: 'search-456',
  sort: 'price_asc'
});

Conversion Events

Track commercial actions like adding to cart or purchasing.

// Track add to cart (flow is required for conversion events)
analytics.trackAddToCart({
  objectId: 'product-123',
  price: 99.99,
  quantity: 1
}, FlowType.DIRECT);

// Track purchase
analytics.trackPurchase({
  objectId: 'product-123',
  value: 99.99,
  currency: 'USD',
  quantity: 1
}, FlowType.DIRECT);

// Track save for later
analytics.trackSaveForLater({
  objectId: 'product-123'
}, FlowType.SEARCH);

Flow Types

Flow types indicate the user journey or context:

// Available flow types:
FlowType.DIRECT    // Direct navigation or interaction
FlowType.SEARCH    // From search results
FlowType.SIMILAR   // From similar product recommendations
FlowType.OUTFIT    // From outfit/collection recommendations
FlowType.CATEGORY  // From category browsing

Most event methods use an appropriate default flow type, but you can override it. For conversion events, you must specify the flow explicitly to track attribution.

Default Flow Types

The SDK automatically sets appropriate default flow types for each event:

Event Method Default Flow Type
trackSearchResultsView FlowType.SEARCH
trackSearchResultClick FlowType.SEARCH
trackSearchQuery FlowType.SEARCH
trackFilterApplied FlowType.SEARCH
trackSortChanged FlowType.SEARCH
trackOutfitView FlowType.OUTFIT
trackOutfitItemClick FlowType.OUTFIT
trackSimilarProductClick FlowType.SIMILAR
trackSimilarProductsView FlowType.SIMILAR
trackCategoryPageView FlowType.CATEGORY
trackProductDetailView FlowType.DIRECT
trackProductClick FlowType.DIRECT

Advanced Usage

Manual Event Tracking

For more control or custom events, use the generic trackEvent method:

import { EventType, EventSubtype, FlowType } from 'shoppi-analytics';

analytics.trackEvent(
  EventType.CONVERSION,
  EventSubtype.ADD_TO_CART,
  {
    objectId: 'product-123',
    objectType: 'product',
    quantity: 2,
    price: 99.99
  },
  FlowType.SEARCH
);

Event Batching and Flushing

Events are batched and sent automatically based on your configuration:

  • Events are queued until the batch size is reached (default: 10)
  • Events are automatically sent every X milliseconds (default: 5000ms)
  • You can manually flush events at any time:
// Send all queued events immediately
analytics.flush();

// For single page applications, flush on route change
router.beforeEach((to, from, next) => {
  analytics.flush().then(() => next());
});

// Always flush before page unload
window.addEventListener('beforeunload', function() {
  analytics.flush();
});

// Call when your application is closing to ensure all events are sent
analytics.shutdown();

Tracking Dynamically Loaded Content

For content loaded dynamically via AJAX or other methods:

function loadProductsAndTrack(products) {
  const container = document.getElementById('product-container');
  
  // Clear container
  container.innerHTML = '';
  
  // Add products and track them
  products.forEach((product, index) => {
    // Create element
    const productEl = document.createElement('div');
    productEl.className = 'product-item';
    productEl.id = `product-${product.id}`;
    
    // Add data attributes
    productEl.dataset.shoppiObjectId = product.id;
    productEl.dataset.shoppiPosition = index + 1;
    productEl.dataset.shoppiPrice = product.price;
    productEl.dataset.shoppiCategory = product.category;
    
    // Add content
    productEl.innerHTML = `
      <h3>${product.name}</h3>
      <p>$${product.price}</p>
    `;
    
    // Add click handler
    productEl.addEventListener('click', () => {
      analytics.trackProductClick(`[id="product-${product.id}"]`);
    });
    
    // Add to container
    container.appendChild(productEl);
  });
}

Event Types and Required Fields

Event Type Event Subtype Description Base Required Fields Additional Required Fields Flow Type Support
SEARCH QUERY Track search query execution eventType, eventSubtype, eventName, flow, queryID, timestamp query All
FILTER_APPLIED Track when filters are applied eventType, eventSubtype, eventName, flow, queryID, timestamp filterName, filterValue All
FILTER_REMOVED Track when filters are removed eventType, eventSubtype, eventName, flow, queryID, timestamp filterName, filterValue All
SORT_CHANGED Track sort order changes eventType, eventSubtype, eventName, flow, queryID, timestamp sortOption All
ZERO_RESULTS Track searches with no results eventType, eventSubtype, eventName, flow, queryID, timestamp query All
CLICK PRODUCT Track product clicks eventType, eventSubtype, eventName, flow, objectID, timestamp - All
SEARCH_RESULT Track search result clicks eventType, eventSubtype, eventName, flow, objectID, timestamp queryID, position SEARCH
SIMILAR_PRODUCT Track similar product clicks eventType, eventSubtype, eventName, flow, objectID, timestamp sourceObjectID, position SIMILAR
OUTFIT_ITEM Track outfit item clicks eventType, eventSubtype, eventName, flow, objectID, timestamp outfitID, position OUTFIT
OUTFIT Track outfit clicks eventType, eventSubtype, eventName, flow, objectID, timestamp outfitID OUTFIT
PAGINATION Track pagination clicks eventType, eventSubtype, eventName, flow, objectID, timestamp - All
FILTER Track filter clicks eventType, eventSubtype, eventName, flow, objectID, timestamp - All
SORT Track sort option clicks eventType, eventSubtype, eventName, flow, objectID, timestamp - All
SUGGESTION Track search suggestion clicks eventType, eventSubtype, eventName, flow, objectID, timestamp suggestion, queryID SEARCH
VIEW PRODUCT_DETAIL Track product detail views eventType, eventSubtype, eventName, flow, timestamp objectID All
SEARCH_RESULTS Track search results views eventType, eventSubtype, eventName, flow, timestamp queryID, resultsCount SEARCH
SIMILAR_PRODUCTS Track similar products views eventType, eventSubtype, eventName, flow, timestamp sourceObjectID SIMILAR
OUTFIT Track outfit views eventType, eventSubtype, eventName, flow, timestamp outfitID OUTFIT
OUTFIT_COLLECTION Track outfit collection views eventType, eventSubtype, eventName, flow, timestamp outfitID OUTFIT
CATEGORY_PAGE Track category page views eventType, eventSubtype, eventName, flow, timestamp categoryID CATEGORY
CONVERSION PURCHASE Track product purchases eventType, eventSubtype, eventName, flow, objectID, timestamp value, currency All
ADD_TO_CART Track add to cart actions eventType, eventSubtype, eventName, flow, objectID, timestamp quantity All
SAVE_FOR_LATER Track save for later actions eventType, eventSubtype, eventName, flow, objectID, timestamp - All
IMPRESSION PRODUCT_LIST Track product list impressions eventType, eventSubtype, eventName, flow, items, timestamp - All
SIMILAR_PRODUCTS Track similar products impressions eventType, eventSubtype, eventName, flow, items, timestamp sourceObjectID SIMILAR
OUTFIT_LIST Track outfit list impressions eventType, eventSubtype, eventName, flow, items, timestamp outfitID OUTFIT
SEARCH_RESULTS Track search results impressions eventType, eventSubtype, eventName, flow, items, timestamp queryID, resultsCount SEARCH

Flow Types and Required Fields

Flow Type Description Required Fields Use Case
DIRECT Direct navigation or interaction - User directly navigates to a product or takes action without context
SEARCH From search results queryID User interacts with content from search results
SIMILAR From similar product recommendations sourceObjectID User interacts with similar product recommendations
OUTFIT From outfit/collection recommendations outfitID User interacts with outfit or collection content
CATEGORY From category browsing categoryID User browses and interacts with category pages

Notes:

  • All events include common fields like timestamp and flow
  • Flow-specific fields are required when using that flow type
  • Additional custom properties can be included beyond the required fields
  • Some events may require specific combinations of fields based on the context

Configuration Options

  • apiKey: Your API key for accessing the analytics server
  • clientId: Your client ID for identifying the application
  • debug: Enable or disable debug logging
  • userToken: Optional user tokens for tracking user journeys
  • batchSize: Maximum number of events to send in a single batch (default: 10)
  • flushInterval: Interval in milliseconds to send events automatically (default: 5000ms)

Best Practices

  • Initialize with existing IDs when available
  • Generate and store client anonymous ID
  • Update authenticated ID after login
  • Keep both IDs after authentication
  • For SPAs and page reloads
  • Use appropriate flow types for conversion events
  • Flush events before page unload
  • Use selector-based tracking for dynamically loaded content

API Reference

Core Methods

  • init(config): Initialize the analytics SDK
  • setUserToken(token): Set user identification tokens
  • setAnonymousId(id): Set anonymous user ID
  • setAuthenticatedId(id): Set authenticated user ID
  • flush(): Flush queued events
  • shutdown(): Shutdown the SDK

View Events

  • trackProductDetailView: Track product detail view
  • trackSearchResultsView: Track search results view
  • trackOutfitView: Track outfit view
  • trackSimilarProductsView: Track similar products view
  • trackCategoryPageView: Track category page view

Click Events

  • trackProductClick: Track product click
  • trackSearchResultClick: Track search result click
  • trackOutfitItemClick: Track outfit item click
  • trackSimilarProductClick: Track similar product click

Search Events

  • trackSearchQuery: Track search query
  • trackFilterApplied: Track filter applied
  • trackSortChanged: Track sort changed

Conversion Events

  • trackAddToCart: Track add to cart
  • trackSearchAddToCart: Track add to cart from search flow
  • trackOutfitAddToCart: Track add to cart from outfit flow
  • trackSimilarAddToCart: Track add to cart from similar products flow
  • trackPurchase: Track purchase
  • trackSaveForLater: Track save for later

Generic Event Tracking

  • trackEvent: Track custom event

Cross-Device Tracking

The SDK supports cross-device tracking by using persistent identifiers.

Changelog

  • v1.0.0: Initial release
  • v1.1.0: Added support for cross-device tracking
  • v1.2.0: Added support for manual event tracking
  • v1.3.0: Added support for event batching and flushing
  • v1.4.0: Added support for tracking dynamically loaded content
  • v1.5.0: Added support for custom tracking wrappers
  • v1.6.0: Added support for event types and required fields
  • v1.7.0: Added default flow types for all event methods