Inside This Post

  1. Intro: Optimize For What?about optimization events and previewing our solution

  2. Critical Choice For ROAS and Scalinghow optimization event impacts the FB algorithm & auction

  3. A Common Example......where "intermediate-events" are extremely valuable

  4. Execution Guide Part 1 - ATCfire AddToCart when checkout form is visible

  5. Execution Guide Part 2 - InitCheckoutfire "InitiateCheckout" when cc number is entered

  6. Added Benefits Of This Approach & Conclusionsummary & further training to enhance your digital data

Optimize Adset For _____ ... What To Choose?

How do you choose your optimization-event for your Facebook Ads?

If you run Facebook Ads at all in 2018, odds are that you’re familiar with the “Conversion” campaign-type.

But there’s one issue here… especially if you’re trying to test a new offer or if you don’t have a lot of budget to work with:

We need to choose our “Optimization Event” wisely… choose an event too “buried” in the funnel, and you might not get enough conversions to maximize the “boost” from the Facebook Algo.  If you choose an event too high in the funnel, you risk attracting people who are “serial clickers” & your delivery might skew away from the REAL converters you’re looking for. We’ll revisit this topic in more detail in the next section.

In this post, you’ll learn how to give yourself more flexibility with your Conversion campaigns by adding the “AddToCart” and “InitiateCheckout” Facebook events to your funnel.

Now, you might be thinking: “That’s basic stuff — Shopify automatically fires these events for me!”

That is true!

However, many advertisers don’t use an ecommerce platform, and even those that do will often send paid traffic to standalone funnels that lack a “cart” feature and/or a built-in Facebook pixel integration that automatically fires events.

Thus, we will demonstrate how to plan, implement and utilize these “mid-funnel” events for situations where you have a standalone checkout page (or even an embedded checkout form in the actual sales page).

Why These Events Are Critical For Scaling & Increasing ROAS

Remember that Facebook’s machine-learning algos need conversion-volume in order to better optimize the delivery / auction-performance of your ads (Facebook states at least 50 through the course of one week, per adset).

Now, the problem there is, if you optimize for an event that’s waaaay down in the funnel, you might not be able to accrue enough conversions for the “algo” to accurately predict which Facebook users are “high probability” to convert against your offer.

Here you have a decision-point: do you optimize for an event that’s sure to get plenty of conversions (landing page views, ViewContent, etc.), but not representative of your ultimate goal (which is often purchases / conversion-value)?

Or do you go ahead and optimize for the “real conversion”, even though you’re doubtful that you’ll get more than 1 – 3 conversions per day?

A Realistic (And Common) Example

Assume you have a new offer you want to test, but you’re not sure how it will perform. You have most of your budget tied-up in other campaigns, so you can’t afford to “go big” on your spend.

Your funnel has the following flow:

  1. The first page the user will hit (upon clicking the CTA in the Facebook Ad) is an advertorial-style lander, and the CTA is an offer for a low-price product. Let’s assume it’s an ebook called “How To Make Millions In ClickBait” (HTMMIC for short) that we’re selling for $9… with a limited-time special bonus, of course.
  2. If the user clicks the CTA to purchase the HTMMIC ebook on this page, they’re auto-scrolled down the page to an embedded check-out form.
  3. If the user purchases the offer, they’re taken to a Thank You page and we fire the Facebook purchase event.

Now, if you can only spend $20 per day to test this offer .. and we know that we need to get around 7 – 8 conversions per day for Facebook’s algos to work with maximum efficiency, what are the odds that this will happen?

You’ll need to drive purchases with a CPA of $2.80 in order to hit the magic “50 per week” mark without increasing your budget.

That’s possible … but is it likely? Of course, it depends on your ad.

For reference, we recently launched a new adset targeting a “cold” interest-based audience that’s currently generating a link-CTR of 13.37% and landing-page views for only $0.09 each. That means we need a conversion-rate (landing-page view → purchase) of 3.21% to hit our mark. That seems doable.

