Skip to content

Instantly share code, notes, and snippets.

@ceaksan
Created April 17, 2026 20:38
Show Gist options
  • Select an option

  • Save ceaksan/13e1fc9da6c202a7ccbf26f4bbe97198 to your computer and use it in GitHub Desktop.

Select an option

Save ceaksan/13e1fc9da6c202a7ccbf26f4bbe97198 to your computer and use it in GitHub Desktop.
Shopify Custom Pixel - Multi-Market GA4 and Google Ads tracking with market-specific measurement and conversion IDs.
/**
* Shopify Custom Pixel - Multi-Market GA4 & Google Ads Tracking
*
* Routes Shopify Customer Events to market-specific GA4 measurement IDs
* and Google Ads conversion IDs based on the market cookie written by
* the market bridge (for storefront events) and the native localization
* object (for checkout events).
*
* Install via: Shopify Admin > Settings > Customer Events > Add custom pixel.
*
* Edit MARKET_CONFIG to match your markets, GA4 properties and
* Google Ads conversion IDs. Handles are expected to match
* localization.market.handle values.
*
* Pairs with:
* - storageHelper: https://gist.github.com/ceaksan/26c8a59aa8a518732a9a40da967d8cd2
* - market bridge: reads _shopify_m cookie written by the app embed snippet
*
* @see https://ceaksan.com/tr/shopify-multi-market-ga4-google-ads-olcum-id-eslemesi
* @license MIT
*/
// --- MARKET CONFIG ---
var MARKET_CONFIG = {
netherlands: {
ga4: "G-NL00000001",
adsConversionId: "AW-NL0000001",
adsConversionLabel: "nlLabel123",
currency: "EUR",
},
germany: {
ga4: "G-DE00000001",
adsConversionId: "AW-DE0000001",
adsConversionLabel: "deLabel456",
currency: "EUR",
},
_default: {
ga4: "G-XX00000001",
adsConversionId: "AW-XX0000001",
adsConversionLabel: "xxLabel000",
currency: "USD",
},
};
// Optional country-code fallback map
var MARKET_CONFIG_BY_COUNTRY = {
NL: MARKET_CONFIG.netherlands,
DE: MARKET_CONFIG.germany,
};
// --- CONSENT (from init, stable for page lifetime) ---
// visitorConsentCollected is a storefront event, not available in pixel sandbox
var consentGranted = init.customerPrivacy.analyticsProcessingAllowed;
// --- MARKET DATA ---
var cachedMarket = null;
var activeConfig = null;
var gtagLoaded = false;
async function getMarketData() {
if (cachedMarket) return cachedMarket;
var raw = await browser.cookie.get("_shopify_m");
if (raw) {
try {
cachedMarket = JSON.parse(decodeURIComponent(raw));
return cachedMarket;
} catch (e) {
console.warn("[pixel] Market cookie parse error:", e);
}
}
return null;
}
async function getMarketDataWithRetry(retries) {
retries = retries || 3;
var data = await getMarketData();
if (data) return data;
for (var i = 0; i < retries; i++) {
await new Promise(function (r) {
setTimeout(r, 150);
});
cachedMarket = null;
data = await getMarketData();
if (data) return data;
}
return null;
}
function getConfig(market) {
if (!market) return MARKET_CONFIG._default;
if (market.market && market.market.handle) {
var handle = market.market.handle;
if (MARKET_CONFIG[handle]) return MARKET_CONFIG[handle];
}
if (market.country && MARKET_CONFIG_BY_COUNTRY[market.country]) {
return MARKET_CONFIG_BY_COUNTRY[market.country];
}
return MARKET_CONFIG._default;
}
function getConfigFromLocalization(localization) {
if (!localization) return MARKET_CONFIG._default;
if (localization.market && localization.market.handle) {
var handle = localization.market.handle;
if (MARKET_CONFIG[handle]) return MARKET_CONFIG[handle];
}
if (localization.country && localization.country.isoCode) {
var code = localization.country.isoCode;
if (MARKET_CONFIG_BY_COUNTRY[code]) return MARKET_CONFIG_BY_COUNTRY[code];
}
return MARKET_CONFIG._default;
}
// --- GTAG ---
function loadGtag(measurementId) {
if (gtagLoaded) return;
var script = document.createElement("script");
script.src = "https://www.googletagmanager.com/gtag/js?id=" + measurementId;
script.async = true;
document.head.appendChild(script);
window.dataLayer = window.dataLayer || [];
window.gtag = function () {
dataLayer.push(arguments);
};
gtag("js", new Date());
gtagLoaded = true;
}
function ensureGtag(config, marketData) {
if (!gtagLoaded) {
loadGtag(config.ga4);
gtag("config", config.ga4, {
send_page_view: false,
market_handle:
marketData && marketData.market ? marketData.market.handle : "unknown",
market_country: marketData ? marketData.country : "unknown",
market_currency: marketData ? marketData.currency : "unknown",
});
}
}
// --- INIT ---
async function initTracking() {
if (!consentGranted) return;
var market = await getMarketDataWithRetry();
activeConfig = getConfig(market);
ensureGtag(activeConfig, market);
}
initTracking();
// --- STOREFRONT EVENTS ---
analytics.subscribe("page_viewed", async function (event) {
if (!consentGranted || !activeConfig) return;
gtag("event", "page_view", {
send_to: activeConfig.ga4,
page_location: event.context.document.location.href,
page_title: event.context.document.title,
page_referrer: event.context.document.referrer,
});
});
analytics.subscribe("product_viewed", async function (event) {
if (!consentGranted || !activeConfig) return;
var product = event.data.productVariant;
gtag("event", "view_item", {
send_to: activeConfig.ga4,
currency: product.price.currencyCode,
value: product.price.amount,
items: [
{
item_id: product.product.id,
item_name: product.product.title,
item_variant: product.title,
price: product.price.amount,
item_brand: product.product.vendor,
item_category: product.product.type,
quantity: 1,
},
],
});
});
analytics.subscribe("product_added_to_cart", async function (event) {
if (!consentGranted || !activeConfig) return;
var cartLine = event.data.cartLine;
var m = cartLine.merchandise;
gtag("event", "add_to_cart", {
send_to: activeConfig.ga4,
currency: cartLine.cost.totalAmount.currencyCode,
value: cartLine.cost.totalAmount.amount,
items: [
{
item_id: m.product.id,
item_name: m.product.title,
item_variant: m.title,
price: m.price.amount,
item_brand: m.product.vendor,
item_category: m.product.type,
quantity: cartLine.quantity,
},
],
});
});
analytics.subscribe("collection_viewed", async function (event) {
if (!consentGranted || !activeConfig) return;
var collection = event.data.collection;
gtag("event", "view_item_list", {
send_to: activeConfig.ga4,
item_list_id: collection.id,
item_list_name: collection.title,
});
});
analytics.subscribe("search_submitted", async function (event) {
if (!consentGranted || !activeConfig) return;
gtag("event", "search", {
send_to: activeConfig.ga4,
search_term: event.data.searchResult.query,
});
});
// --- CHECKOUT EVENTS (native localization is authoritative) ---
analytics.subscribe("checkout_started", async function (event) {
if (!consentGranted) return;
var checkout = event.data.checkout;
var config = getConfigFromLocalization(checkout.localization);
ensureGtag(config, null);
var items = checkout.lineItems.map(function (item) {
return {
item_id: item.variant.product.id,
item_name: item.title,
item_variant: item.variant.title,
price: item.variant.price.amount,
item_brand: item.variant.product.vendor,
item_category: item.variant.product.type,
quantity: item.quantity,
};
});
gtag("event", "begin_checkout", {
send_to: config.ga4,
currency: checkout.currencyCode,
value: checkout.totalPrice.amount,
items: items,
});
});
analytics.subscribe("checkout_completed", async function (event) {
if (!consentGranted) return;
var checkout = event.data.checkout;
var config = getConfigFromLocalization(checkout.localization);
ensureGtag(config, null);
var items = checkout.lineItems.map(function (item) {
return {
item_id: item.variant.product.id,
item_name: item.title,
item_variant: item.variant.title,
price: item.variant.price.amount,
item_brand: item.variant.product.vendor,
item_category: item.variant.product.type,
quantity: item.quantity,
};
});
var txId = checkout.order ? checkout.order.id : checkout.token;
gtag("event", "purchase", {
send_to: config.ga4,
transaction_id: txId,
currency: checkout.currencyCode,
value: checkout.totalPrice.amount,
tax: checkout.totalTax.amount,
shipping: checkout.shippingLine ? checkout.shippingLine.price.amount : 0,
items: items,
});
gtag("event", "conversion", {
send_to: config.adsConversionId + "/" + config.adsConversionLabel,
value: checkout.totalPrice.amount,
currency: checkout.currencyCode,
transaction_id: txId,
});
});
analytics.subscribe("payment_info_submitted", async function (event) {
if (!consentGranted) return;
var checkout = event.data.checkout;
var config = getConfigFromLocalization(checkout.localization);
ensureGtag(config, null);
gtag("event", "add_payment_info", {
send_to: config.ga4,
currency: checkout.currencyCode,
value: checkout.totalPrice.amount,
});
});
analytics.subscribe("checkout_shipping_info_submitted", async function (event) {
if (!consentGranted) return;
var checkout = event.data.checkout;
var config = getConfigFromLocalization(checkout.localization);
ensureGtag(config, null);
gtag("event", "add_shipping_info", {
send_to: config.ga4,
currency: checkout.currencyCode,
value: checkout.totalPrice.amount,
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment