Posts by Alex Czartoryski

Flaneur...

Your YouTube Campaigns are not performing as well as you think!

YouTube Campaigns count conversions differently than all other campaign types in AdWords. This can cause you to significantly overspend!

I recently ran a conversion focused YouTube video campaign that performed extremely well: According to AdWords I spent $10,000 and generated $100,000 in revenue.

However, looking at our analytics data showed a much different picture: That same $10,000 spend only generated $3,000 in sales.

Why the huge discrepancy? Something wasn’t right…

 

View Through vs Click Through

First a quick explanation of the difference between View-through Conversions and Click-through Conversions:

View Through Conversions (VTC) occur when someone sees your ad but does not click on it, and later buys your product. These types of conversions generally are only counted in the “View-through Conversions” column in AdWords.

Click Through Conversions (CTC) occur when someone sees your ad, Clicks the ad, and then later buys your product. These types of conversions are counted in the “Conversions” column in AdWords (and are generally the only conversions tracked by Google Analytics).

 

YouTube Campaigns count Conversions differently from other Campaign types

 

Standard Campaigns

For all campaign types except YouTube, a conversion is only counted in the “Conversions” column if someone clicked on your ad and then purchased your product. If a user sees your ad but does not click, but purchases anyway, that conversion is only counted in the “View Through Conversion” column.

This is the normal expected behaviour.

AdWords Search and Display conversion attribution

YouTube Video Campaigns

For YouTube campaigns, things behave differently. Click-throughs behave as expected, but View-Through conversions are handled very differently, and are divided into two categories:

Impression View-Through: A user briefly sees your video ad, does NOT click, but then buys your product. This conversion is counted in the “View-Through Conversion” column. (This is normal expected behaviour)

Video 30s View-Through: A user watches your video ad for at least 30 seconds, does NOT clickbut buys your product. This conversion is counted in the “Conversions” column, just like a Click-Through conversion. THIS IS NOT EXPECTED BEHAVIOUR!

YouTube conversion attribution

From Google:

View-through conversions for video ads
An impression is different than a “view” of a video ad. A “view” is counted when someone watches 30 seconds (or the whole ad if it’s shorter than 30 seconds) or clicks on a part of the ad. A “view” that leads to a conversion is counted in the “Conversions” column.

Source: https://support.google.com/adwords/answer/6270625

 

Misleading Data

A “Video View” is more like an Impressions than a Click

A 30 second video view is much more like an impression that it is like a click, so why are these conversions being lumped in with click-through conversions? They should clearly be lumped into the View-Through Conversion column, or if YouTube wants to explicitly report on this metric then create another column type. Don’t lump it in with click-through conversions.

Unexpected Behaviour

The problem with all this is that suddenly the “Conversions” column behaves differently in one campaign type vs another. Suddenly the clean click-through conversion data is being polluted and mixed in with View-Through conversion data. This will make the campaign appear to perform better than it should. Which will lead you to incorrectly increase spend.

In our specific case, this issue led to AdWords over reporting campaign revenues by 3000%

 

Notes:

  • This is only an issue if you use Google AdWords Conversion tracking. If you import your conversions directly from Google Analytics, then this should not be an issue.
  • If you are running  a pure brand awareness campaign, this is probably less of a concern for you.

 

Shopify Dynamic Remarketing Setup

Here is how to properly install Dynamic Remarketing Tags on your Shopify store, which will let you run dynamic product ads on the Google Display network.

The code needs to be installed in two places:

  1. At the bottom of your theme.liquid
  2. In the “Additional Scripts” field in your Store’s Admin > Settings > Checkout section

Add the Code to Theme.liquid

Step 1: Create a Remarketing Snippet