However, that adset / ad is an outlier… most of our ads tend to hover around the 5 – 7% range (for link CTR). So let’s not assume this new offer will be extraordinary.

For our example, let’s assume that we expect our link CTR will be 5% and we typically pay around $20 CPM to reach this specific “cold audience”.

For every $20 spent, we’ll deliver 1000 impressions and generate 50 clicks. $20 divided by 50 clicks means that we’ll pay $0.40 per link-click, and thus, we need a conversion rate (link click → purchaser) of 14.28% to hit our goal of 50 conversions per week.

We think this over, consider our historical average conversion rate of FB Ad click → purchase, and conclude that it would be a stretch to assume that we will even get 25 purchases per week (given our $20 per day budget).

This is the exact situation where these “intermediate-events” come in handy.

We decide that we want to setup an AddToCart event that fires when the checkout-form is visible on the page, and an InitiateCheckout event that fires when the user enters a legitimate credit-card number in the checkout form.

Not only will this give us more flexibility when choosing our optimization-event in Facebook, it will also give us better analytics around the design & effectiveness of our advertorial (we can answer questions like: “are people even GETTING to the checkout form, or are they just reading the first few sections, then leaving?”)

Let’s look at how to do that with Google Tag Manager.

The Execution Guide Part 1 - Fire AddToCart When The Checkout Form Is "Visible"

Our goal is to fire our “AddToCart” event when the checkout form is visible on the page.  Thus, the first thing we need to build is the “Trigger” for this event… and it sounds complicated at first glance (“how do we know if an element is ‘visible’ to the end-user or not?”).

Lucky for us, Google Tag Manager has a built-in trigger type for “Element Visibility”.

To create our trigger, we first need to tell GTM which element we’re interested in.

There’s two options in our trigger-settings available. The first, and easiest-to-implement, is to use the ID option. When we say “ID” here, we’re talking about the HTML attribute, ex: <form id=“cform-3” …>.

However, not all html elements have an ID attribute … In order to know for sure, we navigate to our advertorial page, scroll-down to the checkout-form, right-click somewhere inside it, and then choose “Inspect Element” (assuming you’re using Chrome. Other browsers have similar features but, holistically, “Chrome Dev Tools” is my personal favorite).

When Chrome Dev Tools opens, you will see something like this:

We’re looking for the <form> element, which should be nearby / should be the “parent” of the actual element we right-clicked (note that in some cases you won’t see a form element, but see the walkthrough video for more details on edge-cases, etc).

Upon locating the form element, we see that there’s no ID attribute… in many cases, if you have access to edit the actual page-code, it might be easiest to add an ID to the form and then come back to finish up your trigger settings.

However, assume we don’t have the ability to edit the page-code (or the time to coordinate with our developer to make edits) so on to option #2: “CSS Selector”.

Understanding CSS selectors is a whole topic in itself, but essentially what you are trying to do here is specify a set of “matching rules” that are true for your <form>, but not for other elements on the page.

Here’s GMT’s docs on using CSS selectors (concise, but not very thorough), and then here’s a more in-depth guide (css cheat sheet) from

For our example, we’re going to rely on a unique “class” that’s set on our form element (“formMinimal”). To identify an element by class using CSS Selectors, you precede the class-name with a dot (.).

For the option “When to fire this trigger”, we will choose “Once per page”, as we don’t want to fire this event multiple times as the user scrolls around the page.

Under the “Advanced” section, I’ll set “Minimum Percent Visible” to 50, but this option is completely up to you.

Finally, for the “This trigger fires on” setting, I will set it to “Some Visibility Events” and then set a condition based on the Page Path matching my page (thus avoiding this trigger firing on other pages that might have similar forms).

Here’s the final screenshot of my trigger, all I need to do now is name it (I always start my trigger names with the trigger-type to help keep them organized, so I’m naming mine “Visibility – HTMMIC Adv Checkout Form – Class Selector”) and save it!

