1.0.14 • Published 4 months ago

@shoppi/analytics v1.0.14

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

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 MethodDefault Flow Type
trackSearchResultsViewFlowType.SEARCH
trackSearchResultClickFlowType.SEARCH
trackSearchQueryFlowType.SEARCH
trackFilterAppliedFlowType.SEARCH
trackSortChangedFlowType.SEARCH
trackOutfitViewFlowType.OUTFIT
trackOutfitItemClickFlowType.OUTFIT
trackSimilarProductClickFlowType.SIMILAR
trackSimilarProductsViewFlowType.SIMILAR
trackCategoryPageViewFlowType.CATEGORY
trackProductDetailViewFlowType.DIRECT
trackProductClickFlowType.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 TypeEvent SubtypeDescriptionBase Required FieldsAdditional Required FieldsFlow Type Support
SEARCHQUERYTrack search query executioneventType, eventSubtype, eventName, flow, queryID, timestampqueryAll
FILTER_APPLIEDTrack when filters are appliedeventType, eventSubtype, eventName, flow, queryID, timestampfilterName, filterValueAll
FILTER_REMOVEDTrack when filters are removedeventType, eventSubtype, eventName, flow, queryID, timestampfilterName, filterValueAll
SORT_CHANGEDTrack sort order changeseventType, eventSubtype, eventName, flow, queryID, timestampsortOptionAll
ZERO_RESULTSTrack searches with no resultseventType, eventSubtype, eventName, flow, queryID, timestampqueryAll
CLICKPRODUCTTrack product clickseventType, eventSubtype, eventName, flow, objectID, timestamp-All
SEARCH_RESULTTrack search result clickseventType, eventSubtype, eventName, flow, objectID, timestampqueryID, positionSEARCH
SIMILAR_PRODUCTTrack similar product clickseventType, eventSubtype, eventName, flow, objectID, timestampsourceObjectID, positionSIMILAR
OUTFIT_ITEMTrack outfit item clickseventType, eventSubtype, eventName, flow, objectID, timestampoutfitID, positionOUTFIT
OUTFITTrack outfit clickseventType, eventSubtype, eventName, flow, objectID, timestampoutfitIDOUTFIT
PAGINATIONTrack pagination clickseventType, eventSubtype, eventName, flow, objectID, timestamp-All
FILTERTrack filter clickseventType, eventSubtype, eventName, flow, objectID, timestamp-All
SORTTrack sort option clickseventType, eventSubtype, eventName, flow, objectID, timestamp-All
SUGGESTIONTrack search suggestion clickseventType, eventSubtype, eventName, flow, objectID, timestampsuggestion, queryIDSEARCH
VIEWPRODUCT_DETAILTrack product detail viewseventType, eventSubtype, eventName, flow, timestampobjectIDAll
SEARCH_RESULTSTrack search results viewseventType, eventSubtype, eventName, flow, timestampqueryID, resultsCountSEARCH
SIMILAR_PRODUCTSTrack similar products viewseventType, eventSubtype, eventName, flow, timestampsourceObjectIDSIMILAR
OUTFITTrack outfit viewseventType, eventSubtype, eventName, flow, timestampoutfitIDOUTFIT
OUTFIT_COLLECTIONTrack outfit collection viewseventType, eventSubtype, eventName, flow, timestampoutfitIDOUTFIT
CATEGORY_PAGETrack category page viewseventType, eventSubtype, eventName, flow, timestampcategoryIDCATEGORY
CONVERSIONPURCHASETrack product purchaseseventType, eventSubtype, eventName, flow, objectID, timestampvalue, currencyAll
ADD_TO_CARTTrack add to cart actionseventType, eventSubtype, eventName, flow, objectID, timestampquantityAll
SAVE_FOR_LATERTrack save for later actionseventType, eventSubtype, eventName, flow, objectID, timestamp-All
IMPRESSIONPRODUCT_LISTTrack product list impressionseventType, eventSubtype, eventName, flow, items, timestamp-All
SIMILAR_PRODUCTSTrack similar products impressionseventType, eventSubtype, eventName, flow, items, timestampsourceObjectIDSIMILAR
OUTFIT_LISTTrack outfit list impressionseventType, eventSubtype, eventName, flow, items, timestampoutfitIDOUTFIT
SEARCH_RESULTSTrack search results impressionseventType, eventSubtype, eventName, flow, items, timestampqueryID, resultsCountSEARCH

Flow Types and Required Fields

Flow TypeDescriptionRequired FieldsUse Case
DIRECTDirect navigation or interaction-User directly navigates to a product or takes action without context
SEARCHFrom search resultsqueryIDUser interacts with content from search results
SIMILARFrom similar product recommendationssourceObjectIDUser interacts with similar product recommendations
OUTFITFrom outfit/collection recommendationsoutfitIDUser interacts with outfit or collection content
CATEGORYFrom category browsingcategoryIDUser 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
1.0.14

4 months ago

1.0.13

4 months ago

1.0.12

4 months ago

1.0.11

4 months ago

1.0.10

4 months ago

1.0.9

4 months ago

1.0.8

5 months ago

1.0.7

5 months ago

1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago