A real-world case study showing how attribution data (UTM, gclid, fbclid) was captured, persisted, and sent to Shopify orders for accurate marketing attribution. This guide walks through the architecture, implementation, and tracking strategy used in a live TinyBot client project.
Emtiaz Hossain
Attribution & Conversion Tracking Specialist
Most Shopify stores struggle with accurate attribution.
Marketing teams run campaigns across:
But when an order is created in Shopify, the original attribution data is often lost.
In this project with a U.S. marketing agency (TinyBot), the goal was clear:
Capture attribution parameters from the first visit and attach them directly to Shopify orders.
This allows the agency to know exactly which campaign generated each purchase.
When users land on a Shopify store, attribution data exists only in the URL parameters.
Example:
?utm_source=google&utm_medium=cpc&utm_campaign=summer_sale&gclid=123abcBut Shopify's default system has problems:
For marketing agencies managing paid ads, this creates incorrect reporting and wasted budget decisions.
To solve this, I built a three-layer attribution system.
When the user lands on the website, we capture:
These values are stored in browser localStorage
Instead of storing only UTM parameters, the tracking system captures multi-platform click IDs, browser cookies, and campaign parameters, then persists them inside localStorage and sends them to Shopify cart attributes.
This allows attribution data to survive:
The script is injected directly into the Shopify theme:
Location
Shopify Admin
→ Online Store
→ Themes
→ Edit Code
→ theme.liquid
→ Insert after <head>These identifiers allow revenue to be traced back to ad platforms.
Google Ads → gclid, gbraid, wbraid
Meta Ads → fbclid
TikTok → ttclid
Microsoft Ads → msclkid
LinkedIn → li_fat_id
Pinterest → epik
Snapchat → sc_click_id
Twitter/X → twclid
Reddit → rdtclid
Taboola → tblci
Outbrain → ob_click_idSome platforms create first-party cookies used for attribution.
_fbp → Meta browser identifier
_fbc → Meta click identifier
_ttp → TikTok tracking cookieStandard campaign tracking parameters are also captured.
utm_source
utm_medium
utm_campaign
utm_term
utm_content
utm_id
utm_source_platform
utm_creative_format
utm_marketing_tactic(function () {
function getParam(name){
try { return new URLSearchParams(location.search).get(name); }
catch(e){ return null; }
}
function getCookie(name){
try{
var m = document.cookie.match(
new RegExp('(?:^|; )'+name.replace(/[$()*+./?[\\\]^{|}-]/g,'\\$&')+'=([^;]*)')
);
return m ? decodeURIComponent(m[1]) : null;
} catch(e){ return null; }
}
function setLS(key,obj){
try{ localStorage.setItem(key, JSON.stringify(obj)); }
catch(e){}
}
function getLS(key){
try{
var v = localStorage.getItem(key);
return v ? JSON.parse(v) : null;
} catch(e){ return null; }
}
function merge(a,b){
a = a || {};
Object.keys(b || {}).forEach(function(k){
if(b[k] !== null && b[k] !== undefined && b[k] !== ""){
a[k] = b[k];
}
});
return a;
}
})();The script uses localStorage instead of cookies for persistence.
Why?
| Method | Limitation |
|---|---|
| Cookies | Can be blocked or overwritten |
| HttpOnly cookies | Not readable by JavaScript |
| URL parameters | Lost after navigation |
| localStorage | Reliable client-side persistence |
The data is stored as a structured object:
{
"click_ids": {
"gclid": "abc123",
"fbclid": "xyz456"
},
"cookies": {
"_fbp": "fb.1.123456789"
},
"utm": {
"utm_source": "google",
"utm_campaign": "summer_sale"
},
"meta": {
"landing_url": "https://example.com/?utm_source=google"
}
}Once attribution is stored, the script flattens important fields and sends them to Shopify cart attributes.
This ensures the values are attached to the order once checkout completes.
fetch('/cart/update.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
attributes: flatAttributes
})
});Example attributes stored in Shopify:
utm_source : google
utm_medium : cpc
utm_campaign : summer_sale
gclid : Cj0KCQj...
landing_url : https://example.com/?utm_source=googleThese attributes appear directly inside the Shopify order admin panel.

This approach solves multiple attribution problems simultaneously.
| Problem | Solution |
|---|---|
| UTM disappears after navigation | localStorage persistence |
| Multi-platform ads | multi click-ID capture |
| Checkout attribution loss | Shopify cart attributes |
| Cross-platform reporting mismatch | consistent attribution storage |
For marketing agencies running campaigns across multiple platforms, this creates a reliable attribution pipeline from click → order.
Get a detailed audit of your tracking architecture. Find exactly where your data is lying and fix it — before you spend another dollar on ads.