Skip to main content
The Crave SDK includes a built-in analytics module that tracks key events across the ordering funnel. Use it to measure conversion rates, identify drop-off points, and understand customer behavior.

Event types

The SDK supports four funnel events:
EventWhen to fireFunnel stage
SCANCustomer scans a QR code or visits the storefront URLEntry
CART_VIEWCustomer opens the cart panelConsideration
CHECKOUT_VIEWCustomer reaches the checkout pageIntent
ORDER_PLACEDPayment succeeds and order is createdConversion

Track events with the SDK

import { storefront } from '@/lib/storefront';

// Track a storefront visit
await storefront.analyticsEvents.track(locationId, {
  eventType: 'SCAN',
});

// Track cart view with metadata
await storefront.analyticsEvents.track(locationId, {
  cartId,
  eventType: 'CART_VIEW',
  metadata: {
    itemCount: cart.totalQuantity,
    total: cart.orderTotalWithServiceFee,
  },
});

// Track checkout view
await storefront.analyticsEvents.track(locationId, {
  cartId,
  eventType: 'CHECKOUT_VIEW',
  metadata: {
    fulfillmentMethod: cart.fulfilmentMethod,
  },
});

// Track order placed
await storefront.analyticsEvents.track(locationId, {
  cartId,
  eventType: 'ORDER_PLACED',
  metadata: {
    total: cart.orderTotalWithServiceFee,
    currency: cart.currency,
    itemCount: cart.totalQuantity,
  },
});
The API returns { "status": "accepted" } on success. Events are processed asynchronously.

Where to fire events

Place analytics calls at these points in your storefront:
// SCAN — fire on storefront load
useEffect(() => {
  storefront.analyticsEvents.track(locationId, { eventType: 'SCAN' });
}, []);
// CART_VIEW — fire when cart panel opens
function CartPanel({ isOpen }: { isOpen: boolean }) {
  useEffect(() => {
    if (isOpen && cartId) {
      storefront.analyticsEvents.track(locationId, {
        cartId,
        eventType: 'CART_VIEW',
      });
    }
  }, [isOpen]);
  // ...
}
// CHECKOUT_VIEW — fire on checkout page mount
useEffect(() => {
  if (cartId) {
    storefront.analyticsEvents.track(locationId, {
      cartId,
      eventType: 'CHECKOUT_VIEW',
    });
  }
}, [cartId]);
// ORDER_PLACED — fire on confirmation page
useEffect(() => {
  if (cartId) {
    storefront.analyticsEvents.track(locationId, {
      cartId,
      eventType: 'ORDER_PLACED',
      metadata: { total: cart.orderTotalWithServiceFee },
    });
  }
}, [cartId]);

Custom metadata

The metadata field accepts any key-value pairs. Use it to attach context to events:
await storefront.analyticsEvents.track(locationId, {
  cartId,
  eventType: 'CART_VIEW',
  metadata: {
    source: 'qr_code',
    campaignId: 'summer_promo_2025',
    deviceType: 'mobile',
    itemCount: cart.totalQuantity,
    total: cart.orderTotalWithServiceFee,
  },
});

Google Analytics integration

Forward Crave events to Google Analytics for unified reporting:
import { storefront } from '@/lib/storefront';

type FunnelEvent = 'SCAN' | 'CART_VIEW' | 'CHECKOUT_VIEW' | 'ORDER_PLACED';

const GA_EVENT_MAP: Record<FunnelEvent, string> = {
  SCAN: 'storefront_visit',
  CART_VIEW: 'view_cart',
  CHECKOUT_VIEW: 'begin_checkout',
  ORDER_PLACED: 'purchase',
};

export async function trackEvent(
  locationId: string,
  eventType: FunnelEvent,
  cartId?: string,
  metadata?: Record<string, unknown>
) {
  // Send to Crave
  await storefront.analyticsEvents.track(locationId, {
    cartId,
    eventType,
    metadata,
  });

  // Forward to Google Analytics
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('event', GA_EVENT_MAP[eventType], {
      currency: metadata?.currency ?? 'USD',
      value: metadata?.total ?? 0,
      items: metadata?.items ?? [],
    });
  }
}

View analytics in the Dashboard

Analytics data is available in the Crave Dashboard under Analytics > Storefront. The dashboard shows:
  • Funnel visualization — conversion rates between each stage
  • Event timeline — raw event stream with metadata
  • Location comparison — performance across multiple locations
  • Time-based trends — daily, weekly, and monthly patterns

Best practices

  • Fire events once — deduplicate using a ref or flag to prevent double-counting on re-renders
  • Don’t block the UI — fire analytics calls without await to keep the interface responsive
  • Include metadata — the more context you attach, the more useful your Dashboard reports
  • Test in test mode — test API keys still record analytics events, visible in the Dashboard
// Fire-and-forget pattern (don't await)
storefront.analyticsEvents.track(locationId, {
  cartId,
  eventType: 'CART_VIEW',
}).catch(console.error);

Next steps