Skip to content

Integration

This page walks you through integrating your eCommerce store with Shuttlebase. The integration has two steps: granting Google Analytics 4 access and adding the tracking code to your site. Once both are done, Shuttlebase can run and analyze CRO experiments on your store automatically.

Every snippet below contains a <TRACKING_ID> placeholder. Replace it with the unique tracking ID Shuttlebase provides for your account. If Shuttlebase sent you a personalized link to this page, your ID is filled in automatically.

Step 1: Grant Google Analytics (GA4) access

Section titled “Step 1: Grant Google Analytics (GA4) access”
  1. Log in to Google Analytics.
  2. Choose the GA4 property associated with your eCommerce store from the account list.
  3. Click the Admin gear icon in the bottom-left corner.
  4. Under the Account column, click Account Access Management.
  5. Click the + icon in the top-right corner, then select Add users.
  6. Enter the email address of Shuttlebase’s technical lead: evyatar@shuttlebase.com.
  7. Set the permissions to Analyst and click Add to send the invitation.

The tracking code needs to run on every page of your site. The steps differ by platform, so expand the section that matches yours.

Shopify

Add the tracking code to the end of the <head> section of your theme.liquid file. The code needs to be added as-is, without any additions.

<script src="https://cdn.moonshot-ai.com/snippets/<TRACKING_ID>.js"></script>

Purchases on Shopify are tracked through a custom pixel. These steps cover standard Shopify, not Hydrogen.

  1. Open the pixel screen. Depending on your Shopify version it is under Settings, then Customer Events, or on older versions under Settings, then Checkout, in the Order status page section.
  2. Under Custom Pixels, click Add Custom Pixel and name it MoonshotAI tracking.
  3. Permissions: choose Required and check only Analytics.
  4. Data Sale: choose “Data collected does not qualify as data sale”.
  5. Paste the following code and click save.
