Installing the app, how consent is handled, headless storefronts, and stores that check out on their own system. The headless and checkout sections are written for a developer.
The native Evarist app is live on the Shopify App Store. Install it from apps.shopify.com/evarist, then open it in your admin and follow the setup guide: Agree and continue, then turn on the Evarist app embed in your theme editor. No code, and Shopify already knows your store, so there's no domain to type. If you already use Evarist at app.evarist.ai, the same page offers to link the store to that account instead.
The app turns on tracking through a theme app embed and a web pixel. If you already track this site with the snippet or a tag manager, remove it once the app is connected: the app replaces it. Orders are deduplicated by order ID across every source, so your revenue stays correct either way; but while both are running, page events and any goals you set up on the old tracking can be counted twice, so don't leave them side by side longer than the switchover.
The pixel also sends the product id with each product view, so that data is collected on a Shopify store with nothing to wire. Asking about individual products on top of it is still being finished. On a storefront you built yourself, see product ids.
Like everywhere else, the tracker's default on Shopify is to set its first-party cookies when it loads. If your compliance posture requires zero cookies before consent, switch on consent mode, one added line inside the snippet.
The part Shopify handles for you: with consent mode on, there are no banner callbacks to wire. Evarist reads Shopify's own Customer Privacy signal and follows your store's cookie banner automatically. (That applies to the Online Store; a headless storefront carries the signal only if it loads Shopify's customer-privacy runtime; otherwise wire your CMP callbacks as on any other site.)
Running Shopify behind a custom frontend instead of the Online Store (Hydrogen, or your own React/Next.js site)? A theme app embed can't reach those pages, so set up tracking manually with the two steps below. This works today, independent of the app. One exception: a Shopify-hosted customer or subscription portal (native Shopify customer accounts, or an app like Recharge's own portal) is still a Liquid Online Store page, so the app's theme app embed reaches it automatically even while your main storefront is headless, with no manual setup needed there.
Paste the tracking snippet into your storefront's root layout or template, on every page, not just one.
The common case, even with a custom frontend. Whenever you build or update the cart, set a Shopify cart custom attribute named _evarist to the value of the visitor's _evarist cookie, via the Storefront API's cartAttributesUpdate mutation:
mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {
cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {
cart { id }
userErrors { field message }
}
}
# variables
{
"cartId": "YOUR_CART_ID",
"attributes": [{ "key": "_evarist", "value": "VALUE_OF_THE_EVARIST_COOKIE" }]
}
It rides through to the order, so Evarist attributes the purchase to the right visitor, no matter where checkout renders. This only carries the anonymous visitor id, never anything about the customer. If you run subscriptions (through Recharge or another subscription app on top of Shopify), setting this attribute is required, not just helpful: in most subscription setups it is carried forward from the first order onto future rebills, which is what lets Evarist credit each rebill to the channel that originally acquired the subscriber instead of reporting it as unattributed revenue. How much of that carries through depends on the subscription app, so expect good coverage rather than every single rebill.
One timing note: the tracker loads asynchronously, so on a brand-new visit the _evarist cookie may not exist yet when you first create the cart. Read the cookie fresh at every cart mutation rather than caching it at page load, and have the handler that sends the shopper to checkout set the attribute one last time, so a cart created before the tracker finished loading still picks it up. The value present at checkout is the one that rides through; a cart that never got it simply shows as an unattributed order, nothing breaks.
If checkout isn't Shopify at all, install the snippet and tag your order-confirmation page as a goal, the same no-code flow as any other outcome: Track what matters.
If the amount varies per order, fire it from code with one JS call.