Skip to main content

Overview

The AutoTrackPlugin automatically tracks common events based on DOM elements and user interactions, reducing manual tracking code.

Installation

import { Refine, AutoTrackPlugin } from '@refine-ai/sdk';

const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789'
});

refine.use(new AutoTrackPlugin({
  pageViews: true,
  clicks: {
    selector: '[data-refine-item]',
    extractItemId: (el) => el.dataset.refineItem
  },
  viewability: {
    enabled: true,
    threshold: 0.5,
    duration: 1000
  }
}));

Options

pageViews
boolean
default:"false"
Automatically track page view events on navigation.
clicks
ClickConfig
Configuration for automatic click tracking.
viewability
ViewabilityConfig
Configuration for automatic viewability tracking.

Click Tracking

Automatically track clicks on product elements:
refine.use(new AutoTrackPlugin({
  clicks: {
    selector: '[data-refine-item]',
    extractItemId: (el) => el.dataset.refineItem,
    extractPosition: (el) => parseInt(el.dataset.position || '0')
  }
}));

Click Config Options

clicks.selector
string
required
CSS selector for clickable product elements.
clicks.extractItemId
(el: Element) => string
required
Function to extract the product ID from a clicked element.
clicks.extractPosition
(el: Element) => number
Function to extract the position from a clicked element. Defaults to 0.

HTML Setup for Click Tracking

<div class="product-grid">
  <div class="product" 
       data-refine-item="sku_001" 
       data-position="0">
    <img src="..." alt="Product 1" />
    <h3>Product Title</h3>
  </div>
  <div class="product" 
       data-refine-item="sku_002" 
       data-position="1">
    <img src="..." alt="Product 2" />
    <h3>Product Title</h3>
  </div>
</div>

Viewability Tracking

Automatically track when products become visible:
refine.use(new AutoTrackPlugin({
  viewability: {
    enabled: true,
    selector: '[data-refine-item]',
    threshold: 0.5,    // 50% visible
    duration: 1000,    // for 1 second
    extractItemId: (el) => el.dataset.refineItem,
    extractPosition: (el) => parseInt(el.dataset.position || '0')
  }
}));

Viewability Config Options

viewability.enabled
boolean
default:"false"
Enable automatic viewability tracking.
viewability.selector
string
CSS selector for viewable elements. Defaults to clicks.selector.
viewability.threshold
number
default:"0.5"
Percentage of element that must be visible (0.0 to 1.0).
viewability.duration
number
default:"1000"
Milliseconds element must be visible before tracking.
viewability.extractItemId
(el: Element) => string
Function to extract product ID. Defaults to clicks.extractItemId.
viewability.extractPosition
(el: Element) => number
Function to extract position. Defaults to clicks.extractPosition.

Page View Tracking

Track page views automatically:
refine.use(new AutoTrackPlugin({
  pageViews: true
}));
This tracks:
  • Initial page load
  • SPA navigation (using History API)
  • Hash changes

Complete Configuration

import { Refine, AutoTrackPlugin } from '@refine-ai/sdk';

const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789'
});

refine.use(new AutoTrackPlugin({
  // Track page views
  pageViews: true,
  
  // Track clicks on product cards
  clicks: {
    selector: '[data-refine-item]',
    extractItemId: (el) => {
      return (el as HTMLElement).dataset.refineItem || '';
    },
    extractPosition: (el) => {
      return parseInt((el as HTMLElement).dataset.position || '0');
    }
  },
  
  // Track viewability
  viewability: {
    enabled: true,
    threshold: 0.5,
    duration: 1000
  }
}));

HTML Data Attributes

The plugin expects specific data attributes on your product elements:
<!-- Search results -->
<div id="search-results" data-refine-surface="search_results" data-refine-source="text-search">
  <div class="product" 
       data-refine-item="sku_001" 
       data-position="0"
       data-refine-serve-id="srv_abc123">
    <!-- Product content -->
  </div>
</div>

<!-- Recommendations -->
<div id="similar-items" data-refine-surface="product_page" data-refine-source="similar-items">
  <div class="product" 
       data-refine-item="sku_002" 
       data-position="0"
       data-refine-serve-id="srv_xyz789">
    <!-- Product content -->
  </div>
</div>

Required Attributes

AttributePurpose
data-refine-itemProduct ID for the element
data-positionPosition in the results (0-indexed)

Optional Attributes

AttributePurpose
data-refine-surfaceWhere products are displayed
data-refine-sourceHow products were generated
data-refine-serve-idLinks to original serve event

Dynamic Content

For dynamically loaded content, the plugin uses MutationObserver to detect new elements:
// New products added dynamically are automatically tracked
const newProduct = document.createElement('div');
newProduct.className = 'product';
newProduct.dataset.refineItem = 'sku_new';
newProduct.dataset.position = '24';

document.getElementById('search-results').appendChild(newProduct);
// Plugin automatically starts tracking this element

Combining with Manual Tracking

You can use AutoTrackPlugin alongside manual tracking:
// Auto-track plugin handles clicks and views
refine.use(new AutoTrackPlugin({
  clicks: {
    selector: '[data-refine-item]',
    extractItemId: (el) => el.dataset.refineItem
  },
  viewability: { enabled: true, threshold: 0.5, duration: 1000 }
}));

// Manual tracking for search (to get the context)
const results = await refine.search.text({ query: 'shoes', topK: 24 });
const searchContext = refine.events.trackSearch('shoes', results.results, {
  surface: 'search_results',
  totalResults: results.totalResults
});

// Render products with data attributes
renderProducts(results.results);
// Auto-track plugin will handle click and view tracking

Framework Integration

React

import { useEffect } from 'react';
import { refine } from '@/lib/refine';
import { AutoTrackPlugin } from '@refine-ai/sdk';

export function ProductGrid({ products }) {
  useEffect(() => {
    // Plugin is typically initialized once at app level
    // But you can re-configure for specific pages
  }, []);

  return (
    <div data-refine-surface="search_results" data-refine-source="text-search">
      {products.map((product, index) => (
        <div
          key={product.productId}
          className="product"
          data-refine-item={product.productId}
          data-position={index}
        >
          <img src={product.imageUrl} alt={product.title} />
          <h3>{product.title}</h3>
          <p>${product.price}</p>
        </div>
      ))}
    </div>
  );
}

Vue

<template>
  <div data-refine-surface="search_results" data-refine-source="text-search">
    <div
      v-for="(product, index) in products"
      :key="product.productId"
      class="product"
      :data-refine-item="product.productId"
      :data-position="index"
    >
      <img :src="product.imageUrl" :alt="product.title" />
      <h3>{{ product.title }}</h3>
      <p>${{ product.price }}</p>
    </div>
  </div>
</template>

Debugging Auto-Track

Combine with DebugPlugin to see what’s being tracked:
refine.use(new DebugPlugin({ logEvents: true }));
refine.use(new AutoTrackPlugin({
  pageViews: true,
  clicks: { selector: '[data-refine-item]', extractItemId: el => el.dataset.refineItem },
  viewability: { enabled: true, threshold: 0.5, duration: 1000 }
}));

// Console will show:
// [Refine AutoTrack] Click detected: sku_001 at position 3
// [Refine AutoTrack] View tracked: sku_002 at position 0
// [Refine AutoTrack] Page view: /products/shoes

Next Steps