Skip to Content

Headless Shopify Tracking

Add Vendo analytics tracking to a headless Shopify storefront built on Hydrogen.

Last reviewed September 15, 2026

The web pixel of the standard Vendo Shopify app does not apply to headless Shopify storefronts built on Hydrogen . These storefronts have no Online Store theme for Shopify to inject the pixel into. Instead, Vendo hooks into Hydrogen’s own useAnalytics event bus and forwards events from there.

We maintain a reference Hydrogen starter and drop-in files for existing projects:

Repository: vendo-analytics/vendo-shopify-headless-tracking  (public).

How it works

Browser Hydrogen <Analytics.Provider> ── publishes events ──▶ useAnalytics() bus <VendoTracking> ┌───────────────┴───────────────┐ ▼ ▼ Variant A: vendo.track() Variant B: mixpanel.track() │ │ ▼ ▼ Your Vendo ingest API api-js.mixpanel.com ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ Mixpanel OneSignal BigQuery (or any configured destination)

Hydrogen emits standard analytics events on its internal bus, for example page_viewed, product_viewed and cart_updated. The Vendo tracking script subscribes to these events and forwards them to the destination that you choose.

Choose your variant

VariantDestinationWhen to use
A. Vendo Ingestion (recommended)Your Vendo ingest API → any configured destinationYou want one setup that can fan out to Mixpanel, OneSignal, Segment, BigQuery and other destinations. You can pick or change destinations from Vendo without re-deploying.
B. Mixpanel DirectBrowser → api-js.mixpanel.comMixpanel is your only destination and you want zero dependency on Vendo’s ingest infrastructure.

If you are not sure, start with Vendo Ingestion. It works with any destination. You do not have to re-deploy your Hydrogen storefront when your destination preferences change.

Prerequisites

  • A Hydrogen storefront (this guide targets Hydrogen 2025.x with React Router 7)
  • Node.js 18+
  • A Vendo workspace
  • Variant A only: your Vendo ingest host URL and write key (we provide these during onboarding)
  • Variant B only: a Mixpanel project token

1. Add the tracker file

Copy drop-in/vendo-ingestion/VendoTrackingIngestion.jsx into app/components/VendoTrackingIngestion.jsx in your Hydrogen project.

2. Wire it into app/root.jsx

Apply the patch in drop-in/vendo-ingestion/snippets/root.jsx.diff. It adds three things:

  • An import for the tracker component
  • A tracking field in your root loader’s return value (forwards env vars to the client)
  • A <VendoTracking config={data.tracking} /> render inside <Analytics.Provider>

3. Allow your ingest host in CSP

Apply the patch in drop-in/vendo-ingestion/snippets/entry.server.jsx.diff. It adds your ingest host to both connect-src (so the SDK can POST events) and script-src (so the browser can fetch <host>/v1/sdk.js).

4. Set env vars

PUBLIC_VENDO_INGEST_HOST=https://track.your-domain.com PUBLIC_VENDO_WRITE_KEY=your-vendo-write-key

Your Vendo onboarding contact provides both values.

5. Verify

  1. Build and run your Hydrogen storefront.
  2. Browse a couple of pages and view a product.
  3. In the Network tab of your browser, filter by your ingest host. You should see:
    • A GET /v1/sdk.js (loaded once on first page)
    • One or more POST /collect requests. Each request is a batch that contains page, track, and identify events.
  4. In your Vendo workspace, open the Live Events tab for your source. New events should appear within seconds.

Path B — Mixpanel Direct

1. Install mixpanel-browser

npm install mixpanel-browser

2. Add the tracker file

Copy drop-in/mixpanel/VendoTrackingMixpanel.jsx into app/components/VendoTrackingMixpanel.jsx.

3. Wire it into app/root.jsx

Apply the patch in drop-in/mixpanel/snippets/root.jsx.diff. It has the same shape as Path A, but it imports VendoTrackingMixpanel and forwards the mixpanelToken and mixpanelDebug env vars.

4. Allow Mixpanel hosts in CSP