Let’s go to Tags → New and name our new tag: “Facebook – AddToCart – HTMMIC Advertorial LP” (or whatever you prefer).

The tag type is “Custom HTML”, and we will drop code like this into the html-edit field:

    fbq("track", "AddToCart", {
        content_name: "HTMMIC-ebook",
        content_category: "HTMMIC-advertorialFunnel"

For the Trigger conditions, grab the visibility trigger we previously created, and voila, our event is ready for testing.

Be sure to go into Preview Mode, visit your page locally and watch the GTM Debug Window as you scroll the element into view — you should see a new event populate in the left-hand event-timeline, and you should see that your tag fired based on that event.

You can also be 100% sure that your tag is sending the right data to Facebook by using Chrome Dev Tools → Network → filter for ‘facebook’

The Execution Guide Part 2 - Fire InitiateCheckout When The User Enters A Valid Credit Card Number

Now that we have our AddToCart event set to fire when the checkout form is visible to the visitor, the next step is to fire an event that signifies that the visitor has started our form / has demonstrated intent to purchase the product.

We will use the “InitiateCheckout” Facebook event, and as-in part 1 of this execution guide, we’re going to start by building out our trigger.

For my use-case, I’m choosing to fire the InitiateCheckout event when the user “blurs” the credit-card field AND they have entered a 15 or 16 characters into the field.

You can learn more about the “blur” event here, but in short, after a form-field is “activated” (that is, the user can now type into the field), when they “disactivate” the field (using TAB or by clicking elsewhere on the page), it’s called a “blur”.

Google Tag Manager doesn’t have a built-in “Blur” trigger-type that we can utilize, so we’re going to need to create our own trigger.

We will actually construct this trigger by starting with, what I call, a “Utility Tag”.  This will be a standalone “Custom HTML” tag that runs the javascript needed to “listen-for” the proper blur events, and if a successful blur-event occurs (when 15 or 16 characters are entered into the credit-card field), we will push a new event into the dataLayer, so that our Facebook event tag can use that as a trigger.

Whew… ok, that sounds complicated, even to me … but it will make more sense as we set it up.

SO… let’s start by creating this Utility Tag.  Click Tags → New → Tag Type: Custom HTML. I’m naming my tag “Utility – Checkout CCField Blur”.  I’m actually making this tag-name a bit ambiguous, because if I use the same forms across my site, I can use the same tag to listen-for the “credit card blurs” on other checkout pages.

Here is the code that we need to drop into the tag’s HTML editor.  Test this code before pushing to production and remember to edit the selector in line #3.

   var gtmBlurField = document.getElementById("mm_field_cc_number");
      gtmBlurField.onblur = function(){
       if(gtmBlurField.value.length >= 15){
          window.dataLayer = window.dataLayer || [];
                'event': 'blur_initChkout'
        } else {
          console.log('blur field found, length of val less than 15');
     } else {
        console.log('blur field not found');
  } catch(e) {
    console.log('blur utility caused error: ' + e);

Important here is: the dataLayer push sends an “event” (a special type of dataLayer “key” that GTM can use as Triggers) called “blur_initChkout”. We will need that in a moment.

Reminder: you will need to alter line 3 in the code above (var gtmBlurField = …) to get the credit-card field based on your checkout form’s attributes.

To complete this tag setup, I’m going to set its trigger as a Pageview trigger based-on the url of my advertorial page. Note that I could set this to fire on all pages if I wanted to use it universally / more dynamically.  Save the tag, then we can begin our testing.


Testing Our “Blur Utility Tag”

In GTM, I turn on the “Preview” mode of my GTM container, and navigate to our advertorial page. I open Chrome Dev Tools, and go to the “Console” tab. While I’m performing the actual test, I will reference both the GTM Preview-Pane & the Console, watching for the console “log” statements I included in our Utility tag code.

If I “activate” the credit-card field, then tab over to a different form-field (without entering a CC#), in the console we should see “blur field found, length of val less than 15”.

Now I re-activate the credit-card field and put in 15 or 16 digits, and tab-out again.

we should see the blur_initChkout event pop-up in the left-hand side of our GTM Preview Pane:

And the most recent console log should now say “ccfield-blurred”. Looks good!

Next, we will create our tag for our Facebook InitiateCheckout event.

Go to Tags → New → Tag Type: Custom HTML, and I’m naming my tag “Facebook – InitiateCheckout – AdvertorialLP2018”.

In the tag’s html editor, I’m using code like this:

fbq('track', 'InitiateCheckout', {
content_name: "HTMMIC-ebook",
content_category: "HTMMIC-advertorialFunnel"

To finish up our tag, we will go to “Advanced Settings” and set this event to fire “Once Per Page”. We should also, for the sake of sanity, use our typical tag sequencing to insure the Base Pixel has fired before this tag.

Does Your Facebook Reporting Data Ever Seem Off?

A few things you should know about the Facebook Pixel:

  1. the #1 major cause of inaccurate ad-performance data is duplicate-fires of the same custom-conversion (or event) for the same user.  For example, if you fire a “Purchase” event on a thank-you page, any given user could reload that page many times and cause your performance data to be artificially-inflated (which leads to poor decision-making, scaling into losers, etc.)
  2. In GTM, tag-sequencing doesn’t work “out-of-the-box” for Custom HTML tags (e.g: all of our Facebook tags).  There is a workaround.

If you want to solve both of those problems, and/or if you find this post helpful, I urge you to checkout “Facebook Pixel Implementation Blueprint v2”.   This is a brand-new course (July 2018) that is built by performance-marketers, and has paths for novices and more advanced GTM users.

While the course is focused on implementing accurate Facebook tagging, it also contains over 20 videos / .PDFs designed to make you highly-proficient with tagging & GTM in-general.

Get Yours

For the trigger, I will create a New Trigger, and choose Trigger Type: “Custom Event”, which is towards the bottom of the options.

Here’s a picture of my trigger configuration, where the most important things are:

  1. The event name should be set to blur_initChkout (or whatever you’re using as the value for the event key in your Utility Tag’s dataLayer push).
  2. I set it to “Fire on some events” and set the trigger conditions based on the URL of the page where I want to fire this event.

Now we can save our tag, hop back into preview mode and navigate to our advertorial page for one last test.

This time I will open Chrome Dev Tools → Network → filter for facebook. I will also keep an eye on GTM Preview to see if my Facebook tag fires on the blur_initChkout event.

When I enter my CC number into the proper field and click or tab-out, I should see a new request (or two) in my Dev Tools network tab. Click one of them and scroll down to the “Query String Parameters” section at the bottom of the right-hand pane, and you should see your event name and the parameters you set.

Once you’re comfortable with your testing, you’re ready to publish these beastly new tags.

Wrapping Up & Next Steps

Remember that the addition of these extra events doesn’t just give your ad-managers flexibility for optimization: you can use these events in Facebook Analytics funnel reports to see where your intra-page drop-offs occur for this advertorial. Like killing two birds with … well… two tags, I suppose.

If you’re interested in learning more about using GTM to empower your Facebook advertising (along with other platforms like Google Analytics), our brand-new course (as of July 2018) is available: Learn more about “Facebook Pixel Implementation Blueprint v2.0” here

If for nothing else, I suggest grabbing the “FPIBv2” course to get the pre-built GTM container import file, which includes all of the components of our properietary “CACHEMONEY” tagging approach. We designed this solution to resolve the biggest issue with the Facebook pixel’s accuracy: erroneous duplicate fires of key events from the same visitor (due to page reloads, revisits, etc.). We’ve seen that this system improves tracking accuracy for “mission-critical” events by 20%+ for nearly all advertisers we’ve worked with.

I hope this post has been directly-actionable, or has at least provided some inspiration.

Now, if you’ll excuse me, I need to get back to writing my new ebook “How To Make Billions In Clickbait”.