Skip to content

Instantly share code, notes, and snippets.

@blanklob
Created July 1, 2023 23:40
Show Gist options
  • Select an option

  • Save blanklob/35f290c2428aef51a56593cca34553c8 to your computer and use it in GitHub Desktop.

Select an option

Save blanklob/35f290c2428aef51a56593cca34553c8 to your computer and use it in GitHub Desktop.

Revisions

  1. blanklob created this gist Jul 1, 2023.
    110 changes: 110 additions & 0 deletions ga4-shopify-custom-pixel.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,110 @@
    // Step 1. Add and initialize your third-party JavaScript pixel (make sure to exclude HTML)
    // Replace with you GA4 Tag
    const TAG_ID = 'G-XXXXXXXXXX';

    const script = document.createElement('script');
    script.setAttribute('src', `https://www.googletagmanager.com/gtag/js?id=${TAG_ID}`);
    script.setAttribute('async', '');
    document.head.appendChild(script);

    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}

    gtag('js', new Date());
    gtag('config', TAG_ID);

    // Step 2. Subscribe to customer events using the analytics.subscribe() API
    const sendGAEvent = (eventName, eventData) => {
    gtag("event", eventName, eventData);
    };

    const createItemData = (product) => {
    return {
    item_id: product.sku,
    item_name: product.product.title,
    item_variant: product.title,
    currency: product.price.currencyCode,
    item_brand: product.product.vendor,
    price: product.price.amount,
    };
    };

    const createLineItemsData = (lineItems) => {
    return lineItems.map((item) => {
    return {
    item_id: item.variant.sku,
    item_name: item.title,
    item_variant: item?.variant.title,
    currency: item.variant.price.currencyCode,
    item_brand: item.variant.product.vendor,
    price: item.variant.price.amount,
    quantity: item.quantity,
    };
    });
    };

    analytics.subscribe("search_submitted", (event) => {
    const { query } = event.data.searchResult;
    sendGAEvent("search", { search_term: query });
    sendGAEvent("view_search_results", { search_term: query, items: [] });
    });

    analytics.subscribe("collection_viewed", (event) => {
    const { id, title } = event.data.collection;
    sendGAEvent("view_item_list", { item_list_id: id, item_list_name: title, items: [] });
    });

    analytics.subscribe("product_added_to_cart", (event) => {
    const { cartLine } = event.data;
    const totalPrice = cartLine.merchandise.price.amount * cartLine.quantity;
    const itemData = createItemData(cartLine.merchandise.product);

    sendGAEvent("add_to_cart", {
    currency: cartLine.merchandise.price.currencyCode,
    value: totalPrice.toFixed(2),
    items: [Object.assign(itemData, { quantity: cartLine.quantity })],
    });
    });

    analytics.subscribe("product_viewed", (event) => {
    const { productVariant } = event.data;
    const itemData = createItemData(productVariant);

    sendGAEvent("view_item", {
    currency: productVariant.price.currencyCode,
    value: productVariant.price.amount,
    items: [itemData],
    });
    });

    analytics.subscribe("checkout_started", (event) => {
    const checkoutData = ga4CheckoutEvents(event);
    sendGAEvent("begin_checkout", checkoutData);
    });

    analytics.subscribe("payment_info_submitted", (event) => {
    const checkoutData = ga4CheckoutEvents(event);
    sendGAEvent("add_payment_info", checkoutData);
    });

    analytics.subscribe("checkout_completed", (event) => {
    const checkoutData = ga4CheckoutEvents(event);
    const { checkout } = event.data;

    checkoutData.transaction_id = checkout.order?.id || checkout.token;
    checkoutData.shipping = checkout.shippingLine?.price.amount || checkout.shipping_line?.price.amount || 0;
    checkoutData.tax = checkout.totalTax?.amount || 0;

    sendGAEvent("purchase", checkoutData);
    });

    function ga4CheckoutEvents(event) {
    const { checkout } = event.data;
    const lineItems = createLineItemsData(checkout.lineItems);

    return {
    currency: checkout.totalPrice.currencyCode,
    value: checkout.totalPrice.amount,
    items: lineItems,
    };
    }