Seentics

Integration

Shopify

Two pastes: a script tag in your theme for the storefront, and a custom pixel for the shopping events and purchases.

Not yet verified on a live store

The WordPress plugin is tested; this setup is not, because it needs a Shopify store. Place a test order after installing and confirm it appears under Revenue. The two things most likely to need attention are listed under "If purchases do not appear".

1. The storefront

  1. In Shopify admin: Online Store → Themes → … → Edit code.
  2. Open layout/theme.liquid and paste this just before </head>, replacing YOUR_WEBSITE_ID with the ID from Settings → Tracking in Seentics.
layout/theme.liquid
<script defer data-website-id="YOUR_WEBSITE_ID" src="https://seentics.com/trackers/seentics.min.js"></script>

This records pageviews, session recordings and heatmaps on the storefront. Checkout pages are not part of the theme, so they need step 2.

2. Shopping events and purchases

  1. In Shopify admin: Settings → Customer events → Add custom pixel. Name it Seentics.
  2. Paste the code below, replace YOUR_WEBSITE_ID and save.
  3. Click Connect.
custom pixel
// Seentics custom pixel for Shopify — purchases, product views, add to cart, checkout.
//
// Shopify admin → Settings → Customer events → Add custom pixel → paste this file.
// Replace YOUR_WEBSITE_ID, save, then Connect.
//
// Pixels run in Shopify's sandbox, so the tracker is loaded here as well, with
// automatic pageviews off (theme-snippet.liquid already sends those). Only the
// shopping events below are sent from this pixel.
//
// UNTESTED against a live store. Before relying on it, place a test order and check
// that the purchase appears under Revenue. Two things to confirm:
//   1. The sandbox's Origin matches the website URL registered in Seentics. Seentics
//      refuses events whose origin host differs from the site's, so if purchases are
//      missing, look for 403 "domain mismatch" in the browser's network tab.
//   2. Visitor identity: the pixel's tracker is its own visitor, separate from the
//      theme's. Purchases will show, but may be credited to "direct" instead of the
//      campaign that brought the visitor.

const WEBSITE_ID = 'YOUR_WEBSITE_ID';
const SCRIPT_URL = 'https://seentics.com/trackers/seentics.min.js';

const tag = document.createElement('script');
tag.defer = true;
tag.src = SCRIPT_URL;
tag.setAttribute('data-website-id', WEBSITE_ID);
tag.setAttribute('data-auto-track', 'false');
document.head.appendChild(tag);

// The tracker is `defer`red; events that arrive first wait here.
const pending = [];
let ready = false;
const send = (name, props) => {
  if (ready) window.seentics.track(name, props);
  else pending.push([name, props]);
};
tag.addEventListener('load', () => {
  ready = true;
  for (const [name, props] of pending.splice(0)) window.seentics.track(name, props);
});

const money = (m) => (m && typeof m.amount === 'number' ? Math.round(m.amount * 100) / 100 : 0);
const line = (l) => ({
  name: l.merchandise?.product?.title || l.title || '',
  sku: l.merchandise?.sku || '',
  qty: l.quantity || 1,
  price: money(l.merchandise?.price),
});

analytics.subscribe('product_viewed', (e) => {
  const v = e.data.productVariant;
  send('view_item', {
    item_id: v.product?.id,
    product_name: v.product?.title,
    sku: v.sku || '',
    value: money(v.price),
    currency: v.price?.currencyCode,
  });
});

analytics.subscribe('product_added_to_cart', (e) => {
  const l = e.data.cartLine;
  send('add_to_cart', {
    item_id: l.merchandise?.product?.id,
    product_name: l.merchandise?.product?.title,
    sku: l.merchandise?.sku || '',
    value: money(l.cost?.totalAmount),
    currency: l.cost?.totalAmount?.currencyCode,
    qty: l.quantity,
  });
});

analytics.subscribe('checkout_started', (e) => {
  const c = e.data.checkout;
  send('begin_checkout', {
    value: money(c.totalPrice),
    currency: c.currencyCode,
    qty: (c.lineItems || []).reduce((n, i) => n + (i.quantity || 0), 0),
  });
});

analytics.subscribe('checkout_completed', (e) => {
  const c = e.data.checkout;
  const items = (c.lineItems || []).map((i) => ({
    name: i.title,
    sku: i.variant?.sku || '',
    qty: i.quantity,
    price: money(i.variant?.price),
  }));
  send('purchase', {
    value: money(c.totalPrice),
    currency: c.currencyCode,
    // Seentics counts one order per id, so a repeated event is harmless.
    order_id: String(c.order?.id || c.token),
    product_name: items[0]?.name || '',
    user_type: c.order?.customer?.isFirstOrder === false ? 'returning' : 'new',
    items,
  });
});

It sends view_item, add_to_cart, begin_checkout and purchase. The purchase carries the order total, currency, order ID and line items, and appears under Revenue. The other three can be used as steps in a funnel.

3. Test it

  1. Place a test order (Shopify's Bogus Gateway, or a 100% discount code).
  2. In Seentics, open Revenue. The order shows within a minute.

If purchases do not appear

  • Domain mismatch. Seentics accepts events only from the website URL registered for the ID. Shopify runs pixels in a sandbox; if its address differs from your site's, the browser's Network tab shows a 403 from /collect. Check that the URL on the website in Seentics is your shop's public domain, not the myshopify.com address, and write to support if it still fails.
  • Attribution. The pixel is a separate visitor from the theme's tracker, so a purchase may be credited to "direct" instead of the campaign that brought the shopper. The total is still right.
  • Nothing at all. Confirm the pixel is Connected and the website ID is correct. Shopify's customer-events screen has a Test mode that shows each event as it fires.

Refunds are not reported; send them with seentics.track('refund', …) from your own code if you need revenue net of them.