Shopify
Clickport runs on your Shopify store with one script tag in your theme, plus an optional Custom Pixel for checkout and revenue tracking. This page walks through both.
What gets tracked, and where
Shopify has two surfaces that need different install methods:
- Storefront pages (home, collections, products, blog, internal search): one script tag in
theme.liquid. Covered by Section 1 below. - Checkout pages (the
/checkouts/*flow on Shopify's own domain): a small Custom Pixel that listens for Shopify's checkout events and forwards them. Covered by Section 2.
Most stores get a meaningful improvement over Shopify's built-in reporting from Section 1 alone. Add Section 2 when you want revenue attribution per source, channel, country, or device, and to see where your checkout funnel is leaking.
1. Install the snippet on your Shopify theme
Open the theme code editor
From your Shopify admin, go to Online Store → Themes. Find your live theme, click the … button on its row, then Edit code.
Paste the snippet before </head>
Open layout/theme.liquid in the editor. Paste the following just before the closing </head> tag, replacing your-site-id with the site ID from your Clickport dashboard:
<script defer src="https://clickport.io/tracker.js"
data-site="your-site-id"></script>
Click Save.
Verify it's working
Open your store in a new browser tab. Within 30 seconds your visit should appear in the Realtime view of your Clickport dashboard.
If it does not, see Troubleshooting below.
What gets tracked automatically
From the snippet alone, with no further setup:
To track anything else from a storefront page (newsletter signup CTA, a "buy on Amazon" outbound, a discount-code copy), use custom events with clickport.track('Event Name', { ... }).
2. Track checkouts and revenue with a Custom Pixel
Shopify checkout pages live on a Shopify-owned domain (something like shop.myshopify.com/checkouts/…) and never load your theme. To track purchases and revenue, Shopify provides a sandboxed slot called a Custom Pixel that listens for checkout events and forwards them to your analytics tool.
The setup below subscribes to Shopify's standard ecommerce events (started checkout, payment info added, purchase, add to cart, search) and forwards each one to Clickport with revenue attached where it applies.
Create the pixel
From your Shopify admin, go to Settings → Customer events → Add custom pixel. Name it Clickport. Set Permission to Not required (Clickport is cookieless analytics and is exempt from EU cookie-consent rules under CNIL's analytics exemption, see GDPR compliance) or to Required if your store already has a consent banner and you prefer to gate everything behind it.
Setup block [Required]
Paste this at the top of the Custom Pixel code editor. It defines a small cp() helper that sends events directly to the Clickport ingestion endpoint. The pixel posts each event over fetch() rather than loading the storefront tracker inside the sandbox, which keeps your Pages panel clean (the Shopify pixel sandbox has its own iframe URL that we explicitly avoid sending in).
const SITE = 'your-site-id';
const DOMAIN = 'yourstore.com';
function cp(name, props, revenue, url) {
const mk = props ? Object.keys(props) : [];
const body = { t: 'e', n: name, u: url, dm: DOMAIN };
if (mk.length) { body.mk = mk; body.mv = mk.map(k => String(props[k])); }
if (revenue) { body.ra = revenue.amount; body.rc = revenue.currency || 'USD'; }
fetch('https://clickport.io/api/event', {
method: 'POST',
headers: { 'Content-Type': 'text/plain', 'X-API-Key': SITE },
body: JSON.stringify(body)
});
}
Replace your-site-id with the site ID from your Clickport dashboard (same one you use in Section 1) and yourstore.com with your storefront domain (not the .myshopify.com URL). All the analytics.subscribe() calls below go after this block in the same pixel.
Track completed checkouts (purchases)
The one event every store should fire. Sends revenue, currency, and order ID:
analytics.subscribe('checkout_completed', (event) => {
cp('Purchase',
{ order_id: event.data.checkout.order.id },
{ amount: event.data.checkout.totalPrice.amount,
currency: event.data.checkout.currencyCode },
event.context.document.location.href);
});
Once this is firing and you have added Purchase as a goal in Settings → Goals, your dashboard cross-filters every panel by Purchase conversions and shows revenue per source, channel, country, and device:
Channels that Shopify's built-in attribution dumps into Direct (email platforms like Klaviyo and Mailchimp, in-app browsers from Instagram and TikTok, AI search) get classified into the right channel automatically. Clickport recognizes 16 channels including Organic Search, Paid Search, Organic Social, Paid Social, Email, AI Search, Affiliates, and Referral.
Track started checkouts
Fires a Begin Checkout event the moment someone enters the checkout flow. Useful as a top-of-funnel goal so you can see how many visitors actually start checkout, not just how many buy.
analytics.subscribe('checkout_started', (event) => {
cp('Begin Checkout', null,
{ amount: event.data.checkout.totalPrice.amount,
currency: event.data.checkout.currencyCode },
event.context.document.location.href);
});
Track payment info added
Fires when the customer enters their payment details. The drop-off between Begin Checkout and Add Payment Info is where most stores leak the most revenue.
analytics.subscribe('payment_info_submitted', (event) => {
cp('Add Payment Info', null,
{ amount: event.data.checkout.totalPrice.amount,
currency: event.data.checkout.currencyCode },
event.context.document.location.href);
});
Track add to cart
Fires when a customer adds a product to their cart. Useful for measuring product-page effectiveness.
analytics.subscribe('product_added_to_cart', (event) => {
const line = event.data.cartLine;
cp('Add to Cart',
{ product: line.merchandise.product.title,
variant: line.merchandise.title,
quantity: line.quantity },
{ amount: line.cost.totalAmount.amount,
currency: line.cost.totalAmount.currencyCode },
event.context.document.location.href);
});
Track site searches
Captures the query string from internal site searches. Combine with the searches panel to find product gaps:
analytics.subscribe('search_submitted', (event) => {
cp('Search',
{ query: event.data.searchResult.query },
null,
event.context.document.location.href);
});
Track checkout pageviews
Optional. If you want each step of the checkout flow to appear in the Pages panel alongside your storefront pages, post a pageview directly with a small inline helper:
function cpv(url) {
fetch('https://clickport.io/api/event', {
method: 'POST',
headers: { 'Content-Type': 'text/plain', 'X-API-Key': SITE },
body: JSON.stringify({ t: 'v', u: url, dm: DOMAIN })
});
}
analytics.subscribe('checkout_started', (event) => {
cpv(event.context.document.location.href);
});
Filter on Page contains /checkouts/ in the dashboard to isolate the checkout funnel from the rest of your traffic.
Spot where your checkout funnel leaks
With Begin Checkout, Add Payment Info, and Purchase all firing, the Funnels tab turns those three events into a drop-off chart in seconds. From Settings → Goals & Funnels → Funnels, drag the three goals into order and save:
The dashed bars above each step show the drop-off from the previous step. A big dashed gap between Begin Checkout and Add Payment Info almost always points to a payment friction problem (limited methods, slow loads on the payment step, surprise fees). A gap between Add Payment Info and Purchase usually means a payment failure or a final-step pricing surprise. More on funnels in the docs →
The cp() helper signature
The helper from the Setup Block above takes four arguments:
cp(name, properties, revenue, url)
name(string, required): The label that appears in your goals list and in the Events panel.properties(object or null, optional): Up to 30 key-value pairs, 2,000 characters per value. Used for breakdown views (for example, top products by Add to Cart count). Passnullfor events with no extra properties.revenue(object or null, optional):{ amount: 49.99, currency: 'USD' }. Currency defaults toUSDif omitted. Passnullwhen an event has no monetary value (Search, Begin Checkout if you skip the cart total).url(string, required): The actual page URL the event happened on. Always passevent.context.document.location.hrefinside a Custom Pixel, otherwise events get tagged with the sandbox iframe URL.
The helper is a thin wrapper over a POST /api/event call. If you need to send events from somewhere outside a Custom Pixel (a server-side webhook, for example), you can hit the same endpoint directly: Content-Type: text/plain, X-API-Key: <your site ID>, and a JSON body with t (event type, 'e'), n (name), u (URL), dm (domain), and optionally mk/mv (property keys/values), ra/rc (revenue amount/currency). See the custom events reference for the full payload schema.
Goals and revenue reporting
Once your Custom Pixel is firing, add each event you want to act on as a goal:
- Open Settings → Goals in your Clickport dashboard.
- Click Add goal, choose Custom event, and enter the event name exactly as it appears in your
cp()calls in the Custom Pixel, or in yourclickport.track()calls on the storefront (for example,Purchase). - Save. The goal appears in the Goals panel with conversions and revenue, and shows up in the goal-filter dropdown for cross-filtering every other panel.
Each goal accumulates its own per-source, per-channel, per-country, and per-device breakdowns. Click a goal in the Goals panel and the whole dashboard cross-filters to it, swapping the standard Visitors and Engagement columns on every breakdown panel for Conversions and CR. See goals and ecommerce revenue tracking for the full reporting reference.
Troubleshooting
I added the snippet but no visits show up
- Open your store and view source. Confirm the
<script defer src="https://clickport.io/tracker.js">line is present in the<head>. If it is missing, the edit did not save or it was added to a different theme than the live one. - Check your browser's Network tab for a successful
POST /api/eventtoclickport.io. If you see the request but it returns a non-200 status, thedata-siteattribute is wrong or your site is not active in your Clickport dashboard. - If you have an ad blocker or use Brave's built-in shield, disable it on your own store for testing. Clickport is rarely blocked in practice but some blocklists are aggressive.
- Make sure you are looking at the right site in the dashboard if you have multiple sites.
Custom Pixel fires but events do not appear in the dashboard
- Confirm the
DOMAINconstant in the pixel's Setup Block matches the domain registered for your site in Clickport (and is your storefront domain, not the.myshopify.comURL). If it does not, events arrive but route to the wrong site or get dropped. This is the most common pixel issue. - Open the Custom Pixel preview in the Shopify admin and place a test order. In your browser's Network tab, look for
POST /api/eventrequests toclickport.iowhen each event fires. - If you see the requests but no events in the dashboard, double-check the event names match what you registered as goals (case-sensitive:
Purchasenotpurchase).
Revenue shows in the wrong currency
Shopify returns the cart and checkout in the shopper's currency, not your store's default currency. The events above use event.data.checkout.currencyCode which is correct for the shopper. If you want all revenue normalized to your store's base currency, replace currencyCode with a hardcoded value like 'USD' in the snippets above. Note that this normalizes the label but not the amount; multi-currency stores generally prefer keeping the per-order currency intact.
Domain shows as something Shopify-ish in my dashboard
This happens when the DOMAIN constant in the Setup Block was left as the placeholder or set to the wrong value. Update it to your storefront domain (not the .myshopify.com URL) and resave the pixel.
What this looks like compared to Shopify's built-in analytics
Shopify Analytics is reliable for order and revenue data because the platform owns the checkout. It is structurally limited everywhere else: the majority of visitors who land on your store but do not buy are not surfaced in detail, accelerated checkouts (Shop Pay, Apple Pay, Google Pay) bypass the cart and confuse session attribution, in-app browsers from Instagram and TikTok register as Direct because they strip the referrer header, and metrics like scroll depth, engaged time, outbound clicks, and copy events do not exist at any plan tier.
Clickport's Section 1 install closes the storefront-side gap (every visitor counted, every source classified, engagement and behavior metrics included). Section 2 closes the checkout-side gap (revenue per channel, funnel drop-off, custom events with monetary values). The two together replace what most Shopify stores stitch together from GA4 plus a tag manager plus a heatmap tool plus an attribution app, with one 2 KB script tag and one Custom Pixel.
For the full comparison and the data behind why merchants switch, see Shopify Analytics: The store owner's guide to better data.