Traditional client-side tracking increasingly suffers from cookie loss, ITP restrictions, and blocked third-party JavaScript. The solution? Leverage first-party attribution tracking using Google Tag Manager (GTM) and Google Analytics 4 (GA4)βfully powered by your own OpenCart site.
π§° Prerequisites
| Component | Description |
|---|---|
| OpenCart 3.x or 4.x | With editable Twig templates |
| Google Tag Manager | Installed across all pages |
| Google Analytics 4 | Setup with active Config Tag |
| Consent Mode v2 | Recommended for legal compliance |
π Goal
- Capture UTM parameters (source, medium, campaign, content, term)
- Store them in first-party cookies or
localStorage - Reuse values on checkout/purchase events
- Send them to GA4 for accurate attribution
π¦ Step 1: Capture & Store UTM Parameters in Cookie/LocalStorage
Add this script to the header of your OpenCart layout (header.twig):
<script>
(function() {
function getParameter(name) {
const match = new RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
let data = {};
utmParams.forEach(function(param) {
const value = getParameter(param);
if (value) {
localStorage.setItem(param, value);
data[param] = value;
}
});
if (Object.keys(data).length) {
console.log('Stored UTM Params:', data);
}
})();
</script>
β This will persist UTM values for future page loadsβeven if the user buys 2 days later.
π Step 2: Read Stored UTM Values into dataLayer
Place this just below the script above (in header.twig or footer.twig):
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'utm_capture',
utm_source: localStorage.getItem('utm_source') || 'direct',
utm_medium: localStorage.getItem('utm_medium') || 'none',
utm_campaign: localStorage.getItem('utm_campaign') || '(not set)',
utm_content: localStorage.getItem('utm_content') || '',
utm_term: localStorage.getItem('utm_term') || ''
});
</script>
π This makes UTM values available as Data Layer Variables in GTM.
π Step 3: Inject UTM Values on Purchase Page (success.twig)
In your success.twig file:
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: '{{ order_id }}',
value: {{ order_total }},
currency: '{{ currency }}',
items: [
{% for product in products %}
{
item_id: '{{ product.product_id }}',
item_name: '{{ product.name }}',
price: '{{ product.price }}',
quantity: '{{ product.quantity }}'
}
{% if not loop.last %},{% endif %}
{% endfor %}
]
},
attribution: {
utm_source: localStorage.getItem('utm_source'),
utm_medium: localStorage.getItem('utm_medium'),
utm_campaign: localStorage.getItem('utm_campaign'),
utm_content: localStorage.getItem('utm_content'),
utm_term: localStorage.getItem('utm_term')
}
});
</script>
π― Step 4: Send Attribution Data to GA4 via GTM
In GTM:
- Create Variables:
DLV - attribution.utm_sourceDLV - attribution.utm_mediumDLV - attribution.utm_campaignDLV - attribution.utm_contentDLV - attribution.utm_term
- Create GA4 Event Tag (Purchase):
- Event Name:
purchase - Parameters:
utm_source:{{DLV - attribution.utm_source}}utm_medium:{{DLV - attribution.utm_medium}}utm_campaign:{{DLV - attribution.utm_campaign}}- (Include product info via
ecommerceobject)
- Event Name:
β These values will now appear under User Acquisition and Traffic Source in GA4βeven if the user bought days after their initial visit.
π Step 5: Optional β Respect Consent
Wrap attribution logic inside a consent check:
if (window.Cookiebot && Cookiebot.consents.given.marketing) {
// push dataLayer or store UTM values
}
Or configure GTM tags to require additional consent signals (ad_storage, analytics_storage).
π§ͺ Step 6: QA & Debugging
| Tool | Use Case |
|---|---|
| GTM Preview | Check if UTM values pass into variables |
| GA4 DebugView | Confirm values are attached to events |
| Network > collect | Inspect payloads to GA4 server endpoint |
| DevTools > Application | Confirm localStorage values |
π§ Pro Tips
| Strategy | Benefit |
|---|---|
| Use localStorage (not cookies) | Avoids cookie blocking by ITP |
Fallback to direct/none |
Prevents missing attribution |
| Persist values for 30+ days | Extend attribution windows manually |
| Use in BigQuery exports | Analyze attribution across touchpoints |
π Benefits of First-Party Attribution
- Survives cross-session journeys
- Complies with cookie laws & privacy requirements
- Avoids reliance on 3rd-party cookies (blocked on Safari/Firefox)
- Empowers GA4βs audience & conversion modeling
