Website builders · 5 min setup
How to add analytics to a Shopify store
layout/theme.liquid, and paste the script tag right before </head>. That covers every storefront page — home, collections, products, cart, blog — but not Shopify's checkout, which doesn't run theme code.Updated
No app is required: theme.liquid is the layout every storefront page renders through. Be aware of two Shopify-specific limits before you rely on the numbers. First, theme edits belong to that theme — if you switch themes or install a new version, add the tag again. Second, checkout and the thank-you page only allow Shopify web pixels, which run inside a sandboxed iframe; VisitTrack's script deliberately doesn't run inside iframes, so it can't track checkout steps there.
Shopify at a glance
- Where the tag goes
layout/theme.liquid, right before</head>- Covers
- All storefront pages (not checkout / thank-you)
- Theme changes
- Re-add the tag after switching or updating themes
- Purchases
- Via an
orders/paidwebhook → server-side event - Revenue tab
- Shopify Payments isn't a supported revenue provider
How to install VisitTrack on Shopify
Step 1: Copy your site id
Add your store's domain as a site in VisitTrack and copy the snippet from the install step (or Settings → General). Replace
SITE_IDbelow.Step 2: Open the theme code editor
In Shopify admin, go to Online Store → Themes. On your live theme, click ⋯ → Edit code. (Tip: duplicate the theme first if you want a backup.)
Step 3: Paste the tag before </head> in theme.liquid
Under Layout, open
theme.liquid, find the closing</head>tag and paste the snippet just above it. Click Save.layout/theme.liquid<script defer data-site="SITE_ID" src="https://visitrack.app/tracker.js"></script>Step 4: Allow your store domains
Visitors may reach both
your-store.myshopify.comand your custom domain. Both report into the same VisitTrack site. In Settings → General → Allowed hostnames, save the hosts you want counted (for exampleyourstore.comand*.yourstore.com).
How to check VisitTrack is working on Shopify
- Open your storefront in a private window (so you're not looking at the theme editor preview) and open a collection and a product.
- The VisitTrack live view shows you within seconds; the Pages tab lists
/collections/…and/products/…paths. - If nothing arrives, view the page source and search for
tracker.js— if it's missing, the tag was saved in a theme that isn't the published one.
Does VisitTrack track Shopify page navigation?
Shopify storefronts are classic multi-page sites: each page is a full load and a pageview. Pageviews are recorded by path, so /collections/shoes?page=2 and /collections/shoes?sort_by=price-ascending count toward /collections/shoes, which keeps collection stats readable.
Some themes update the URL when a shopper picks a variant (?variant=…). That only changes the query string, so it isn't counted as a new pageview.
How to track custom events and goals in Shopify
Add data-vt-goal to the buttons that matter, in the theme code. In Dawn-based themes the add-to-cart button lives in snippets/buy-buttons.liquid and the cart's checkout button in sections/main-cart-footer.liquid; other themes use similar names — search the code editor for name="add" and name="checkout".
With automatic events on, product forms also record a form_submit event, but its name comes from the form's id, which varies by template — explicit goals are easier to read.
<button type="submit" name="add" data-vt-goal="add_to_cart" class="product-form__submit button">
Add to cart
</button>
<button type="submit" name="checkout" data-vt-goal="checkout_started" class="cart__checkout-button button">
Check out
</button>Create goals from add_to_cart and checkout_started in Settings → Goals, and a funnel from product page → add_to_cart → checkout_started → purchase (below).
Revenue attribution on Shopify
VisitTrack's Revenue tab reads payments from Stripe, Polar, Lemon Squeezy, Paddle and Razorpay webhooks; Shopify Payments isn't one of them. You can still connect orders to sources with two small pieces: store the visitor id on the cart as a cart attribute (Shopify copies cart attributes onto the order as note_attributes), then send a purchase event from your own orders/paid webhook handler with server-side events.
The event joins the visitor's history, so purchase works as a goal and funnel step broken down by first source. It won't appear as revenue in the Revenue tab. In cookieless mode there's no browser visitor id to store, so this pattern needs standard mode.
<script>
// Store the VisitTrack visitor id on the cart, once per session, so it
// travels with the order (as a note attribute) into your webhook.
document.addEventListener("DOMContentLoaded", function () {
var vid = window.visitrack && window.visitrack.visitorId && window.visitrack.visitorId();
if (!vid || sessionStorage.getItem("vt_cart_attr") === vid) return;
fetch("/cart/update.js", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ attributes: { visitrack_visitor_id: vid } }),
}).then(function () { sessionStorage.setItem("vt_cart_attr", vid); });
});
</script>
// Your orders/paid webhook handler (verify X-Shopify-Hmac-Sha256 first)
const order = JSON.parse(rawBody);
const vid = order.note_attributes?.find((a) => a.name === "visitrack_visitor_id")?.value;
if (vid) {
await fetch("https://visitrack.app/api/track", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VISITRACK_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "event",
visitorId: vid,
name: "purchase",
props: {
amountCents: Math.round(Number(order.total_price) * 100),
currency: order.currency,
order: order.name,
},
}),
});
}Script options you might need on Shopify
All optional — add them to the same tag. Full reference: script configuration.
| Attribute | What it does |
|---|---|
data-cookieless | Store nothing in the browser; the server derives a daily-rotating id. See cookieless mode. |
data-exclude="/app/*" | Never track these paths (comma-separated, * wildcard). Checked on every navigation. |
data-allow-local | Track on localhost and *.local — for testing an install only. |
data-debug | Log every event the script sends, and why it skipped one, to the console. |
data-auto="false" | Turn off automatic events (downloads, contact clicks, form submits, rage clicks, JS errors, 404s). |
Shopify troubleshooting
Tracking stopped after a theme update
Theme updates and new themes don't keep edits to theme.liquid. Paste the tag into the new theme's theme.liquid again.
No data from checkout or the thank-you page
Expected. Shopify doesn't run theme code there, and its customer-event pixels run in a sandboxed iframe, where the tracker doesn't run. Use the webhook pattern above for purchases.
*.myshopify.com and your domain appear as two hosts
That's the same store on two hostnames. Filter by host in the Hostname tab, or limit Allowed hostnames to your custom domain.
Your own browsing inflates numbers
Open the store once with ?vt_ignore=1 in the URL to exclude that browser.
The cart attribute never reaches orders
The cart script must run after the tracker, so visitorId() exists, and only works in standard mode. Check the cart with /cart.js in the browser — the attributes object should list visitrack_visitor_id.
Shopify analytics FAQ
Do I need a Shopify app to use VisitTrack?
No. Paste the script tag into layout/theme.liquid before </head>. There's no app to install and nothing that slows down your admin.
Can VisitTrack track Shopify checkout?
Not inside checkout itself. Shopify only allows web pixels there, which run in a sandboxed iframe, and the VisitTrack script doesn't run in iframes. Track checkout_started on the cart button and send paid orders from a webhook.
Does VisitTrack show Shopify revenue by traffic source?
Not in the Revenue tab — Shopify Payments isn't a supported provider. With the cart-attribute and webhook pattern above, each paid order becomes a purchase event tied to the visitor's first source, with the amount in its props.
Will editing theme.liquid break my store?
Adding one deferred script tag before </head> is low-risk, and Shopify keeps a version history of every file in the code editor so you can roll back. Duplicating the theme first gives you a full backup.
Do I need a cookie banner for VisitTrack on Shopify?
Not in cookieless mode, which stores nothing on the shopper's device. The purchase-attribution pattern above needs standard mode, which stores a first-party id and generally needs consent in the EU/UK. General information, not legal advice.
How is this different from Shopify Analytics?
Shopify's reports are order-centric. VisitTrack adds live visitors, journeys, session replays, click heatmaps, AI-crawler tracking and UTM/channel breakdowns for every storefront page, without cookies in cookieless mode.
Keep going
- WordPress analyticsAdd VisitTrack to WordPress with a header-code plugin or a wp_head hook — works with block themes, caching plugins and WooCommerce.
- Webflow analyticsAdd VisitTrack to Webflow in Site settings → Custom code → Head code, then publish — plus custom attributes for goals and Stripe Payment Link revenue.
- Google Tag Manager analyticsLoad VisitTrack from Google Tag Manager with a Custom HTML tag on All Pages — SPA-safe, consent-aware, with dataLayer events forwarded as custom events.
- Wix analyticsAdd VisitTrack to Wix in Settings → Custom Code: All pages, Head, load once — Wix's client-side page changes are tracked automatically.
- Install the tracking scriptThe reference tag, CSP notes and how to check it's working.
- Custom events and signupsvisitrack(), data-vt-goal, scroll events and server-side signups.
- Use casesHow SaaS teams, indie hackers, stores and agencies use VisitTrack.
- VisitTrack vs Google AnalyticsCookie-free analytics with revenue attribution, compared honestly.
Add VisitTrack to your Shopify site
Cookie-free analytics with revenue attribution, live visitors, funnels and session replays. One script tag, every feature on every plan. 14 days free, no card required.
14-day free trial · No card required · Cookie-free · Cancel anytime
Or explore the live demo first →Not on Shopify? See all 29 integration guides.