Your Shopify analytics says 71% of carts got abandoned this week. Fine — that's roughly the industry average. What it doesn't say is which step killed each one: the shipping calculator, the discount code field that quietly errored, the Shop Pay popup that never loaded on Safari iOS 17.
That's the gap most marketing teams try to close with session replay. Below is a 20-minute setup that gets CloseTrace recording on your Shopify storefront, then turns those replays into a funnel and an email follow-up for shoppers who reach checkout step 1 but never pay.
Step 1: Drop the snippet into theme.liquid
CloseTrace ships as a single async script. You install it once at the theme level so it covers every product page, collection, cart drawer, and the hosted /checkout pages your plan exposes.
In your Shopify admin: Online Store → Themes → ⋯ (on your live theme) → Edit code.
Open layout/theme.liquid and paste this just before the closing </head> tag:
<!-- CloseTrace -->
<script async
src="https://cdn.closetrace.com/t.js"
data-site="ct_YOUR_SITE_KEY"
data-shopify="true"
data-mask-pii="phone,address1,address2"></script>
Replace ct_YOUR_SITE_KEY with the key from your dashboard (Settings → Sites → New site → Shopify). The data-shopify="true" flag tells the tracker to read Shopify.checkout and window.ShopifyAnalytics.meta when they're present, so you get cart token, variant IDs, and step transitions without writing a single event yourself.
Save the theme. Hit any product page in an incognito window, add to cart, and check the Live sessions view. You should see one active session within ~10 seconds.
A note on the hosted checkout
Shopify's /checkout runs on a separate subdomain (checkout.shopify.com or your store's checkout domain on Plus). Standard themes don't let non-Plus stores inject scripts into checkout. The tracker handles this by listening to the analytics.subscribe events that Shopify exposes through the Customer Events API — which you wire up next.
Step 2: Add a Customer Event for checkout coverage
This is the part most replay tools skip and then quietly under-report on. Go to Settings → Customer events → Add custom pixel, and paste:
analytics.subscribe("checkout_started", (event) => {
window.closetrace?.track("checkout_started", {
cart_token: event.data.checkout.token,
total: event.data.checkout.totalPrice.amount,
});
});
analytics.subscribe("checkout_shipping_info_submitted", (event) => {
window.closetrace?.track("shipping_submitted", {
cart_token: event.data.checkout.token,
});
});
analytics.subscribe("payment_info_submitted", (event) => {
window.closetrace?.track("payment_submitted", {
cart_token: event.data.checkout.token,
});
});
analytics.subscribe("checkout_completed", (event) => {
window.closetrace?.track("purchase", {
cart_token: event.data.checkout.token,
order_id: event.data.checkout.order?.id,
});
});
Set the permission to Not required (these are first-party events to your own analytics) and Connect the pixel. Shopify will start streaming the four events to the tracker within minutes.
The cart_token is the linchpin. It joins the storefront session you recorded with whatever happens (or doesn't) in checkout, so a single replay covers the whole journey.
Step 3: Build the cart-to-purchase funnel
In CloseTrace, open Funnels → New and add five steps in order:
pageviewwherepathcontains/products/add_to_cart(auto-captured from Shopify whendata-shopify="true")checkout_startedshipping_submittedpurchase
Save it as Shopify cart → purchase. Within an hour you'll have a conversion rate at each step, plus a "Watch sessions that dropped here" button on every step that lost users. That's the view to live in every morning.
If you want context on what a healthy version of this looks like, the d2c checkout funnels teardown walks through where carts typically bleed. The benchmarks track Baymard's ~70% abandonment number, but the per-step breakdown is what's actually useful.
Step 4: Turn one drop-off into a recovery email
The cart you really want back is the one where someone got to checkout_started, entered their email, and then bailed before payment_submitted. Shopify's own abandoned-checkout email covers some of these, but it fires once and only if the shopper made it past the contact step on the first visit.
The lead recovery flow captures the email as soon as it's typed into the checkout field — before submit — and emits a lead_captured event with the cart token. In the dashboard, create a recovery rule:
- Trigger:
lead_capturedAND nopurchasewithin 45 minutes - Filter: cart total over $40 (or whatever your AOV threshold is)
- Action: send templated email with the cart-recovery link
That link is just https://yourstore.com/cart/c/{cart_token} — Shopify rehydrates the exact cart contents. Pair the email send with the recorded session replay attached in the dashboard, and spot-check the first ten manually before letting it run on autopilot.
What this setup won't catch
One caveat worth saying out loud. Shopify's Customer Events API runs in a sandboxed iframe on checkout, which means the tracker can record DOM events and field interactions, but pixel-perfect visual replay on /checkout pages is limited on non-Plus plans. You'll see the full visual replay through add_to_cart, then event-only telemetry through purchase. For most teams that's enough — you still see which step they left on and why (rage clicks, dead clicks, validation errors). For pixel-perfect replay inside checkout itself, you need Shopify Plus and the checkout extensibility setup.
The other thing: if your store ships to the EU, walk through your GDPR posture before flipping email capture on. The data-mask-pii attribute controls what's redacted from replays, but capturing a typed email into a recovery flow is a separate consent question.
Verify it before you trust it
Run one end-to-end test before you tell the team it's live:
- Open the store in incognito, add a product to cart, start checkout, type an email, then close the tab.
- Wait two minutes. The session should appear in the Sessions view with the
lead_capturedevent and acart_tokenproperty attached. - Complete a real purchase from another browser. Confirm the
purchaseevent lands and the funnel's last step ticks up.
If step 1 doesn't capture the email, the most common cause is data-mask-pii being too aggressive. Check the masked-fields list and confirm email isn't in it.
Next thing to do: tomorrow morning, open the funnel, sort drop-off sessions by cart value descending, and watch the top five replays. That's a 15-minute weekly habit that pays for the tool by itself.
