Last active
November 25, 2024 21:31
-
-
Save royvn/a1500e19c0aa1876271c40b47a176d5e to your computer and use it in GitHub Desktop.
Send consent from theme to Shopify pixel based on user consent choices. Default Shopify Cookie Banner required.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Docs: | |
// https://developers.google.com/tag-platform/security/concepts/consent-mode | |
// https://shopify.dev/docs/api/customer-privacy#check-data-processing-permissions | |
/** | |
* feedback | |
* @description Log the tracking status to the console. | |
*/ | |
function feedback() { | |
const p = Shopify.customerPrivacy; | |
console.log(`Tracking ${p.userCanBeTracked() ? 'en' : 'dis'}abled`); | |
} | |
/** | |
* Shopify.loadFeatures | |
* @description Load the Shopify Customer Privacy JavaScript library. With callback and event listeners. | |
*/ | |
Shopify.loadFeatures( | |
[ | |
{ | |
name: 'consent-tracking-api', | |
version: '0.1', | |
}, | |
], | |
(error) => { | |
if (error) throw error; | |
console.log('> Callback Shopify Customer Privacy JavaScript library'); | |
feedback(); | |
// Set state if it is already set | |
console.log('Set consent based on know info'); | |
sendConsentToPixel(); | |
// Event | |
document.addEventListener("visitorConsentCollected", function (event) { | |
console.log("> visitorConsentCollected"); | |
console.log(event); | |
sendConsentToPixel(); | |
}); | |
} | |
); | |
/** | |
* sendConsentToPixel | |
* @description Bridge consent object to Shopify's Web Pixel based on user consent choices. | |
*/ | |
function sendConsentToPixel() { | |
const event_name = 'consent_update'; | |
const event_data = { | |
ad_personalization: window.Shopify.customerPrivacy.marketingAllowed() ? 'granted' : 'denied', | |
ad_storage: window.Shopify.customerPrivacy.marketingAllowed() ? 'granted' : 'denied', | |
ad_user_data: window.Shopify.customerPrivacy.marketingAllowed() ? 'granted' : 'denied', | |
personalization_storage: window.Shopify.customerPrivacy.marketingAllowed() ? 'granted' : 'denied', | |
analytics_storage: window.Shopify.customerPrivacy.analyticsProcessingAllowed() ? 'granted' : 'denied', | |
functionality_storage: window.Shopify.customerPrivacy.preferencesProcessingAllowed() ? 'granted' : 'denied', | |
security_storage: window.Shopify.customerPrivacy.preferencesProcessingAllowed() ? 'granted' : 'denied', | |
wait_for_update: 500, | |
}; | |
console.log(event_name, event_data); | |
Shopify.analytics.publish(event_name, event_data); | |
feedback(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ content_for_header }} | |
{% comment %} Inject after content_for_header {% endcomment %} | |
<script src="{{ 'privacy-api-consent.js' | asset_url }}" defer></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('Pixel loaded.'); | |
// Can be added as a custom pixel under /settings/customer_events | |
const gtm_id = 'GTM-XXXXXXX'; | |
// 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_id); | |
// Set default consent | |
gtag('consent', 'default', { | |
ad_personalization: 'denied', | |
ad_storage: 'denied', | |
ad_user_data: 'denied', | |
analytics_storage: 'denied', | |
functionality_storage: 'denied', | |
personalization_storage: 'denied', | |
security_storage: 'granted', | |
wait_for_update: 500, | |
}); | |
gtag('set', 'ads_data_redaction', true); | |
gtag('set', 'url_passthrough', true); | |
// Custom events | |
analytics.subscribe('consent_update', (event) => { | |
console.log('> Web Pixel: event consent_update'); | |
const options = { | |
...event.customData, | |
}; | |
console.log(options); | |
// Update the consent based on cookiebot consent state | |
gtag('consent', 'update', options); | |
}); | |
// All standard Shopify events, https://shopify.dev/docs/api/web-pixels-api/standard-events | |
// 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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
country_code: event.data?.checkout?.shippingAddress?.countryCode, | |
province: event.data?.checkout?.shippingAddress?.province, | |
province_code: event.data?.checkout?.shippingAddress?.provinceCode, | |
zip: event.data?.checkout?.shippingAddress?.zip, | |
order_id: 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, | |
line_items: event.data?.checkout?.lineItems, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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?.merchandise?.id, | |
product_title: event.data?.cartLine?.merchandise?.product?.title, | |
quantity: event.data?.cartLine?.quantity, | |
total_cost: event.data?.cartLine?.cost?.totalAmount?.amount, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
product_title: event.data?.productVariant?.product?.title, | |
product_sku: event.data?.productVariant?.sku, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
fired_from: 'custom_pixel', | |
}); | |
}); | |
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, | |
fired_from: 'custom_pixel', | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment