> ## Documentation Index
> Fetch the complete documentation index at: https://docs.craveup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics

> Track storefront events and measure ordering funnel performance.

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 public SDK accepts three cart-authorized interaction events. Crave records `ORDER_PLACED`
server-side only after payment succeeds and the order is created, so clients cannot forge a
conversion.

| Event           | When to fire                                          | Funnel stage  |
| --------------- | ----------------------------------------------------- | ------------- |
| `SCAN`          | Customer scans a QR code or visits the storefront URL | Entry         |
| `CART_VIEW`     | Customer opens the cart panel                         | Consideration |
| `CHECKOUT_VIEW` | Customer reaches the checkout page                    | Intent        |
| `ORDER_PLACED`  | Recorded automatically by Crave after order creation  | Conversion    |

## Track events with the SDK

<CodeGroup>
  ```ts SDK theme={null}
  import { storefront } from '@/lib/storefront';

  // Track a storefront visit
  await storefront.analyticsEvents.track(locationId, {
    cartId,
    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,
    },
  });
  ```

  ```bash REST theme={null}
  curl -X POST "https://api.craveup.com/api/v1/storefront/locations/loc_123/analytics-events" \
    -H "Content-Type: application/json" \
    -H "X-Cart-Token: CART_CAPABILITY" \
    -H "Idempotency-Key: analytics_01" \
    -d '{
      "cartId": "cart_456",
      "eventType": "CHECKOUT_VIEW"
    }'
  ```
</CodeGroup>

The API returns `{ "status": "accepted" }` after it authorizes the cart and records or deduplicates
the event.

## Where to fire events

Place analytics calls at these points in your storefront:

```tsx filename="src/app/page.tsx" theme={null}
// SCAN — fire after the ordering session creates or restores the cart
useEffect(() => {
  if (cartId) {
    storefront.analyticsEvents.track(locationId, { cartId, eventType: "SCAN" });
  }
}, [cartId]);
```

```tsx filename="src/components/CartPanel.tsx" theme={null}
// 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]);
  // ...
}
```

```tsx filename="src/app/checkout/page.tsx" theme={null}
// CHECKOUT_VIEW — fire on checkout page mount
useEffect(() => {
  if (cartId) {
    storefront.analyticsEvents.track(locationId, {
      cartId,
      eventType: "CHECKOUT_VIEW",
    });
  }
}, [cartId]);
```

Do not send `ORDER_PLACED` from a browser or mobile client. Poll the authoritative order result for
the UI; the API writes the conversion event during server-side order creation.

## Custom metadata

The `metadata` field accepts any key-value pairs. Use it to attach context to events:

```ts theme={null}
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:

```ts filename="src/lib/analytics.ts" theme={null}
import { storefront } from "@/lib/storefront";

type PublicFunnelEvent = "SCAN" | "CART_VIEW" | "CHECKOUT_VIEW";

const GA_EVENT_MAP: Record<PublicFunnelEvent, string> = {
  SCAN: "storefront_visit",
  CART_VIEW: "view_cart",
  CHECKOUT_VIEW: "begin_checkout",
};

export async function trackEvent(
  locationId: string,
  eventType: PublicFunnelEvent,
  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 ?? [],
    });
  }
}
```

If you also send a Google Analytics purchase event, do so only after
`checkout.getOrderResult()` returns `completed`; do not forward that event to the Crave public
analytics endpoint.

## 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 outside production first** — confirm events appear in the intended Dashboard environment

```ts theme={null}
// Fire-and-forget pattern (don't await)
storefront.analyticsEvents
  .track(locationId, {
    cartId,
    eventType: "CART_VIEW",
  })
  .catch(console.error);
```

## Next steps

<CardGroup cols={2}>
  <Card title="Order Tracking" icon="map-pin" href="/guides/order-tracking">
    Track order status after checkout.
  </Card>

  <Card title="Deployment" icon="rocket" href="/guides/deployment">
    Deploy your storefront and go live.
  </Card>
</CardGroup>
