Shopify purchase tracking on headless stores
How to link Shopify orders to the visit that led to them when your storefront is custom-built and checkout runs on a different domain.
This is for stores whose storefront is custom-built (Hydrogen, Next.js and so on) and runs on a different domain from Shopify checkout. Standard Shopify theme stores don't need any of this, purchases are tracked as soon as the app is installed.
Why headless stores need an extra step
Lead Recorder remembers each visitor in their browser on your storefront's domain. On a headless store, checkout happens on a different domain, which can't see that information, so the order can't be linked to the visit on its own. The fix is to pass the visitor's Lead Recorder IDs to Shopify with the cart. Shopify copies them onto the order, and the Lead Recorder app reads them from there. No cookies are involved.
Setup
- 1Add the Lead Recorder tracking snippet to the <head> of every page on your storefront.
- 2Install the Lead Recorder Shopify app and open it once to approve its permissions. This switches on purchase tracking at checkout.
- 3Ask your developer to add the code below. It runs when the shopper heads to checkout.
Developer code
The tracking snippet adds window.LeadRecorder.cartAttributes(), which returns three hidden cart attributes: _lr_key, _lr_sid and _lr_vid. Just before sending the shopper to the cart's checkoutUrl, add them to the cart:
async function goToCheckout(cart) {
const leadRecorder = window.LeadRecorder?.cartAttributes?.() ?? [];
// cartAttributesUpdate replaces the cart's attribute list,
// so keep any attributes the site already uses.
const existing = (cart.attributes ?? []).filter((a) => !a.key.startsWith("_lr_"));
const { data } = await storefrontApi(`
mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {
cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {
cart { checkoutUrl }
userErrors { field message }
}
}`,
{ cartId: cart.id, attributes: [...existing, ...leadRecorder] }
);
window.location.href = data.cartAttributesUpdate.cart.checkoutUrl;
}storefrontApi is whatever your site already uses to call Shopify's Storefront API. On Hydrogen, pass the same attribute list to the cart handler's updateAttributes instead.
Tip: The optional chaining matters. If the snippet hasn't loaded, or the visitor's browser blocks storage, cartAttributes returns nothing and checkout carries on as normal. The order just won't be linked to a visit.
Check it works
- 1Add something to the cart on your storefront and start checkout.
- 2Place a test order.
- 3Open the order in Shopify admin. Under Additional details you should see _lr_key, _lr_sid and _lr_vid, each with a value.
- 4In Lead Recorder, open the Purchases tab and tick Show test orders. The order should be there with its source and page journey.
Limits
- Shoppers who decline analytics cookies aren't tracked at checkout, so order counts can be lower than Shopify's.
- If the cart code doesn't attach the attributes, the order isn't recorded at all.
- Everything in Shopify purchase tracking about currencies, test orders and the free plan applies here too.