1. Add the Nimvue Script

The first step is to add the Nimvue script to your site’s <head> to enable session and page tracking.

Instructions

  1. Log in to your Shopify admin.
  2. Go to Online Store > Themes.
  3. Click the ··· next to your live theme, then select Edit code.
Edit Theme Code
  1. In the left sidebar, navigate to layout > theme.liquid.
  2. Search for </head> and insert the Nimvue script just before it.
You can find your script in the Nimvue portal > Installation > Website Tag. theme.liquid file
  1. Click Save (top-right).
Your basic tracking is now enabled. Confirm it’s working by going to Settings > Tracking Health in your Nimvue dashboard. You should see a Last Event Seen timestamp.

2. Track Checkout & E-Commerce Events

Due to Shopify’s sandboxed checkout, you need a Custom Pixel to capture e-commerce events like checkout_started, item_viewed, etc.

Setting up a Custom Pixel

  1. In Shopify Admin, go to Settings > Customer Events.
  2. Click Add Custom Pixel.
Add Custom Pixel
  1. Name it Nimvue.
Name Pixel
  1. By default, the pixel will only be visible/tracked for users who have granted permission for Marketing & Analytics. You will need to check privacy laws and regulations in your region before unticking those options.
  2. Under the Data Sale setting, you may select “Data collected does not qualify as a data sale”, as Nimvue does not collect personal information, nor do we sell or share any data with third parties.
  3. Paste the following code into the Code field:
// Nimvue Shopify Custom Pixel Integration

const measurementId = '[MEASUREMENT ID]';
const nvScriptSrc = '[SCRIPT URL]';

let nvLoaded = false;
let nvEventQueue = [];

function sendNvEvent(event) {
  if (nvLoaded && typeof nv_create_event === 'function') {
    nv_create_event(event);
  } else {
    nvEventQueue.push(event);
  }
}

analytics.subscribe('page_viewed', (event) => {
  if (nvLoaded) return;

  let locationPathName = event.context.document.location.pathname;

  // Check if the path contains '/checkout'
  if (/\/checkouts?\/cn\//.test(locationPathName)) {
    // Replace everything after /cn/
    locationPathName = locationPathName.replace(/(\/checkouts?\/cn\/)[^\/]+.*/, '$1');
  }

  const nvScript = document.createElement('script');
  nvScript.defer = true;
  nvScript.src = nvScriptSrc;
  nvScript.setAttribute('data-ba-page-path', locationPathName);
  nvScript.setAttribute('data-ba-measurement-id', measurementId);

  nvScript.onload = () => {
    nvLoaded = true;
    nvEventQueue.forEach(evt => {
      if (typeof nv_create_event === 'function') {
        nv_create_event(evt);
      }
    });
    nvEventQueue = [];
  };

  document.head.appendChild(nvScript);
});

// Checkout Started
analytics.subscribe('checkout_started', (event) => {
  const checkout = event.data.checkout || {};
  sendNvEvent({
    event_name: "checkout_started",
    parameters: {
      value: checkout.totalPrice?.amount ?? 0.00,
      item_quantity: checkout.lineItems?.length ?? 1,
      discount_value: checkout.discountsAmount?.amount ?? 0.00
    }
  });
});

// Product Viewed
analytics.subscribe('product_viewed', (event) => {
  const product = event.data.productVariant?.product || {};
  sendNvEvent({
    event_name: "item_viewed",
    parameters: {
      item_id: product.id ?? '',
      item_parent_id: product.id ?? '',
      item_name: product.title ?? '',
      item_brand: product.vendor ?? '',
      item_category: product.type ?? ''
    }
  });
});

// Add to Basket
analytics.subscribe('product_added_to_cart', (event) => {
  const product = event.data.cartLine?.merchandise?.product || {};
  sendNvEvent({
    event_name: "add_to_basket",
    parameters: {
      item_id: product.id ?? '',
      item_parent_id: product.id ?? '',
      item_name: product.title ?? '',
      item_brand: product.vendor ?? '',
      item_category: product.type ?? '',
      item_quantity: event.data.cartLine?.quantity ?? 1
    }
  });
});

// Checkout Complete
analytics.subscribe('checkout_completed', (event) => {
  const checkout = event.data.checkout || {};
  const shippingValue = checkout.shippingLine?.price?.amount ?? 0.00;
  const amount = parseFloat(((parseFloat(checkout.totalPrice?.amount) || 0) - shippingValue).toFixed(2));

  sendNvEvent({
    event_name: "checkout_complete",
    parameters: {
      value: amount,
      item_quantity: checkout.lineItems?.length ?? 1,
      discount_value: checkout.discountsAmount?.amount ?? 0.00,
      shipping_value: shippingValue,
      tax_value: checkout.totalTax?.amount ?? 0.00
    }
  });

  (checkout.lineItems ?? []).forEach((item) => {
    const quantity = item.quantity ?? 1;
    const product = item.variant?.product || {};
    let lineDiscount = 0.00;

    if (Array.isArray(item.discountAllocations)) {
      lineDiscount = item.discountAllocations.reduce((sum, alloc) =>
        sum + (parseFloat(alloc?.amount ?? 0) || 0), 0.00);
    }

    sendNvEvent({
      event_name: "item_purchased",
      parameters: {
        item_id: product.id ?? '',
        item_parent_id: product.id ?? '',
        item_name: item.title ?? item.name ?? '',
        item_brand: product.vendor ?? '',
        item_category: product.type ?? '',
        item_quantity: quantity,
        discount_value: lineDiscount,
        value: item.finalLinePrice?.amount ?? 0.00
      }
    });
  });
});
Important: Replace [MEASUREMENT ID] and [SCRIPT URL] with the values found in Installation > Shopify within the portal for the chosen website. Make sure that the custom pixel is using the Shopify-specific script, and the head tag is using the general website tag.
Tip: If you don’t wish to track every type of event, the only required part of the script is everything before the checkout started event. After that, each event can be separated out.

Final Steps

  • Click Save at the top.
  • Click Connect, then Confirm in the popup.
Save And Connect Custom Pixel
Your Shopify store is now fully integrated with Nimvue. If you run into any issues, please contact support and we’ll be happy to help.

Things to Note

  • Engagement tracking won’t feed through to Nimvue during the checkout flow due to Shopify’s sandbox.
  • However, e-commerce related events will send.
  • The “Engaged Sessions” metric usually remains unaffected, as most users are considered engaged before they reach checkout.