Skip to content

Instantly share code, notes, and snippets.

@samba
Last active April 25, 2024 07:52
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save samba/3a6c901fac1459eda80d58388c996d40 to your computer and use it in GitHub Desktop.
Save samba/3a6c901fac1459eda80d58388c996d40 to your computer and use it in GitHub Desktop.
Shopify DataLayer Checkout
{% if first_time_accessed %}
<script>
(function(dataLayer){
var customer_type = ({{customer.orders_count}} > 1) ? 'repeatcustomer' : 'newcustomer';
var discounts = "{{ order.discounts | map: 'code' | join: ',' | upcase}}";
function strip(text){
return text.replace(/\s+/, ' ').replace(/^\s+/, '').replace(/\s+$/, '');
}
function firstof(){
for(var i = 0; i < arguments.length; i++){
if(arguments[i]) return arguments[i];
}
return null;
}
var products = [];
{% for line_item in order.line_items %}
products.push({
'id': firstof(strip('{{line_item.sku}}'), strip('{{line_item.product_id}}')),
'name': strip('{{line_item.product.title}}'),
'category': strip('{{line_item.product.type}}'),
'brand': strip('{{line_item.vendor}}'),
'variant': strip('{{line_item.variant.title}}'),
'coupon': "{{ line_item.discounts | map : 'code' | join: ',' | upcase}}",
'price': {{line_item.price | times: 0.01}},
'quantity': {{line_item.quantity}}
});
{% endfor %}
dataLayer.push({
'event': 'checkoutComplete',
'customerType': customer_type,
'ecommerce': {
'currencyCode': '{{shop.currency}}',
'purchase': {
'actionField': {
'id': '{{order.order_number}}',
'affiliation': strip('Shopify {{shop.name}}'),
'revenue': {{order.total_price | times: 0.01}},
'tax': {{order.tax_price | times: 0.01}},
'shipping': {{order.shipping_price | times: 0.01}},
'coupon': discounts
},
'products': products
}
}
});
setTimeout(function(){
// Clear the ecommerce data for subsequent hits.
dataLayer.push({ 'ecommerce': null });
}, 3);
}(window.dataLayer = window.dataLayer || []));
</script>
{% endif %}
<script>
function containsGTMStart(dl){
var i = 0;
dl.map(function(e){ if('gtm.start' in e) i++; });
return !!i;
}
(function(w,d,s,l,i){
w[l]=w[l]||[];
// attempts to prevent GTM from loading twice.
if(containsGTMStart(w[l])) return false;
w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),
dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXX');
</script>
@grace764
Copy link

Yes, the adapted script from my comment above works. It is not referencing the order object, but uses the accessible checkout variables directly.

Thanks will give it a try 👍

@PMM-customs
Copy link

Hey,

Could you explain what

| times: 0.01

does?

Thanks a lot for the code!

@samba
Copy link
Author

samba commented Jul 27, 2023

IIRC the "price" attribute is (by default) an integer representing cents so representing it as (floating point) dollars requires dividing it by 100; it was here implemented as multiplying by 0.01. This gets you better currency representation in GTM that is intuitively sensible. Hope that helps!

@adventuretocode
Copy link

@samba I am have setup code but still getting the error. order_number is null.

@wwwXpert
Copy link

wwwXpert commented Oct 24, 2023

Note:
I believe this depends on checkout.liquid. Unfortunately, checkout.liquid will be deprecated on August 13, 2024 and store owners will need to upgrade to Checkout Extensibility before then.

After upgrading, you will no longer have access or be able to edit the checkout.liquid file.

Reference: https://shopify.dev/docs/themes/architecture/layouts/checkout-liquid

To add customer events via GTM, refer to this page https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/gtm-tutorial

Web Pixels Overview: https://help.shopify.com/en/manual/promoting-marketing/pixels/overview

@chr1s1
Copy link

chr1s1 commented Oct 25, 2023

Note: I believe this depends on checkout.liquid. Unfortunately, checkout.liquid will be deprecated on August 13, 2024 and store owners will need to upgrade to Checkout Extensibility before then.

After upgrading, you will no longer have access or be able to edit the checkout.liquid file.

Reference: https://shopify.dev/docs/themes/architecture/layouts/checkout-liquid

To add customer events via GTM, refer to this page https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/gtm-tutorial

Web Pixels Overview: https://help.shopify.com/en/manual/promoting-marketing/pixels/overview

I am not editing the checkout.liquid to run the script.

@wwwXpert
Copy link

wwwXpert commented Oct 25, 2023

Hi @chr1s1

You've got some good code here. I read your instructions above regarding where to add the code.
Unfortunately, the Order Processing -> Additional Scripts input textarea is gone.

There are now two "Additional Scripts" areas.
One is under Post-purchase page section.
The second is under Order status page section.

With checkout extensibility, the entire checkout process is sandboxed. You're only able to push customer events data once you've completed your checkout and arrive at the order status page.

Your script would be added to the Order status page section > Additional Scripts.
Correct?

@VictorBirdo
Copy link

Hi @chr1s1

Instead of CustomerType: NewCustomer

Is it possible to use a boolean:

New customer: false

Depending on the {{customer.orders_count}} ?

As in: if {{customer.orders_count}} is greater than 0, newcustomer: false
if {{customer.orders_count}} equals 0, newcustomer: true

Has Anyone tried this?

Thank you very much and kind regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment