App Development and Tracking Features: Best Practices

Today the matter of tracking and web analytics is not about IF the user is going to want to implement it, but how he is going to do it. Data is important for analysis and efficiency, and with AI it is becoming more and more important to get the correct data and have minimum or no discrepancy at all.

Custom Head and Body Tracking Code

You can go and make things easier for your user with pre-built inputs for tracking pixels or tag managers like Google Tag Manager, but the most efficient and sure way of making the best option for all kind of tools is leaving an area where the user can insert <head> and <body> scripts.

One thing about it: make sure that the tracking code is as high possible in the tag – be it <head> or <body>.

An example (by Checkout Champ):

Server-side

Being used more often these days, the practice of sending events through the server-side is more reliable, avoids having to implement several Javascript snippets on the page and the usage of third party cookies, saving loading time and the probability of causing conflicts.

That can be done by sending the events to an endpoint through Javascript – Google Tag Manager uses has a server-side container for that – or directly from the back-end sending the data to the tool (i.e. Conversion API from Meta).

When you do it straight from the back-end – no pun intended – you can use an API, webhooks, pixels or postbacks. For the most common tools you may want to build a user-friendly interface where the user can just insert the tool’s ID or API Key and then the system sends all the events and information without the user having to configure anything else.

Postbacks, Pixels, Webhooks and Data Layers

When dealing with data with several factors and ever changing structure, the best course of action is to give the user the greatest capacity of customizing the URLs, data layer and payload, together with many variables as possible.

Also, do not forget the rules, if you can let the user choose WHEN to fire those based on source, medium, minimum and maximum price, products and other variables.

First Click Parameters

One of the things that you need to be aware of is when you have a system that breaks the tracking – like when the user lands in one domain, but the purchase event happens in another, or when the purchase event happens at the server-side of your system – if you do not store the data from the First Click, you are not going to be able to send the purchase event as a conversion back to Google Ads for example.

You can check the most common traffic parameters and already build your application around them or even better: leave it to the user to define which parameters to track and pass those through your API.

User Data

Most of the tools forget to add this kind of information when sending data back to media platforms and other tools like Meta Ads , Tiktok Ads and Google Ads.

Usually the data can be stored in cookies, session storage, variables, tokens or be sent by data layers.

The best way: is to have an input field or fields, where the user can insert custom Javascript code wherever an important event happens.

The regular ones are these:

  • User ID
  • Email
  • First Name
  • Last Name
  • Phone
  • Country
  • State
  • City
  • Postal Code
  • Street Address

Product Feed

When you have an e-commerce platform like Shopify, the product feed is crucial for the the user, it is almost 100% sure to be used for ads inside media platforms like Google Merchant or Meta Catalog, amongst other tools and apps that can benefit from a well structured feed.

We are not going to enter into details about every platform here, you can better check their structure inside their own documentations, but here is a list of ones more frequently used:

  • Meta Catalog
  • Google Merchant
  • Microsoft Ads
  • Data Feed Watch (for transforming data feeds)
  • Amazon Marketplace
  • Criteo
  • Pinterest Catalog
  • Ebay
  • Twitter Shopping Manager

Common Tracking Pixels and Tools

  • Meta Ads
  • Tiktok Ads
  • Linkedin Ads
  • Twitter Ads
  • Snapchat Ads
  • Pinterest Ads
  • Google Ads
  • Google Merchant
  • Meta Catalog
  • Google Tag Manager
  • Segment
  • Clarity
  • Hotjar
  • AdBeacon
  • Mixpanel

Common Variables/Tokens

  • User ID
  • Transaction ID
  • Items/Products
    • Item ID
    • Item Name
    • Item Category
    • Item Brand
    • Affiliation
    • Discount Coupon
    • Index
    • Price
    • Quantity
    • Location ID
    • Item List
    • Item LIst Name
    • Item Variant
    • Tax
    • Gross Revenue
    • Profit Revenue
  • User Data
  • Discount Coupon ( for the order)
  • Currency
  • Order Total Value
  • Shipping Value
  • Shipping Type
  • Device
  • Traffic Parameters
    • Source (utm_source)
    • Medium (utm_medium)
    • Creative
    • Campaign Name (utm_campaign)
    • Campaign ID (utm_id)
    • Adset Name
    • Adset ID
    • Ad Name
    • Ad ID
    • Placement
    • Content
    • Keyword (utm_term)
    • Search Query
    • Click IDs
      • FBCLID (Meta Pixel)
      • GCLID (Google Ads)
      • WBRAID (Google Ads)
      • GBRAID (Google Ads)
      • TTCLID ( Tiktok)
      • TWCLID (Twitter)

Important Events

  1. Form Submit
  2. Sign Up
  3. Login
  4. Add To Cart
  5. Remove From Cart
  6. Refund
  7. Add Payment
  8. Begin Checkout
  9. Purchase
  10. Newsletter Signup
  11. Site Search

When to send those events?

Those events should be sent ideally from the server-side or through a callback from the Javascript, when the event is confirmed as a success, it SHOULD NOT BE SENT BY A SCRIPT ON THE PAGE EVERY TIME THE PAGE REFRESHES.

Also, if you are going to send an event just to mark the confirmation and let your user get the rest of the data from a cookie or session storage, be sure to have that data available there.

Data Layer Samples

Data layers are structured data that can be pushed via Javascript through the client-side – browser – in order to send data to Google Tag Manager and even GTAG tags.