Apply the patch in drop-in/mixpanel/snippets/entry.server.jsx.diff. It adds https://api-js.mixpanel.com and https://api.mixpanel.com to connect-src.

5. Set env vars

PUBLIC_MIXPANEL_TOKEN=your-mixpanel-project-token PUBLIC_MIXPANEL_DEBUG=false

For verbose Mixpanel console logging in development, set PUBLIC_MIXPANEL_DEBUG=true.

6. Verify

  1. Build and run your Hydrogen storefront.
  2. Browse a couple of pages and view a product.
  3. In the Network tab of your browser, filter by api-js.mixpanel.com. You should see POSTs with Page Viewed, Product Viewed and the other events.
  4. Check that the same events appear in the Live View of your Mixpanel project.

Event reference

Both variants forward the same five Hydrogen events. <Analytics.Provider> and its built-in helpers publish each event. The Hydrogen skeleton routes already use these helpers (for example <Analytics.ProductView> and <Analytics.CollectionView>).

Hydrogen eventTracker callWhen it fires
page_viewedpage() / track('Page Viewed')On every route change
product_viewedtrack('Product Viewed', ...)On product detail page load
collection_viewedtrack('Collection Viewed', ...)On collection page load
cart_viewedtrack('Cart Viewed', ...)When the cart drawer is opened
cart_updatedtrack('Cart Updated', ...)When items are added, removed, or quantity changes

Adding custom events

To track more events (for example search_submitted or wishlist_added), add a new subscribe(...) block to your tracker component. Then add a matching publish(...) call in the component that triggers the event. For the full pub/sub API, see Shopify’s analytics docs .

Identity model

Headless storefronts hand off to Shopify’s hosted checkout. For cross-boundary attribution to work, the browser identity and the checkout identity must match.

Both variants bridge identity using Shopify’s _shopify_y first-party cookie:

VariantBridge
Vendo IngestionCalls vendo.identify(null, { shopify_visitor_id }) on first event. The Vendo anonymousId is then associated with the Shopify visitor ID, so order events that arrive server-side (via your Shopify destination → Vendo) stitch to the same profile.
Mixpanel DirectUses _shopify_y as the Mixpanel distinct_id. Order events sent through your Vendo→Mixpanel pipeline that include the same _shopify_y value land on the same Mixpanel profile.

If _shopify_y is not set (for example, the user has third-party cookies disabled in some configurations), the tracker falls back to the SDK’s own anonymous ID. You still capture browse activity, but stitching to checkout-side events for that visitor is best-effort.

Limitations

  • Checkout pages. Checkout runs on Shopify’s domain, so storefront-side tracking stops at “Checkout started.” Capture order events server-side through your Shopify webhook → Vendo pipeline.
  • Server-side rendering. Hydrogen renders pages on Oxygen workers, but the tracker runs only in the browser. It does nothing during SSR. The page_viewed event fires after hydration.
  • CSP nonce. Hydrogen uses CSP nonces by default. Both tracker scripts are added inside the Hydrogen <Analytics.Provider> lifecycle, so they inherit the correct nonce automatically. If you customize CSP, make sure the ingest host (Variant A) or Mixpanel hosts (Variant B) remain in connect-src / script-src.

Troubleshooting

No events in network tab. Check the browser console for [Vendo] warnings. Most likely cause: the env vars are not set, or your root loader does not pass tracking to the <VendoTracking> component.

CSP errors blocking the SDK. Confirm that entry.server.jsx includes the right origins for the variant that you use. For Variant A, both connect-src and script-src need to include PUBLIC_VENDO_INGEST_HOST.

Events fire but do not appear in Mixpanel/Vendo. Verify that the write key (Variant A) or project token (Variant B) is correct and matches the environment. In Variant A, also confirm that the ingest API is healthy with GET <host>/health.

Duplicate events. If you see each event fire twice, the tracker is probably mounted twice. Check that you have a single <VendoTracking> render inside <Analytics.Provider>.

Need help?

When you contact support, give your workspace, the source or destination name, the job ID and the first error message.

support@vendodata.com
Last updated on