Integrating UTM Parameter Persistence Across OpenCart Sessions for Attribution

Standard

In the modern privacy-first landscape, preserving UTM parameters across a user’s OpenCart session is crucial for accurate attribution, funnel analysis, and marketing ROI. Most users land with UTM tags (like from Google Ads), but lose attribution by the time they convert.

๐Ÿงฐ Prerequisites

Component Purpose
OpenCart 3.x or 4.x eCommerce platform
Google Tag Manager Installed across all pages
Google Analytics 4 Configured via GTM
Consent Mode v2 Optional but recommended for legality


๐Ÿ“ UTM Parameters Weโ€™ll Track

  • utm_source
  • utm_medium
  • utm_campaign
  • utm_content
  • utm_term


๐Ÿ“ฆ Step 1: Create a UTM Capture Script in OpenCart Header

Insert this script in catalog/view/theme/YOUR_THEME/template/common/header.twig:

<script>
(function() {
const getParam = (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'];

utmParams.forEach(param => {
const value = getParam(param);
if (value) {
localStorage.setItem(param, value);
document.cookie = `${param}=${value}; path=/; max-age=2592000`; // 30 days
}
});
})();
</script>

โœ… This stores the UTM values in both localStorage and cookie, making them accessible for both client-side and server-side scripts.


๐Ÿ—ƒ๏ธ Step 2: Push Stored UTM Values into dataLayer

Still inside header.twig or footer.twig, add:

<script>
window.dataLayer = window.dataLayer || [];

dataLayer.push({
event: 'utm_ready',
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 3: Configure GTM to Capture These Values

In GTM:

  1. Create Data Layer Variables:
    • DLV - utm_source โ†’ utm_source
    • DLV - utm_medium โ†’ utm_medium
    • DLV - utm_campaign โ†’ utm_campaign
    • DLV - utm_content โ†’ utm_content
    • DLV - utm_term โ†’ utm_term
  2. Modify GA4 Event Tags (purchase, add_to_cart, etc.):
    • Add custom parameters in the event tag: utm_source: {{DLV - utm_source}} utm_medium: {{DLV - utm_medium}} utm_campaign: {{DLV - utm_campaign}}
  3. Optionally send these as user properties in your GA4 Config tag: user_properties.utm_source: {{DLV - utm_source}}


โœ… Step 4: Inject UTM into Purchase Event on Success Page

In success.twig, ensure this is fired with each order:

<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: '{{ order_id }}',
value: {{ 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>

Then in GTM, update your purchase GA4 tag to include:

  • utm_source: {{DLV - attribution.utm_source}}
  • utm_medium: {{DLV - attribution.utm_medium}}
  • etc.


๐Ÿ” Step 5: Consent-Aware Storage (Optional)

If using a CMP (like Cookiebot), wrap the script like:

<script>
if (window.Cookiebot && Cookiebot.consents.given.marketing) {
// store or read UTM
}
</script>

Or use GTM’s consent settings to delay UTM storage until allowed.


๐Ÿงช Step 6: QA & Debugging

Tool Use Case
GTM Preview Mode Confirm UTM variables are available
GA4 DebugView Validate custom UTM parameters in events
Browser DevTools Inspect localStorage + cookies
GA4 โ†’ Explorations Build audience filters by UTM data


๐Ÿ“Š Strategic Value of UTM Persistence

Benefit Why It Matters
Survives multi-day journeys Users can convert days later with credit
Enables retargeting segmentation Segment by campaign even after bounce
Fixes attribution gaps Avoids (direct) / (none) in GA4
Powers server-side attribution UTM from cookies = backend use


Leave a Reply

Your email address will not be published. Required fields are marked *