Skip to main content

How to use Direct-to-Checkout UTM Links

This article outlines how to use UTM links

Updated over a week ago

AfterSell supports triggering funnels based on UTM parameters.

You can configure your funnel to activate when a customer visits your site with a specific UTM query string.

To see how to quickly get started with UTM triggers, check out this video:

How to Use Direct-to-Checkout UTM Links

The setup shown in the previous video does not support links that send customers directly to checkout. By default, AfterSell can only detect UTM parameters on the main part of your site. This is because it relies on a theme app block, which works only on storefront pages and not on the checkout or thank-you page.

Enable UTM Tracking on Checkout Pages

To track UTM parameters on the checkout page, you will need to add a Shopify Pixel to your store.

Important: This setup requires the visitor to have a cart token when they arrive at the checkout through a UTM link. Without a cart token, the UTM data will not be captured.

Setting Up Direct-to-Checkout UTM Links

You can watch this video to get started:

Or follow the step-by-step instructions:

  1. In your Shopify admin, go to Settings > Customer Events.

  2. Click Add Custom Pixel and give it any name you like.

  3. Under the Permission dropdown, select Analytics. This is the only permission required.

  4. For the Data Sale dropdown, you can choose Data collected does not qualify as data sale. AfterSell keeps all collected data private and never shares it with anyone other than you.

  5. In the code editor that appears, paste in the code provided below.

  6. Click Save, then Connect.

/**
* IMPORTANT: This pixel can only fire on sessions where the
* customer has a cart object, otherwise it will be skipped.
* For example, clicking "Buy Now" on a product page skips the cart,
* going directly to checkout.
**/
function processData({event, cartToken}) {
// TODO: Edit MYSHOPIFY_DOMAIN to your domain. E.g.
// const MYSHOPIFY_DOMAIN = 'example-store.myshopify.com';
const MYSHOPIFY_DOMAIN = '';

const enableDebug = false;

// DO NOT EDIT PAST HERE
const SESSION_STORAGE_KEY = 'as-customer-trigger-data';
const HOST = 'https://start.aftersell.app';

if (!MYSHOPIFY_DOMAIN) {
if (enableDebug) {
console.log("UTM pixel didn't fire because of missing Shopify domain");
}
return;
}
if (!cartToken) {
if (enableDebug) {
console.log("UTM pixel didn't fire because of missing cart token");
}
}

let existingCustomerData = null;
try {
existingCustomerData = JSON.parse(
sessionStorage.getItem(SESSION_STORAGE_KEY) || 'null'
);
} catch (ignore) {
if (enableDebug) {
console.log("UTM pixel didn't fire because malformed user data json");
}
}

const allowedUrlParams = [
'utm_source',
'utm_medium',
'utm_campaign',
'utm_term',
'utm_id',
'utm_content',
];

const searchParams = new URLSearchParams(event.context.window.location.search);
let hasCustomerData = false;
const customerData = {};
for (const param of allowedUrlParams) {
const paramValue = searchParams.get(param) || existingCustomerData?.[param];
if (paramValue) {
hasCustomerData = true;
customerData[param] = paramValue;
}
}

if (hasCustomerData) {
sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(customerData));

const postBody = {
shop: MYSHOPIFY_DOMAIN,
cartToken,
checkoutToken: event.data.checkout.token ?? undefined,
customerTriggerData: customerData,
};

if (enableDebug) {
console.log("UTM pixel fired with the following data:", postBody);
}

fetch(`${HOST}/api/v1/storefrontSessions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postBody),
});
} else {
if (enableDebug) {
console.log("UTM pixel didn't fire because there was no data to send");
}
}
}

analytics.subscribe('checkout_started', (event) => {
// minimum realistic time between adding item to cart and clicking checkout
const COOKIE_POLLING_INTERVAL_MS = 500;

let currentCookieValue = getCookieValue({ cookie: document.cookie, cookieName: 'cart' });
processData({event, cartToken: currentCookieValue});

setInterval(() => {
const newCookieValue = getCookieValue({ cookie: document.cookie, cookieName: 'cart' });
if (newCookieValue !== currentCookieValue) {
currentCookieValue = newCookieValue;
processData({event, cartToken: newCookieValue});
}
}, COOKIE_POLLING_INTERVAL_MS);
});

function getCookieValue({ cookie, cookieName }) {
const cartCookieRegex = new RegExp(`^${cookieName}=`);
const cartCookie = cookie
.split(';')
.map((val) => val.trim())
.find((val) => cartCookieRegex.test(val));
if (!cartCookie) return null;
const cartCookieValue = cartCookie.replace(`${cookieName}=`, '');
return cartCookieValue;
}
Did this answer your question?