In your store’s admin section go to:

  • Online Store > Themes > Edit HTML/CSS
  • Expand the Snippets section and click “Add new snippet”
  • Call the snippet “adwords-remarketing”
  • Paste the following code into the snippet
  • Update the google_conversion_id to use your specific conversion Id (you will find it in your Google AdWords account)
{% comment %} Enter your google conversion id below {% endcomment %}
{% assign google_conversion_id = 0 %}
{% assign shopify_store_country = 'US' %}
{% if shop.currency == 'CAD' %}
{% assign shopify_store_country = 'CA' %}
{% endif %}

<script type="text/javascript">

 {% if template contains 'cart' %}
 var google_tag_params = {
 ecomm_prodid: [{% for item in cart.items %}'shopify_{{ shopify_store_country }}_{{ item.product.id }}_{{ item.variant.id }}'{% unless forloop.last %}, {% endunless %}{% endfor %}],
 ecomm_pagetype: 'cart',
 ecomm_totalvalue: {{ cart.total_price | money_without_currency | remove: ',' }}
 };

 {% elsif template contains 'collection' %}
 var google_tag_params = {
 ecomm_prodid: [{% for item in collection.products limit:5 %}'shopify_{{ shopify_store_country }}_{{ item.id }}_{{ item.variants.first.id }}'{% unless forloop.last %}, {% endunless %}{% endfor %}],
 ecomm_pagetype: 'category',
 ecomm_category: '{{ collection.handle }}'
 };

 {% elsif template contains 'index' %}
 var google_tag_params = {
 ecomm_pagetype: 'home'
 };

 {% elsif template contains 'product' %}
 var google_tag_params = {
 ecomm_prodid: 'shopify_{{ shopify_store_country }}_{{ product.id }}_{{ product.selected_or_first_available_variant.id }}',
 ecomm_pagetype: 'product',
 ecomm_totalvalue: {{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }}
 };

 {% elsif template contains 'search' %}
 var google_tag_params = {
 ecomm_prodid: [{% for item in search.results limit:5 %}'shopify_{{ shopify_store_country }}_{{ item.id }}_{{ item.variants.first.id }}'{% unless forloop.last %}, {% endunless %}{% endfor %}],
 ecomm_pagetype: 'searchresults'
 };
 {% else %}
 var google_tag_params = {
 ecomm_pagetype: 'other'
 };

 {% endif %}

 /* <![CDATA[ */
 var google_conversion_id = {{ google_conversion_id }};
 var google_custom_params = window.google_tag_params;
 var google_remarketing_only = true;
 /* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="//googleads.g.doubleclick.net/pagead/viewthroughconversion/{{ google_conversion_id }}/?value=0&amp;guid=ON&amp;script=0"/></div>
</noscript>

This code is also available on GitHub: Shopify Remarketing Code Snippet

Step 2: Install the snippet in your Theme file

Open up the theme.liquid file and add the following line of code before the closing </body> tag:

<!-- Dynamic Remarketing -->
{% include 'adwords-remarketing' %}

Add the Code to Checkout Scripts

In your Shopify Store’s Admin, go to:

  • Settings > Checkout
  • Scroll down to the “Additional Scripts” field.
  • Copy and paste the code below into the “Additional Scripts” field
  • Make sure you update the code with your own custom google_conversion_id.
<!-- Google Dynamic Remarketing -->
{% comment %} Enter your account specific value below {% endcomment %}
{% assign google_conversion_id = 0 %}
{% assign shopify_store_country = 'US' %}
{% if shop.currency == 'CAD' %}
{% assign shopify_store_country = 'CA' %}
{% endif %}
<script type="text/javascript">
var google_tag_params = {
 ecomm_prodid: [{% for item in order.line_items %}'shopify_{{ shopify_store_country }}_{{ item.product.id }}_{{ item.variant.id }}'{% unless forloop.last %}, {% endunless %}{% endfor %}],
 ecomm_pagetype: 'purchase',
 ecomm_totalvalue: {{ total_price | money_without_currency | remove: ',' }}
};
</script>
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = {{ google_conversion_id }};
var google_custom_params = window.google_tag_params;
var google_remarketing_only = true;
/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="//googleads.g.doubleclick.net/pagead/viewthroughconversion/{{ google_conversion_id }}/?guid=ON&amp;script=0"/></div>
</noscript>

Download the code from Github here: Shopify Checkout Remarketing Code

Final Step: Verification

Once you’ve installed all your code, it’s time to run through your site and main pages (collection, product, cart, and purchase pages) with Google Tag Assistant installed. This will help you troubleshoot any errors.

Common errors include:

  • Products not properly uploaded to Google Merchant Center
  • Google Conversion Id not properly set

AdWords Display Remarketing Setup Best Practice for e-Commerce

The key to setup a performing ROI based display remarketing campaign is to properly segment your audiences and ad groups.

Basic Theory

  1. The deeper a user is in your sales funnel, the more likely he is to buy. A shopping cart abandoner is more likely to buy than someone who simply browsed your homepage.
  2. The more recent the user’s visit, the more likely he is to buy. A user who abandoned his shopping cart yesterday is more likely to buy than someone who abandoned their cart 10 days ago.
  3. The more likely a user is to buy, the more you want to bid on that user.
  4. The 80 / 20 rule applies. Roughly 80% of your remarketing sales will come from your cart abandoners. 16% will come from your product viewers. And the remaining 4% will come from general site browsers.

Audiences

Here are the initial audiences to create. If you have a high volume site you may want to add additional audiences with more granular time periods.  Remember that the more granular you make something, the more traffic you need to make the stats significant.

  • Cart Abandoners – 1 day
  • Cart Abandoners – 4 day
  • Product Viewers – 7 day
  • Product Viewers – 28 day

Properly Defining your Audiences

It is important that your audiences do not overlap. (It is ok if the time scales overlap, but not cart abandoners and product viewers). There are 2 ways to set this up.

  1. When you define your audience, make sure you exclude necessary audiences. Exclude purchasers from Cart Abandoners; exclude cart abandoners and purchasers from product viewers.
  2. Create base audiences like “Purchased”, “Added to Cart” and “Viewed Product” and then EXCLUDE the audiences at the ad group level. “Added to Cart” minus “Purchase == Cart Abandoner; Viewed product minus Cart Abandoner == Product Viewers.

Campaign Setup

Create one campaign per major market you are targeting, and give them a descriptive name:

  • USA: Display Remarketing
  • Canada: Display Remarketing

Generally, but not always, you will want a separate campaign for every unique currency and language you are targeting.

Core AdGroups

Creating only these two ad groups will generate 90% of your display remarketing conversions . I highly recommend you start with only these two. Only add more groups (described later) if the extra 10% in remarketing sales will justify the extra administrative complexity.

1. Cart Abandoners

This ad group will target cart abandoners: Visitors who added a product to their cart but never purchased. Dynamic Product ads perform particularly well with cart abandonment, as your visitors are shown the exact products that they added to their cart.

Audiences:

  • Cart Abandoners – 1 day
  • Cart Abandoners – 4 day

2. Product Viewers

This ad group will target users who visited a product details page but who never added a product to their cart.

Audiences:

  • Product Viewers – 7 day
  • Product Viewers – 28 day

Optional Ad Groups

Here are additional remarketing ad groups and audiences. In my experience, most conversions come from the two core ad groups identified above (Cart Abandoners and Product Viewers) but you may have a different experience depending on your business.

Just Purchased

This will show ads to people who have just purchased. This is a good place to possibly push micro conversions such as joining a loyalty program, joining a community, etc… Or perhaps up-selling them another related product?

Audience

  • Purchase 7 days

Past Customers

This is similar to the “Just Purchased” ad group, but with a longer time window. This will show ads to people that have previously purchased a product 30 or more days ago. This is a good place to advertise new product launches or promotions.

Audience

  • Purchase 30 days
  • Purchase 90 days
  • Purchase 360 days

Never Purchased

This is the opposite of the “Past Customers” group. These are people who visited your site in the past year, but have never purchased. This is also a good place to advertise new product launches or promotions.

Audience

  • Site Visitors 30 days
  • Site Visitors 90 days
  • Site Visitors 360 days

Exclude Audience

  • Purchase 360 days

New Customers, Brand Unaware

This isn’t really remarketing, but simple display advertising: These are people who have never visited your site. Your remarketing audiences are EXCLUDED so that you are only targeting people who are unaware of your product or brand. You are arguably willing to pay more for each customer as they are new customers, but this will be your worst performing segment. You can waste a lot of money here, so be careful.

Audience

  • Combination of keyword, interest, topic, and placement targeting relevant to your product and brand.

Exclude Audience:

  • Site Visitors 360 days

 

Other Tips

Exclude “low quality” visitors

You will have to create these audience groups within Google Analytics, and then exclude them from all your remarketing campaigns:

  • Exclude people who have bounced
  • Exclude people who have spent less than ten seconds on the site

Frequency Capping

Most resources online will tell you to limit your frequency cap to about 20 times per user per month, but I suspect this is wrong. That means a user will be exposed to your ad once every other day or so, with no guarantee that he actually noticed it.

I normally set the frequency capping to 20 times per user PER DAY. If you think of how many web pages you visit in a day, 20 ads will be gone fairly quickly and you will probably miss most of them. Add in that for cart abandonment ads you really want to hit the abandoners hard within the first 24 hours, I think the 20 impressions per day is the safer bet.

But the true answer will vary based on your business, product, and customers.

A word about View Through Conversions

View Through Conversions are conversions where a display ad appeared on the screen, was NOT clicked, but the user ended up purchasing on your site sometime later. In general I recommend that everyone IGNORE View Through Conversions, in particular in remarketing campaigns.

What usually happens, is that an ad is displayed on screen, the visitor may not even see it, but clicks instead on a cart-abandonment e-mail and makes the purchase. AdWords will credit that conversion to the view through.

The one exception is for “brand unaware” customers. These are customers that have never visited your website before. If such a customer sees you ad, and purchases, then the odds are better that it was a result of your ad.

In an ideal world, there would be a simple way to test the value of your view-through-conversions, as they are different for every segment, and every business.

Other Resources

AdWords: Why aggregate data can be misleading

When making decisions based on your Google AdWords account performance, don’t just look at overall account performance. It is very important to get more granular in your analysis.

Consider this scenario

You are willing to spend up to 20% of your product’s price to make a sale. (Maximum % Cost of Sales = 20%). You’ve spent $10,000 in a given period and generated $100,000 in sales. Great! Your advertising’s cost is 10% of sales, well below your 20% maximum. Your account is performing great!

SPEND SALES % COST OF SALES (COS) PERFORMANCE
ACCOUNT $10,000 $100,000 10% Great!

Based on this you decide to increase your spend by an additional $10,000, with the hope that doubling your spend will double your sales. Unfortunately, this doesn’t happen, and you only generate another $25,000 in sales.

SPEND SALES % COS PERFORMANCE
ACCOUNT $20,000 $125,000 16% Good. But not Great.

Why doesn’t it scale?

The problem is that your account performance is not even. Every dollar spent is not generating the same revenue. If we take another look at the initial account, this time with the underlying campaigns visible, it might look something like this:

SPEND SALES % COS PERFORMANCE
BRANDED CAMPAIGN $2,000 $80,000 2.5% Great!
UNBRANDED CAMPAIGN $8,000 $20,000 40% Underperforming
ACCOUNT TOTAL

$10,000

$100,000 10%

The performance of the Branded Campaign is subsidizing and hiding the not-so-good performance of the Unbranded Campaign. Your spend and sales are following a typical 80/20 split: 80% of your sales are coming from only 20% of the spend, and the remaining 80% of your spend is underperforming.

Now that you have this additional information, your budget conclusions are much different:

  1. Decrease spend on your Unbranded campaign (and optimize or segment further)
  2. Increase spend on your Branded campaign.

However, your branded search spend is usually a function of search demand for your brand. Once you are capturing 100% of your search demand, you can’t really scale up any higher. If you want to increase your spend, the only place where you might be able to put the extra spend is the already underperforming unbranded campaign, which will lead to something like this:

SPEND SALES % COS PERFORMANCE
BRANDED CAMPAIGN $2,000 $80,000 2.5% Great!
UNBRANDED CAMPAIGN $18,000 $45,000 40% Underperforming
ACCOUNT TOTAL

$20,000

$125,000 16%

  Summary

  • Avoid making account wide budget decisions on aggregate data. Always try to dig a little deeper.
  • Don’t let underperforming segments ride the coat tails of your top performers. Look for 80/20 campaign and ad group performance and analyze those individually.
  • If you have a single campaign with a single ad group, your Branded and Unbranded searches are likely lumped together. Split them apart into separate ad groups.

Adding Schema.org Microdata to your Shopify Product Pages to enable Google Merchant Center automatic updates (with product variant support)

If you are using Google Merchant Center to drive either your Google Product Listing Ads (PLAs) or for your Dynamic Remarketing Ads, you have likely ran into an issue where Merchant Center will sometimes give you a warning that there is insufficient match of micro-data information and that it is no longer performing automatic item updates.

merchant-center-warning

This is generally due to incorrect or incomplete micro-data on your product page, in particular if you have submitted deep-linking product variant data to your merchant center.

The Fix: Add Variant Level Micro-data

To fix this issue, you need to know some basic HTML and be able to navigate your product.liquid file.

Firstly, I recommend you read this great write-up by Gavin Ballard on adding micro-data to your Shopify store: http://gavinballard.com/microdata-on-shopify-and-other-ecommerce-platforms/

There is overlap with what is discussed below, but the article provides some good background and other benefits of using micro-data.

Product.liquid

All the required edits should be limited to your Product.liquid file. In a nutshell: You need to define a Product itemscope which will have properties such as Product Url, Product Image, Product Title, and Product Description.

Nested within the Product will be an Offer itemscope that will contain the product variant’s price, currency, condition, and availability.

Schema.org Product ItemScope

Open your product.liquid file and add the Product itemscope property to the outer most div. The first line of your product.liquid should look something like this:

<div itemscope itemtype="http://schema.org/Product">

 

Directly below this line, you should add the product variant’s url and image markup as so:

<meta itemprop="url" content="{{ shop.url }}{{ product.selected_or_first_available_variant.url }}" />
<meta itemprop="image" content="https:{{ product.selected_or_first_available_variant.image.src | product_img_url: 'grande' }}" />

 

Find where your product’s title and description are displayed, and add itemprop=name and itemprop=description attributes as shown below:

<!-- Product Title -->
<h1 itemprop="name">{{ product.title }}</h1>
<!-- Product description -->
<div class="product-description" itemprop="description">
{{ product.description }}</div>

 

Schema.org Offer ItemScope

Now you need to find the place in your product.liquid file where you display your price, find a wrapping div tag and add the Offers itemscope attributes to the tag. The Offers itemscope MUST nested within the Product itemscope div tag.

<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">

 

Immediately after this line you can add the product variant’s price, currency, condition, and availability microdata as so:

<meta itemprop="priceCurrency" content="{{ shop.currency }}" />
<meta itemprop="price" content="{{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }}" />
<meta itemprop="itemCondition" itemtype="http://schema.org/OfferItemCondition" content="http://schema.org/NewCondition"/>
{% if product.selected_or_first_available_variant.available %}
	<link itemprop="availability" href="http://schema.org/InStock" />
{% else %}
	<link itemprop="availability" href="http://schema.org/OutOfStock" />
{% endif %}

 

Putting it all together

Once done, your product.liquid should have roughly the following structure.

<!-- BEGIN Product itemscope -->
<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="url" content="{{ shop.url }}{{ product.selected_or_first_available_variant.url }}" />
  <meta itemprop="image" content="https:{{ product.selected_or_first_available_variant.image.src | product_img_url: 'grande' }}" />

  <!-- Product Title & Description -->
<h1 itemprop="name">{{ product.title }}</h1>
<div class="product-description" itemprop="description">
  {{ product.description }}</div>
<!-- BEGIN Offer itemscope -->
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
    <meta itemprop="priceCurrency" content="{{ shop.currency }}" />
    <meta itemprop="price" content="{{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }}" />
    <meta itemprop="itemCondition" itemtype="http://schema.org/OfferItemCondition" content="http://schema.org/NewCondition"/>
    {% if product.selected_or_first_available_variant.available %}
    			<link itemprop="availability" href="http://schema.org/InStock" />
    {% else %}
    			<link itemprop="availability" href="http://schema.org/OutOfStock" />
    {% endif %}</div>
</div>

 

Final Steps

  1. Save and test your new product page in Google’s Structured Data Testing Tool, and fix all errors if any.
  2. Wait and check back periodically in Google Merchant center to ensure no new errors were introduced. It will take a few weeks before the “unable to update” warning disappears.

Related Reading

Shopify Facebook Dynamic Product Ads: Build your own Retargeting feed

If you want to setup Facebook Dynamic Product Retargeting ads for your Shopify store, you need to upload your store’s product catalog feed to Facebook. Below is a walk through of how to generate your Facebook product feed.

This is an advanced topic and I assume you have a basic understanding of HTML/Liquid, the Shopify Store Admin and Facebook Business Manager.

  • UPDATE September 14, 2017: Removed redundant top level products that would cause duplicate products in cases where only a single variant was present.
  • UPDATE September 13, 2017: Fixed issue where some variant images were showing up blank.

Step 1
Install Shopify’s Google Shopping App

Install Shopify’s free Google Shopping app to configure various properties on your products such as Age Group, Gender, and Product Category.

Step 2
Create a Collection Template for your Feed

Create a new custom collection template that will output your collection as XML instead of HTML.

In your Shopify admin, go to:

  • Online Store > Themes > Action > Edit Code
  • Under Templates, choose Add a new Template
  • Choose collection from the drop down and name your template fb-product-feed

Paste the following code into your new template and click Save. (The most recent version of the code is always available on Github here: Shopify Facebook Product Feed Template)

{% layout none %}<?xml version="1.0"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
{% paginate collection.products by 1000 %}
{% assign CountryCode = 'US' %}
{% if shop.currency == 'CAD' %}{% assign CountryCode = 'CA' %}{% endif %}
{% assign Color = "" %}
{% assign Size = "" %}
<channel>
<title>{{ shop.name }} {{ collection.title | replace: '&', '&amp;' }}</title>
		<link>{{ shop.url }}</link>
<description>{{ collection.description | strip_html }}</description>
{% for product in collection.products %}
  {% assign GoogleProductCategory = product.metafields.google.google_product_type %}
  {% assign Gender = product.metafields.google.gender %}
  {% assign AgeGroup = product.metafields.google.age_group %}

  {% if product.variants.size > 0 %}
  {% for variant in product.variants %}
    {% for option in product.options %}
  	  {% if option == 'Color' %}{% capture Color %}{{ variant.options[forloop.index0] }}{% endcapture %}
  	  {% elsif option == 'Size' %}{% capture Size %}{{ variant.options[forloop.index0] }}{% endcapture %}
  	  {% endif %}
    {% endfor %}
<item>
<title>{{ product.title | strip_html | strip_newlines | replace: '&', '&amp;' }}  {{ Color | replace: '&', '&amp;' }}</title>
		<link>{{ shop.url }}{{ variant.url }}</link>
<description>{{ product.title | strip_html | strip_newlines | replace: '&', '&amp;' }} {{ variant.title | strip_html | strip_newlines | replace: '&', '&amp;' }} {{ product.description | replace: '</', ' </' | strip_html | strip_newlines | replace: '&', '&amp;' }}</description>
<g:google_product_category>{{ GoogleProductCategory | replace: '&', '&amp;'  }}</g:google_product_category>
<g:item_group_id>{{ product.id }}</g:item_group_id>
<g:id>{{ variant.id }}</g:id>
<g:condition>new</g:condition>
<g:price>{{ variant.price | money_without_currency }} {{ shop.currency }}</g:price>
<g:availability>{% if variant.available %}in stock{% else %}out of stock{% endif %}</g:availability>
<g:image_link>http:{% if variant.image.src %}{{ variant.image.src | product_img_url: 'grande' }}{% else %}{{ product.featured_image.src | product_img_url: 'grande' }}{% endif %}</g:image_link>
<g:gtin>{{ variant.barcode }}</g:gtin>
<g:brand>{{ product.vendor }}</g:brand>
<g:mpn>{{ variant.sku }}</g:mpn>
<g:product_type>{{ product.type }}</g:product_type>
<g:age_group>{{ AgeGroup }}</g:age_group>
{% unless Color == "" %}<g:color>{{ Color | strip_html | strip_newlines | replace: '&', '&amp;' }}</g:color>{% endunless %}
{% unless Size == "" %}<g:size>{{ Size | strip_html | strip_newlines | replace: '&', '&amp;' }}</g:size><g:size_system>US</g:size_system>{% endunless %}
<g:gender>{{ Gender }}</g:gender>
</item>

  {% endfor %}
  {% else %}
<item>
<title>{{ product.title | strip_html | strip_newlines | replace: '&', '&amp;' }}</title>
		<link>{{ shop.url }}{{ product.url }}</link>
<description>{{ product.title | strip_html | strip_newlines | replace: '&', '&amp;' }} {{ product.description | replace: '</', ' </' | strip_html | strip_newlines | replace: '&', '&amp;' }}</description>
<g:google_product_category>{{ GoogleProductCategory | replace: '&', '&amp;'  }}</g:google_product_category>
<g:item_group_id>{{ product.id }}</g:item_group_id>
<g:id>{{ product.id }}</g:id>
<g:condition>new</g:condition>
<g:price>{{ product.price | money_without_currency }} {{ shop.currency }}</g:price>
<g:availability>{% if product.available %}in stock{% else %}out of stock{% endif %}</g:availability>
<g:image_link>http:{{ product.featured_image.src | product_img_url: 'grande' }}</g:image_link>
<g:gtin>{{ product.barcode }}</g:gtin>
<g:brand>{{ product.vendor }}</g:brand>
<g:mpn>{{ product.sku }}</g:mpn>
<g:product_type>{{ product.type }}</g:product_type>
<g:age_group>{{ AgeGroup }}</g:age_group>
<g:gender>{{ Gender }}</g:gender>
</item>
  {% endif %}
{% endfor %}
</channel>
</rss>
{% endpaginate %}

or Download from Github:  Shopify Facebook Product Feed Template

Step 3
Assign products to your Feed Collection.

You now need to assign products to your new facebook feed template:

  • Go to Products > Collections
  • Click Create Collection
  • Enter a Title for your feed collection. I recommend Facebook Product Feed.
  • Add the products you want to be included in your Facebook feed, either manually or using conditions.
  • IMPORTANT! Assign your feed TEMPLATE to this collection. In the right column, at the bottom, under Theme Templates, choose : collection.fb-product-feed (the name may change depending on what you actually called your template file).
  • Click Save Colleciton.
  • Preview the collection to make sure it works. You should see unformatted text on the screen. Do a “view source” in your browser to see the formatted XML.
  • Copy the url of this collection as you need it in the next step.

Step 4
Upload your Product Feed to Facebook

  • Log into Facebook Business Manager
  • Go to Assets > Product Catalogs > Product Feeds and click +Add Product Feed to create a new feed.
  • Enter a descriptive name for your feed. (eg: Shopify Facebook Feed); your store’s currency; select recurring or single upload; and click next.
  • Enter your feed collection url you copied in step 3 above. Leave the username & password blank. Choose a time for your daily upload to occur (early morning is usually a good time)
  • Click Create Feed and wait for the feed to be fetched and processed.
  • Fix errors: If there are errors, go back, fix them, re-fetch, and keep doing so until the feed is error free.

NOTE: If you have more than 1000 variants, you will need to submit multiple feeds with a ?page=x querystring appended like so:

Step 5
Exclude your Facebook Feed Collection from Showing on your Public Store Pages

Depending on how your store is setup, you may need to add some code to prevent your Facebook feed collection from showing up on your store. The exact way to do this may depend on your theme, but generally you will want to have an “unless” statement within the loop that displays your collections:

{% unless collection.title contains "facebook" %}
... your collection code ...
{% endunless %}

Done!

You are now ready to setup your Dynamic Product Remarketing campaigns!

Related Posts

Shopify: Fix your Google Analytics Product Performance Reports

The Problem: By default Shopify includes product variant details in the product’s name when it sends e-commerce data to Google Analytics, . If you sell clothing ,or shoes, or other products with color and size variants, then your Product Performance Report becomes too granular.

ga-productperformance-productname

How Shopify data shows up by default in Google Analytics. Notice that the various “Trillium Parka” variants are ungrouped because the size and color information is in the product name. This makes it difficult to see aggregate data for all variants of this product.

This is a bug, because there already exists a “Product Variant” field in Analytics, and it is already being properly populated.

The Solution:
Google Analytics Custom Data Import

The solution to this problem is to overwrite the Shopify data using the Custom Data Import tool.

Step 1: Export your Product Data

First we need to export all our product data – you can use a similar technique to generating your own custom Google Shopping Product Feeds to build a CSV export file.

a. Create a new Collection Template

Call the new collection template csv-ga-product-feed and paste the following code:

{% layout none %}{% paginate collection.products by 1000 %}ga:productSku,ga:productName,ga:productVariant{% for product in collection.products %}{% for variant in product.variants %}
{{ variant.sku }},{{ product.title | replace: ',','' }},{{variant.title | replace: ',',''}}{% endfor %}{% endfor %}{% endpaginate %}

(also available on GitHub here)

b. Create a new Collection based on your csv-ga-product-feed Template

Select the products you want to include in this feed (probably all your products). These will be the products whose values will be overwritten in Google Analytics. Call your collection “Google Analytics Product Data Import” or something similar and save it.

c. Download your Product Feed

  • View your new collection in your store (eg: store.myshopify.com/collections/google-analytics-product-data-import)
  • View source in your browser and save as HTML
  • Rename the file with a CSV extension (eg: google-analytics-product-data-import.csv)

Step 2: Setup and Import the data into Google Analytics

IMPORTANT WARNING! I highly recommend you duplicate or backup your Google Analytics view and do a trial run before working with your live data. Once you upload this new data and overwrite there is no UNDO!

a. Setup the Data Feed

  • Go to Google Analytics > Admin > Account > Property > Data Import
  • Click the red “+ NEW DATA SET” button
  • Select “Product Data”
  • Give your Data Import a name: “Product Name Override”
  • Select the Google Analytics Views you want this import to affect
  • Setup your Data Set Schema: Product SKU is the mandatory key, but select Product and Product Variant as the additional fields.
  • Overwrite Hit Data: Choose Yes (but read my warning above)
  • Click Save and Done

b. Upload your data feed

  • Click on “manage uploads” beside your new Data Feed definition
  • Click the blue UPLOAD button
  • Choose your CSV file and click UPLOAD again
  • And now wait for the upload an update to be complete

Step 3: Verify your new data

The data upload will only affect data from this date forward. So your old data will unfortunately not be fixed. But your future data will be nice and clean.

You will need to wait at least a day before you start seeing the new data coming in. If you add new product SKUs to your store, you will also need to regenerate and reupload a new file in order for the new product data to be fixed.