Some of them have a standard structure, the “event” key is required, but other than that, everything else is optional, mind you that GA4 and other tools may require specifical keys for some reports.

Here you have samples of the most common events, some of them are from Google itself:

User Data

You can insert the user data inside the data layer as well, that way you can get that data within GTM as soon as it is available and not be forced to fish it out from cookies or local storage after the event has happened.

If you prefer, you can also just append the information to the other events data layers instead of creating its own.

dataLayer.push({
  event: "user_data",
  user_id: "1234567890",
  first_name: "John",
  last_name: "Doe",
  user_email: "john_doe@gmail.com",
  user_phone: "1234567890",
  user_city: "New York",
  user_state: "NY",
  user_zip: "10001",
  user_country: "US",
  user_address: "123 Main St",
  user_address2: "Apt 1"  
});

Sign Up

dataLayer.push({
  event: "sign_up"
  // as said before, instead of using the User Data data layer, you can insert the form data here as well, so GTM can fetch it. 
});

Lead

dataLayer.push({
  event: "lead",
  formId: "trial_form" // optional, but recommended if you have more than one form in the same page and want to differentiate them
  // as said before, instead of using the User Data data layer, you can insert the form data here as well, so GTM can fetch it. 
});

Error

This is useful to track those errors inside your tracking tools as well, that way you can better set alarms for them, if you do not have them inside your system or just want to double the safety.

dataLayer.push({
  event: "error",
  errorCode: "34hE322jdx",
  errorMessage: "Credit card payment failed: Invalid billing descriptor"
});

Ecommerce

View Item

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "view_item_list",
  ecommerce: {
    item_list_id: "related_products",
    item_list_name: "Related products",
    items: [
     {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    },
    {
      item_id: "SKU_12346",
      item_name: "Google Grey Women's Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 3.33,
      index: 1,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "gray",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 20.99,
      promotion_id: "P_12345",
      promotion_name: "Summer Sale",
      quantity: 1
    }]
  }
});

Select Item

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "select_item",
  ecommerce: {
    item_list_id: "related_products",
    item_list_name: "Related products",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Add To Wishlist

If your ecommerce has a wishlist, you can send this data layer every time a product is submitted.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "add_to_wishlist",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Add To Cart

When the user adds the product to an ecommerce cart.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Remove From Cart

When the user removes the product from an ecommerce cart.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "remove_from_cart",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Begin Checkout

One of the most important events for ad optimization, sent when the user enters the first step of the checkout process.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "begin_checkout",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    coupon: "SUMMER_FUN",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Add Shipping Info

This is to be fired when the user submits shipping information, if that concludes the purchase, just send the Purchase data layer instead.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "add_shipping_info",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    coupon: "SUMMER_FUN",
    shipping_tier: "Ground",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Add Payment Info

This is to be fired when the user submits payment information, if that concludes the purchase, just send the Purchase data layer instead.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "add_payment_info",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    coupon: "SUMMER_FUN",
    payment_type: "Credit Card",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Purchase

Try to set it to be pushed when a purchase is successful and not when the user gets to the Thank You page, otherwise you may incur into duplicated purchases being sent to your tracking tool when that page is refreshed.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "purchase",
  ecommerce: {
      transaction_id: "T_12345",
      value: 25.42,
      tax: 4.90,
      shipping: 5.99,
      currency: "USD",
      coupon: "SUMMER_SALE",
      items: [
       {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        affiliation: "Google Merchandise Store",
        coupon: "SUMMER_FUN",
        discount: 2.22,
        index: 0,
        item_brand: "Google",
        item_category: "Apparel",
        item_category2: "Adult",
        item_category3: "Shirts",
        item_category4: "Crew",
        item_category5: "Short sleeve",
        item_list_id: "related_products",
        item_list_name: "Related Products",
        item_variant: "green",
        location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
        price: 9.99,
        quantity: 1
      },
      {
        item_id: "SKU_12346",
        item_name: "Google Grey Women's Tee",
        affiliation: "Google Merchandise Store",
        coupon: "SUMMER_FUN",
        discount: 3.33,
        index: 1,
        item_brand: "Google",
        item_category: "Apparel",
        item_category2: "Adult",
        item_category3: "Shirts",
        item_category4: "Crew",
        item_category5: "Short sleeve",
        item_list_id: "related_products",
        item_list_name: "Related Products",
        item_variant: "gray",
        location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
        price: 20.99,
        promotion_id: "P_12345",
        promotion_name: "Summer Sale",
        quantity: 1
      }]
  }
});

Refund

This should be pushed when you make a refund, usually in the back end, so you can cancel the purchases inside tools like GA4, that also means you have to include the GTM snippet there as well.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "refund",
  ecommerce: {
    currency: "USD",
    transaction_id: "T_12345", // Transaction ID. Required for purchases and refunds.
    value: 12.21,
    coupon: "SUMMER_FUN",
    shipping: 3.33,
    tax: 1.11,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

View Promotion

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "view_promotion",
  ecommerce: {
    creative_name: "Summer Banner",
    creative_slot: "featured_app_1",
    promotion_id: "P_12345",
    promotion_name: "Summer Sale",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Select Promotion

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  event: "select_promotion",
  ecommerce: {
    creative_name: "Summer Banner",
    creative_slot: "featured_app_1",
    promotion_id: "P_12345",
    promotion_name: "Summer Sale",
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});

Leave a Comment