Follow the steps in this guide to set up Google Analytics 4 tracking in Shopify using Customer events (Custom pixel)
NOTE: Read this guide if you prefer using Google Tag Manager template https://knowledge.profitmetrics.io/how-to-set-up-google-analytics-4-with-e-commerce-events-in-google-tag-manager
NOTE: Read this guide if you prefer to configure in Google Tag Manager manually
Click here for instructions on How to manually set up Google Analytics 4 (GA4) in Google Tag Manager
// ProfitMetrics - Google Analytics 4 - v2.0
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
function getConsentStatus( cookieCMP ) {
let consentMarketing = true;
let consentAnalytics = true;
try {
const cmp_a = cookieCMP;
const cookiedecoded = JSON.parse( decodeURIComponent( cmp_a ) );
consentMarketing = cookiedecoded?.purposes?.m ?? consentMarketing;
consentAnalytics = cookiedecoded?.purposes?.a ?? consentAnalytics;
} catch( e ) {
}
return {
'ad_storage': consentMarketing ? 'granted' : 'denied',
'ad_user_data': consentMarketing ? 'granted' : 'denied',
'ad_personalization': consentMarketing ? 'granted' : 'denied',
'analytics_storage': consentAnalytics ? 'granted' : 'denied'
};
}
const script = document.createElement( 'script' );
script.setAttribute( 'src', 'https://www.googletagmanager.com/gtag/js?id=G-AAAAAAAAAA' );
script.setAttribute( 'async', '' );
document.head.appendChild( script );
gtag("js", new Date());
gtag("config", "G-AAAAAAAAAA");
gtag("config", "G-BBBBBBBBBB");
const eventData = {
getItemsFromLineItems(lineItems) {
let items = []
for (const item of lineItems) {
items.push({
item_id: item.variant.product.id,
item_name: item.variant.product.title,
})
}
return items
},
getPageViewData(evt) {
let ctx = evt.context
return {
page_location: ctx.document.location.href,
page_title: ctx.document.title,
language: ctx.language,
}
},
getViewItemData(evt) {
return {
currency: evt.data.productVariant.price.currencyCode,
value: evt.data.productVariant.price.amount,
items: [{ item_id: evt.data.productVariant.id, item_name: evt.data.productVariant.product.title }],
}
},
getAddToCartData(evt) {
return {
currency: evt.data.cartLine.merchandise.price.currencyCode,
value: evt.data.cartLine.merchandise.price.amount,
items: [{ item_id: evt.data.cartLine.merchandise.id, item_name: evt.data.cartLine.merchandise.product.title }],
}
},
getPaymentInfoData(evt) {
return {
currency: evt.data.checkout.currencyCode,
value: evt.data.checkout.totalPrice.amount,
items: this.getItemsFromLineItems(evt.data.checkout.lineItems),
}
},
getCheckoutData(evt) {
return {
currency: evt.data.checkout.currencyCode,
value: evt.data.checkout.totalPrice.amount,
items: this.getItemsFromLineItems(evt.data.checkout.lineItems),
}
},
getCheckoutCompletData(evt) {
return {
transaction_id: evt.data.checkout.order.id,
currency: evt.data.checkout.currencyCode,
value: evt.data.checkout.totalPrice.amount,
items: this.getItemsFromLineItems(evt.data.checkout.lineItems),
}
}
}
analytics.subscribe("page_viewed", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "page_view", eventData.getPageViewData(event));
});
analytics.subscribe("product_viewed", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "view_item", eventData.getViewItemData(event));
});
analytics.subscribe("search_submitted", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "search", {
search_term: event.data.searchResult.query,
});
});
analytics.subscribe("product_added_to_cart", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "add_to_cart", eventData.getAddToCartData(event));
});
analytics.subscribe("payment_info_submitted", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "add_payment_info", eventData.getPaymentInfoData(event));
});
analytics.subscribe("checkout_started", async (event) => {
const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
gtag('consent', 'update', actualConsent );
gtag("event", "begin_checkout", eventData.getCheckoutData(event));
});
// Disabled - Purchase events are sent server-side by ProfitMetircs.
// analytics.subscribe("checkout_completed", async (event) => {
// const actualConsent = getConsentStatus( await browser.cookie.get( '_cmp_a' ) );
// gtag('consent', 'update', actualConsent );
// gtag("event", "purchase", eventData.getCheckoutCompletData(event));
// );
- Log in to https://admin.shopify.com
- Click "Settings"
- Click "Customer Events"
- Click "Add custom pixel"
- Name the custom pixel "ProfitMetrics - GA4" and click "Add pixel"
- Click "Permissions" and select your preferred permission set.
CAUTION: Choosing the correct "Permission" and "Data Sale" settings is ultimately your responsibility. Please consult a lawyer or legal expert.
By default, the pixel will only fire when Marketing and Statistics consent is granted. Please ensure your Cookie Banner and Shopify Consent API are connected properly in order for consent to be registered.
Some countries allow the use of "basic statistic tracking" without consent. This requires that all Marketing related settings and options in Google Analytics 4 are disabled. If this relevant to you, you can opt for the "Not required" option under "Permissions" and "Data collection does not qualify as data sale" under "Data Sale. " - Click "Permission"
- Select "Not required"
- Click "Data sale"
- Select "Data collected does not qualify as data sale"
- Click "Permission"
- Select "Not required"
- Click "Data sale"
- Select "Data collected does not qualify as data sale"
- Paste the code into the Code field
- Replace the default code with the code provided by ProfitMetrics or use the code below and remember to update G-XXXXXXXX and G-YYYYYYYYY with your Revenue and Gross Profit Measurement IDs.
- Click "Save"
- Click "Connect" and then "Connect" again.
All done. The Custom Pixel will now track all e-commerce events except Purchase which is handled by ProfitMetrics.