const REMOTE_LOADER_URL = "https://cdn.moonshot-ai.com/shopify_pixel/shopify_pixel_events_handler.js";
const project_id = "<TRACKING_ID>";
const __MSAI_PIXEL_DEBUG__ = false;
function loadRemoteScript(url, debug = false) {
return new Promise((resolve, reject) => {
try {
const script = document.createElement("script");
script.src = `${url}`;
script.async = true;
script.referrerPolicy = "no-referrer";
script.onload = () => {
if (debug) {
console.log(`[pixel] remote url ${url} loaded`);
}
resolve();
};
script.onerror = (e) => {
if (debug) {
console.warn(`[pixel] remote url ${url} failed`, e);
}
reject(e);
};
document.head.appendChild(script);
} catch (e) {
if (debug) {
console.warn(`[pixel] bootstrap error for remote url ${url}`, e);
}
reject(e);
}
});
}
window.msaiAllowIframe = true;
const remoteLoaderPromise = loadRemoteScript(REMOTE_LOADER_URL, __MSAI_PIXEL_DEBUG__);
/**
* Flag to track if we've already set up the remote handler properties.
* @type {boolean}
*/
let remoteHandlerInitialized = false;
/**
* Initializes the remote handler with project-specific properties.
* This only runs once to avoid setting up the properties multiple times.
*/
function initializeRemoteHandler() {
if (remoteHandlerInitialized) return;
window.__PIXEL_REMOTE__.projectId = project_id;
window.__PIXEL_REMOTE__.loadMsaiClientScript = async () => {
await loadRemoteScript(`https://cdn.moonshot-ai.com/snippets/${project_id}.js`, __MSAI_PIXEL_DEBUG__);
};
remoteHandlerInitialized = true;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function processEventWithRetry(event, eventName, maxRetries = 5, initialDelay = 100) {
let retries = 0;
let delay = initialDelay;
while (retries <= maxRetries) {
if (window.__PIXEL_REMOTE__ && typeof window.__PIXEL_REMOTE__.handleEvent === "function") {
initializeRemoteHandler();
window.__PIXEL_REMOTE__.handleEvent(event);
return true;
} else {
if (retries === maxRetries) {
__MSAI_PIXEL_DEBUG__ && console.warn(`[pixel] remote handler not available after ${maxRetries} retries. Event dropped:`, eventName);
return false;
}
__MSAI_PIXEL_DEBUG__ && console.log(`[pixel] waiting for remote handler to be available. Retry ${retries + 1}/${maxRetries}`);
await sleep(delay);
delay *= 2;
retries++;
}
}
return false;
}
async function subscribeToEvents() {
try {
analytics.subscribe("all_events", async (ev) => {
try {
await remoteLoaderPromise;
const success = await processEventWithRetry(ev, ev.name);
if (success && __MSAI_PIXEL_DEBUG__) {
console.log(`[pixel] successfully processed event: ${ev}`);
}
} catch (error) {
__MSAI_PIXEL_DEBUG__ && console.warn(`[pixel] error processing event: ${ev}`, error);
}
});
console.log("[pixel] loaded");
} catch (e) {
__MSAI_PIXEL_DEBUG__ && console.warn("[pixel] failed to subscribe all events", e);
}
}
subscribeToEvents();
VTEX
  1. Access your website’s HTML files.
  2. Locate the <head> section of your site’s HTML.
  3. Paste the tracking code just before the closing </head> tag.
  4. Save and upload the changes to your server.
<script src="https://cdn.moonshot-ai.com/snippets/<TRACKING_ID>.js"></script>

Add a handleEvents function that listens for the vtex:orderPlaced event, and have it send the revenue event below with the order’s transaction parameters filled in.

Shuttlebase tracks purchases through a revenue event pushed to the snippet’s queue. Replace the {placeholder} values with the actual transaction parameters from the completed order. The comments mark which fields are required.

window['msaiClient'] = window['msaiClient'] || [];
window['msaiClient'].push({
event_type: 'revenue', // (REQUIRED)
event_value: 123.45, // (REQUIRED) number - The decimal money amount
transaction_currency: "{currency}", // (REQUIRED) string - 3-letter ISO 4217 currency code (i.e. USD, EUR, GBP)
order_id: "{order_id}", // (REQUIRED) string - Unique order identifier
transaction_id: "{transaction_id}", // (OPTIONAL) string | null - Unique transaction identifier
discount_allocations: [ // (OPTIONAL) Array of Discounts applied to the entire cart and/or shipping. NOTE if targeting specific products, use the discount_allocations array in the line_items_info to target those specific products.
{
amount: { // (REQUIRED IF DISCOUNT) The total amount of the discount applied to the entire cart or shipping line
amount: {discount_amount}, // number - The decimal money amount
currency_code: "USD" // string - 3-letter ISO 4217 currency code (if different from transaction_currency)
},
target_type: "{target_type}", // (REQUIRED) string - "LINE_ITEM" for discounts to the entire cart or "SHIPPING_LINE" for discount to entire shipping line
title: "{discount_code}", // (REQUIRED IF DISCOUNT CODE) string - The discount code (i.e. "FREESHIP", "CART20") if applicable
type: "{type}", // (REQUIRED) string - "AUTOMATIC", "DISCOUNT_CODE"
value: { // The discount value
amount: {discount_amount}, // (REQUIRED IF FIXED AMOUNT) number - Fixed amount discount (if applicable)
currency_code: "USD", // (REQUIRED IF FIXED AMOUNT) string - Currency code for fixed amount (if different from transaction_currency)
percentage: 15 // (REQUIRED IF PERCENTAGE) number - Percentage discount (if applicable)
}
}
],
line_items_info: [ // (REQUIRED) Array of detailed information about each item type in the order
{
id: "{line_item_id}", // (REQUIRED) string - Globally unique identifier (Normally Product ID)
quantity: 1, // (REQUIRED) number - Quantity of this item type
title: "{product_title}", // (Optional) string - The title of the line item (If different from product title)
final_line_price: { // Combined price after line-level discounts
amount: 99.99, // (REQUIRED) number - The decimal money amount
currency_code: "USD" // (REQUIRED IF DIFFERENT FROM TRANSACTION_CURRENCY) string | null - Only include if the currency is different from the transaction_currency
},
variant: { // (REQUIRED) ProductVariant | null - Variant information
id: "{variant_id}", // (OPTIONAL) string | null - Globally unique identifier (If not provided, the product_id will be used)
title: "{variant_title}", // (OPTIONAL) string | null - The product variant's title (If not provided, the product_title will be used)
sku: "{sku}", // (OPTIONAL) string | null - SKU (stock keeping unit) (Can be the product_sku)
price: { // (REQUIRED) The product variant's price
amount: 99.99, // (REQUIRED) number - The decimal money amount
currency_code: "USD" // (REQUIRED IF DIFFERENT FROM TRANSACTION_CURRENCY) string | null - Only include if the currency is different from the transaction_currency
},
product: { // (REQUIRED) The product object
id: "{product_id}", // (REQUIRED) string | null - The ID of the product
title: "{product_title}", // (REQUIRED) string - The product's title
type: "{product_type}", // (OPTIONAL) string | null - The product type
vendor: "{vendor}", // (OPTIONAL) string - The product's vendor name
url: "{product_url}" // (OPTIONAL) string | null - The URL of the product
}
},
selling_plan_allocation: { // (OPTIONAL) Subscription information
selling_plan: { // (OPTIONAL) SellingPlan
id: "{selling_plan_id}", // (REQUIRED IF SELLING PLAN) string - Globally unique identifier
name: "{selling_plan_name}" // (REQUIRED IF SELLING PLAN) string - Name of the plan (i.e. "6 weeks of prepaid granola, delivered weekly")
}
},
discount_allocations: [ // (OPTIONAL) Discounts applied to this specific line item
{
amount: { // (REQUIRED IF DISCOUNT) The monetary value allocated to the discount
amount: 5.00, // number - The decimal money amount
currency_code: "USD" // string - 3-letter ISO 4217 currency code
},
discount_application: { // (REQUIRED IF DISCOUNT) The discount info
target_type: "{target_type}", // (REQUIRED) string - "LINE_ITEM" for discounts to the product or "SHIPPING_LINE" for discount to specific product's shipping NOTE: If shipping discount is for all products, use the discount_allocations array in the top level of the event
title: "{discount_code}", // (REQUIRED IF DISCOUNT CODE) string - The discount code (i.e. "SAVE20")
type: "{type}", // (REQUIRED) string - "AUTOMATIC", "DISCOUNT_CODE"
value: {
amount: 5.00, // (REQUIRED IF FIXED AMOUNT) number - Fixed amount discount (if applicable)
currency_code: "USD", // (REQUIRED IF FIXED AMOUNT) string - Currency code for fixed amount
percentage: 10 // (REQUIRED IF PERCENTAGE) number - Percentage discount (if applicable)
}
}
}
]
}
]
});
Other platforms
  1. Access your website’s HTML files.
  2. Locate the <head> section of your site’s HTML.
  3. Paste the tracking code just before the closing </head> tag.
  4. Save and upload the changes to your server.
<script src="https://cdn.moonshot-ai.com/snippets/<TRACKING_ID>.js"></script>

Find the “thank you for your purchase” page on your site and add the revenue event below, with the transaction parameters filled in from the completed order.

Shuttlebase tracks purchases through a revenue event pushed to the snippet’s queue. Replace the {placeholder} values with the actual transaction parameters from the completed order. The comments mark which fields are required.

window['msaiClient'] = window['msaiClient'] || [];
window['msaiClient'].push({
event_type: 'revenue', // (REQUIRED)
event_value: 123.45, // (REQUIRED) number - The decimal money amount
transaction_currency: "{currency}", // (REQUIRED) string - 3-letter ISO 4217 currency code (i.e. USD, EUR, GBP)
order_id: "{order_id}", // (REQUIRED) string - Unique order identifier
transaction_id: "{transaction_id}", // (OPTIONAL) string | null - Unique transaction identifier
discount_allocations: [ // (OPTIONAL) Array of Discounts applied to the entire cart and/or shipping. NOTE if targeting specific products, use the discount_allocations array in the line_items_info to target those specific products.
{
amount: { // (REQUIRED IF DISCOUNT) The total amount of the discount applied to the entire cart or shipping line
amount: {discount_amount}, // number - The decimal money amount
currency_code: "USD" // string - 3-letter ISO 4217 currency code (if different from transaction_currency)
},
target_type: "{target_type}", // (REQUIRED) string - "LINE_ITEM" for discounts to the entire cart or "SHIPPING_LINE" for discount to entire shipping line
title: "{discount_code}", // (REQUIRED IF DISCOUNT CODE) string - The discount code (i.e. "FREESHIP", "CART20") if applicable
type: "{type}", // (REQUIRED) string - "AUTOMATIC", "DISCOUNT_CODE"
value: { // The discount value
amount: {discount_amount}, // (REQUIRED IF FIXED AMOUNT) number - Fixed amount discount (if applicable)
currency_code: "USD", // (REQUIRED IF FIXED AMOUNT) string - Currency code for fixed amount (if different from transaction_currency)
percentage: 15 // (REQUIRED IF PERCENTAGE) number - Percentage discount (if applicable)
}
}
],
line_items_info: [ // (REQUIRED) Array of detailed information about each item type in the order
{
id: "{line_item_id}", // (REQUIRED) string - Globally unique identifier (Normally Product ID)
quantity: 1, // (REQUIRED) number - Quantity of this item type
title: "{product_title}", // (Optional) string - The title of the line item (If different from product title)
final_line_price: { // Combined price after line-level discounts
amount: 99.99, // (REQUIRED) number - The decimal money amount
currency_code: "USD" // (REQUIRED IF DIFFERENT FROM TRANSACTION_CURRENCY) string | null - Only include if the currency is different from the transaction_currency
},
variant: { // (REQUIRED) ProductVariant | null - Variant information
id: "{variant_id}", // (OPTIONAL) string | null - Globally unique identifier (If not provided, the product_id will be used)
title: "{variant_title}", // (OPTIONAL) string | null - The product variant's title (If not provided, the product_title will be used)
sku: "{sku}", // (OPTIONAL) string | null - SKU (stock keeping unit) (Can be the product_sku)
price: { // (REQUIRED) The product variant's price
amount: 99.99, // (REQUIRED) number - The decimal money amount
currency_code: "USD" // (REQUIRED IF DIFFERENT FROM TRANSACTION_CURRENCY) string | null - Only include if the currency is different from the transaction_currency
},
product: { // (REQUIRED) The product object
id: "{product_id}", // (REQUIRED) string | null - The ID of the product
title: "{product_title}", // (REQUIRED) string - The product's title
type: "{product_type}", // (OPTIONAL) string | null - The product type
vendor: "{vendor}", // (OPTIONAL) string - The product's vendor name
url: "{product_url}" // (OPTIONAL) string | null - The URL of the product
}
},
selling_plan_allocation: { // (OPTIONAL) Subscription information
selling_plan: { // (OPTIONAL) SellingPlan
id: "{selling_plan_id}", // (REQUIRED IF SELLING PLAN) string - Globally unique identifier
name: "{selling_plan_name}" // (REQUIRED IF SELLING PLAN) string - Name of the plan (i.e. "6 weeks of prepaid granola, delivered weekly")
}
},
discount_allocations: [ // (OPTIONAL) Discounts applied to this specific line item
{
amount: { // (REQUIRED IF DISCOUNT) The monetary value allocated to the discount
amount: 5.00, // number - The decimal money amount
currency_code: "USD" // string - 3-letter ISO 4217 currency code
},
discount_application: { // (REQUIRED IF DISCOUNT) The discount info
target_type: "{target_type}", // (REQUIRED) string - "LINE_ITEM" for discounts to the product or "SHIPPING_LINE" for discount to specific product's shipping NOTE: If shipping discount is for all products, use the discount_allocations array in the top level of the event
title: "{discount_code}", // (REQUIRED IF DISCOUNT CODE) string - The discount code (i.e. "SAVE20")
type: "{type}", // (REQUIRED) string - "AUTOMATIC", "DISCOUNT_CODE"
value: {
amount: 5.00, // (REQUIRED IF FIXED AMOUNT) number - Fixed amount discount (if applicable)
currency_code: "USD", // (REQUIRED IF FIXED AMOUNT) string - Currency code for fixed amount
percentage: 10 // (REQUIRED IF PERCENTAGE) number - Percentage discount (if applicable)
}
}
}
]
}
]
});