Shopify: Difference between revisions
Ben.robson (talk | contribs) No edit summary |
Ben.robson (talk | contribs) |
||
| (12 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
= Shopify Pixel = | = Shopify Pixel = | ||
The old method is due to be deprecated in Dec-24, so this will only be available until then. | The old method is due to be deprecated in Dec-24, so this will only be available until then. </br> | ||
New Shopify sites also appear to have checkout scripts disabled by default. | New Shopify sites also appear to have checkout scripts disabled by default. </br> | ||
The new method for adding tracking to Shopify sites is through a Custom Pixel | The new method for adding tracking to Shopify sites is through a Custom Pixel. </br> | ||
Based on Shopifys documentation: | Based on Shopifys documentation:</br> | ||
[https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/gtm-tutorial Creating a GTM pixel] | [https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/gtm-tutorial Creating a GTM pixel]</br> | ||
< | [https://shopify.dev/docs/api/web-pixels-api/pixel-privacy Pixel privacy documentation]</br> | ||
Go to Settings > Customer Events > Add Custom Pixel | - Go to Settings > Customer Events > Add Custom Pixel. | ||
Set the Customer Privacy settings to Not required | - Set the Customer Privacy settings to Not required. | ||
Set Data Sale to Data collected does not qualify as data sale | - Set Data Sale to Data collected does not qualify as data sale. | ||
- Add the below code. | |||
<pre> | <pre> | ||
| Line 24: | Line 24: | ||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= | 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); | 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); | ||
})(window,document,'script','dataLayer', 'GTM- | })(window,document,'script','dataLayer', 'GTM-XXXXXX'); | ||
let customerPrivacyStatus = init.customerPrivacy; | let customerPrivacyStatus = init.customerPrivacy; | ||
let | let ad_permission = ( customerPrivacyStatus.marketingAllowed ? 'granted' : 'denied' ); | ||
let analytics_permission = ( customerPrivacyStatus.analyticsProcessingAllowed ? 'granted' : 'denied' ); | |||
//Google Consent Mode v2 | //Google Consent Mode v2 | ||
gtag('consent', 'default', { | gtag('consent', 'default', { | ||
'ad_storage': | 'ad_storage': ad_permission, | ||
'analytics_storage': | 'analytics_storage': analytics_permission, | ||
'ad_user_data': | 'ad_user_data': ad_permission, | ||
'ad_personalization': | 'ad_personalization': ad_permission, | ||
}); | }); | ||
| Line 41: | Line 42: | ||
window.dataLayer = window.dataLayer || []; | window.dataLayer = window.dataLayer || []; | ||
let customerPrivacyStatus = event.customerPrivacy; | let customerPrivacyStatus = event.customerPrivacy; | ||
let | let ad_permission = ( customerPrivacyStatus.marketingAllowed ? 'granted' : 'denied' ); | ||
let analytics_permission = ( customerPrivacyStatus.analyticsProcessingAllowed ? 'granted' : 'denied' ); | |||
gtag('consent', 'update', { | gtag('consent', 'update', { | ||
'ad_storage': | 'ad_storage': ad_permission, | ||
'analytics_storage': | 'analytics_storage': analytics_permission , | ||
'ad_user_data': | 'ad_user_data': ad_permission, | ||
'ad_personalization': | 'ad_personalization': ad_permission, | ||
}); | }); | ||
}); | }); | ||
| Line 244: | Line 247: | ||
quantity: event.data?.cartLine?.quantity, | quantity: event.data?.cartLine?.quantity, | ||
total_cost: event.data?.cartLine?.cost?.totalAmount?.amount, | total_cost: event.data?.cartLine?.cost?.totalAmount?.amount, | ||
}); | }); | ||
}); | }); | ||
| Line 307: | Line 309: | ||
}); | }); | ||
}); | }); | ||
</pre> | |||
Custom events (for example contact form submissions) have to be sent by adding an event to the liquid files: | |||
<pre> | |||
<script> | |||
document.addEventListener("DOMContentLoaded", function (event) { | |||
Shopify.analytics.publish('EVENT_NAME_HERE'); | |||
}); | |||
</script> | |||
</pre> | |||
Which can then be accessed within the pixel with the same logic as the standard events: | |||
<pre> | |||
analytics.subscribe("EVENT_NAME_HERE", (event) => { | |||
window.dataLayer.push({ | |||
'event': 'EVENT_NAME' | |||
}); | |||
}); | |||
</pre> | |||
The below can also be added to have access to the dataLayer in console, which should be useful for debugging/testing: | |||
<pre> | |||
analytics.subscribe("check_datalayer", (event) => { | |||
console.log(dataLayer); | |||
}) | |||
</pre> | |||
This can then be called from console with the following: | |||
<pre> | |||
Shopify.analytics.publish('check_datalayer'); | |||
</pre> | |||
== File Location == | |||
The Shopify pixel loads the JS into a JS file which is loaded by the browser.<br /> | |||
The location of this can be built by using data from the home web page.<br /><br /> | |||
<pre> | |||
https://<<domain>>/wpm@<<wpm_id>>/custom/web-pixel-<<pixel_id>>@<<script_version>>/sandbox/modern/ | |||
wpm_id - is the version of the wpm (Web Pixel Manager), this is the same across all sites and will change when the wpm is updated by shopify. | |||
pixel_id - this is found via the JSON below that is on the site | |||
script_version - this is found via the JSON below that is on the site | |||
{"id":"<<pixel_id >>","eventPayloadVersion":"1","runtimeContext":"LAX","scriptVersion":"<<script_version>>","type":"CUSTOM","privacyPurposes":[],"name":"GTM + Value Tracking"} | |||
</pre> | </pre> | ||
Latest revision as of 11:13, 12 December 2025
Shopify Pixel
The old method is due to be deprecated in Dec-24, so this will only be available until then.
New Shopify sites also appear to have checkout scripts disabled by default.
The new method for adding tracking to Shopify sites is through a Custom Pixel.
Based on Shopifys documentation:
Creating a GTM pixel
Pixel privacy documentation
- Go to Settings > Customer Events > Add Custom Pixel. - Set the Customer Privacy settings to Not required. - Set Data Sale to Data collected does not qualify as data sale. - Add the below code.
// Define dataLayer and the gtag function.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
//Initialize GTM tag
(function(w,d,s,l,i){w[l]=w[l]||[];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-XXXXXX');
let customerPrivacyStatus = init.customerPrivacy;
let ad_permission = ( customerPrivacyStatus.marketingAllowed ? 'granted' : 'denied' );
let analytics_permission = ( customerPrivacyStatus.analyticsProcessingAllowed ? 'granted' : 'denied' );
//Google Consent Mode v2
gtag('consent', 'default', {
'ad_storage': ad_permission,
'analytics_storage': analytics_permission,
'ad_user_data': ad_permission,
'ad_personalization': ad_permission,
});
// Use the customerPrivacy Standard API to subscribe to consent collected events and update the status
api.customerPrivacy.subscribe('visitorConsentCollected', (event) => {
window.dataLayer = window.dataLayer || [];
let customerPrivacyStatus = event.customerPrivacy;
let ad_permission = ( customerPrivacyStatus.marketingAllowed ? 'granted' : 'denied' );
let analytics_permission = ( customerPrivacyStatus.analyticsProcessingAllowed ? 'granted' : 'denied' );
gtag('consent', 'update', {
'ad_storage': ad_permission,
'analytics_storage': analytics_permission ,
'ad_user_data': ad_permission,
'ad_personalization': ad_permission,
});
});
//subscribe to events
analytics.subscribe("checkout_completed", (event) => {
window.dataLayer.push({
event: "checkout_completed",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
Other Ecommerce events that could be useful:
analytics.subscribe("payment_info_submitted", (event) => {
window.dataLayer.push({
event: "payment_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_shipping_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_shipping_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_address_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_address_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_contact_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_contact_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_started", (event) => {
window.dataLayer.push({
event: "checkout_started",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("product_added_to_cart", (event) => {
window.dataLayer.push({
event: "product_added_to_cart",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
price: event.data?.cartLine?.merchandise?.price?.amount,
currency: event.data?.cartLine?.cost?.totalAmount?.currencyCode,
product_id: event.data?.cartLine?.merchandise?.product?.id + '_' + event.data?.cartLine?.merchandise?.id,
product_title: event.data?.cartLine?.merchandise?.product?.title,
quantity: event.data?.cartLine?.quantity,
total_cost: event.data?.cartLine?.cost?.totalAmount?.amount,
});
});
analytics.subscribe("cart_viewed", (event) => {
window.dataLayer.push({
event: "cart_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
total_cost: event.data?.cart?.cost?.totalAmount?.amount,
quantity: event.data?.cart?.totalQuantity,
cart_id: event.data?.cart?.id,
});
});
analytics.subscribe("page_viewed", (event) => {
window.dataLayer.push({
event: "page_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
page_title: event.context.document.title,
});
});
analytics.subscribe("product_viewed", (event) => {
window.dataLayer.push({
event: "product_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
product_id: event.data?.productVariant?.product?.id + '_' + event.data?.productVariant?.id,
product_title: event.data?.productVariant?.title,
product_sku: event.data?.productVariant?.sku,
});
});
analytics.subscribe("search_submitted", (event) => {
window.dataLayer.push({
event: "search_submitted",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
query: event.data?.searchResult?.query,
});
});
analytics.subscribe("collection_viewed", (event) => {
window.dataLayer.push({
event: "collection_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
collection_id: event.data?.collection?.id,
collection_title: event.data?.collection?.title,
});
});
Custom events (for example contact form submissions) have to be sent by adding an event to the liquid files:
<script>
document.addEventListener("DOMContentLoaded", function (event) {
Shopify.analytics.publish('EVENT_NAME_HERE');
});
</script>
Which can then be accessed within the pixel with the same logic as the standard events:
analytics.subscribe("EVENT_NAME_HERE", (event) => {
window.dataLayer.push({
'event': 'EVENT_NAME'
});
});
The below can also be added to have access to the dataLayer in console, which should be useful for debugging/testing:
analytics.subscribe("check_datalayer", (event) => {
console.log(dataLayer);
})
This can then be called from console with the following:
Shopify.analytics.publish('check_datalayer');
File Location
The Shopify pixel loads the JS into a JS file which is loaded by the browser.
The location of this can be built by using data from the home web page.
https://<<domain>>/wpm@<<wpm_id>>/custom/web-pixel-<<pixel_id>>@<<script_version>>/sandbox/modern/
wpm_id - is the version of the wpm (Web Pixel Manager), this is the same across all sites and will change when the wpm is updated by shopify.
pixel_id - this is found via the JSON below that is on the site
script_version - this is found via the JSON below that is on the site
{"id":"<<pixel_id >>","eventPayloadVersion":"1","runtimeContext":"LAX","scriptVersion":"<<script_version>>","type":"CUSTOM","privacyPurposes":[],"name":"GTM + Value Tracking"}
Tag Manager
Add Tag Manager to theme: Modify Theme
"online store" -> "..." or "Actions" -> "edit HTML / CSS"
Modify theme.liquid
Google Tag Manager will also need to be added to Checkout's additional settings to track conversions
Conversion Tracking Code
Google Tag Manager will also need to be added to Checkout's additional settings to track conversions
In "settings" -> "checkout" -> "additional settings"
{% if first_time_accessed %}
<script>
var dataLayer = window.dataLayer || [];
dataLayer.push({'order_id' : '{{ order_number }}', 'order_value' : '{{ total_price | money_without_currency }}', 'event' : 'order-submitted'});
</script>
{% endif %}
- Note: if testing without "{% if first_time_accessed %}" on a order that has already converted, the order ID will not show
to add product ids add within the code above:
dataLayer.push({ 'product_ids' : [{% for line_item in line_items %}{{ line_item.product_id }}{% unless forloop.last == true %}, {% endunless %}{% endfor %}] });
- Note: This was made for dynamic re-marketing, for analytics 4 go to the section below
Tracking Contact Page
In the snippets section, go to "form-status.liquid" or "contact.liquid".
Find the snippet that shows the success text ( in-between {%- if form.posted_successfully? -%}{%- endif -%} ), Then add:
<script>
var dataLayer = window.dataLayer || [];
dataLayer.push({'event' : 'contact-form-submitted'});
</script>
Product Feed
The below App is free to use & should do most of the setup for you:
https://apps.shopify.com/google
After installing the App a Google account with access to the Merchant Centre needs to sign in.
DO NOT sign in using one of our Master email addresses, instead you can either:
- Ask the client to do this, if they don't have access to Merchant Center we can try to add them. - Create a new email address that only has access to this Merchant Center & sign in with this instead.
Then the below needs to be done, in this order otherwise it won't send the products through & you'll have to start from scratch:
- Make sure the Store requirements are met & confirm these, if they aren't then send this back to the client so they can add whats necessary. - Under Product Feed, start the setup process. - Connect the Merchant Centre on the settings tab. - Specify the Target Market & set the Shipping settings to Manual (These will need to be added to Merchant Center by someone afterwards).
If this has been done correctly then the products should now be available within the Merchant Center account.
Below is for Reference, Do not use!
Alternatively, Shopify does provide you with the Product feed URL for your store.
To access this, you will need to append .atom to either all of your collections or to a specific collection URL.
For example:
"yourstorename.com/collections/all.atom" "yourstorename.com/collections/collectionname.atom"
Events for Analytics 4
View Item:
Add this to product-template.liquid
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: "view_item",
ecommerce: {
currency: "GBP",
items: [
{
item_id: {{ product.id }},
item_name: "{{ product.title }}",
{% if product.vendor %} item_brand: "{{ product.vendor }}", {% endif %}
price: {{ product.price | money_without_currency }},
{% if product.type %} item_category: "{{ product.type }}", {% endif %}
google_business_vertical: "retail",
id: "{{ product.id }}"
}
]
},
});
</script>
Add To Cart:
The below listener can be added to GTM, this should send add_to_cart events to GTM for you.
<script>
jQuery(document).ready(function() {
jQuery( document ).ajaxSuccess(function( event, xhr, settings, data ) {
if (~settings.url.indexOf("/cart/add")) {
var items = [];
items.push({
item_id: data.product_id,
item_name: data.title,
item_category: data.product_type,
price: ( data.price / 100 ),
google_business_vertical: "retail",
id: data.product_id
});
if (typeof data.brand != "undefined") items[0]['item_brand'] = data.brand;
var dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: "GBP",
items: items
}
});
}
});
});
</script>
Purchases:
Add this to the Settings > Checkout > Additional Scripts section.
{% if first_time_accessed %}
<script>
var items = [];
var temp = {};
{% for line_item in line_items %}
temp = {
item_id: {{ line_item.product.id }},
item_name: "{{ line_item.title }}",
price: {{ line_item.final_line_price | money_without_currency }},
google_business_vertical: "retail",
id: {{ line_item.product.id }},
quantity: {{ line_item.quantity }}
};
{% if line_item.product.type %}
temp['item_category'] = "{{ line_item.product.type }}";
{% endif %}
{% if line_item.product.vendor %}
temp['item_brand'] = "{{ line_item.product.vendor }}";
{% endif %}
items.push(temp);
{% endfor %}
var dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'purchase',
ecommerce: {
affiliation: 'Online Store',
transaction_id: '{{ order_number }}',
value: '{{ total_price | money_without_currency }}',
tax: '{{ tax_price | money_without_currency }}',
shipping: '{{ shipping_price | money_without_currency}}',
currency: "GBP",
items: items
}
});
</script>
{% endif %}
The Event Tag & Variables can be setup with the below template:
File:Shopify-ga4-container-elements.json
Shopify Links
Cheat sheet for Variables:
https://www.shopify.co.uk/partners/shopify-cheat-sheet