Connector: Shopify

The Shopify Plugin allows you to connect your Shopify Store to Spotler Activate. By installing the Plugin, Event Tracking and Product Feed will be automatically implemented in Spotler Activate. In addition, existing email addresses and newsletter consent from Shopify will be imported into Spotler Activate.

Activate the Shopify connector

Step 1: Add tracking code in theme

In Spotler Activatie on the Apps page you will find the Shopify connector. Open the connector and Copy the Tracking script tag. 

Go to your Shopify Store. Go to "Online Store → Themes → Customize Themes".

Shopify 1.png

Go to "... → Edit code".

Shopify 2.png

Paste the "Tracking script tag" into the <head> section in theme.liquid. Click on "Save".

Shopify 3.png

Alternative option: Google Analytics code snippet

This is only required when you are unable to follow step 1 or when this step does not add the tracker code as expected. Go to "Online Store → Themes → Preferences". Scroll to "Google Analytics" and add the following snippet to the "Add custom JavaScript to Google Analytics" box. Replace YOUR SQ ACCOUNT ID with your Spotler Activate Account ID, found at the Settings page.

/* START SQUEEZELY TRACKING */
/* Please note we're using Shopify Privacy Consent. If you use this, please hook us into your cookiebanner. */
function loadSqueezely() {
if (!window.Shopify.customerPrivacy || window.Shopify.customerPrivacy.userCanBeTracked()) {
var sqzlScript = document.createElement("script");
sqzlScript.src = 'https://app.squeezely.tech/assets/js/channels/SqueezelyShopifyTracker.js?SqueezelyIdentifier=YOUR SQ ACCOUNT ID';
sqzlScript.async = 1;
if(document.body && typeof document.body.appendChild === 'function') {
document.body.appendChild(sqzlScript);
}
else if(document.head && typeof document.head.appendChild === 'function') {
document.head.appendChild(sqzlScript)
}
else {
document.lastChild.appendChild(sqzlScript);
}
}
}
loadSqueezely();
/* END SQUEEZELY TRACKING */

Step 2: Add code on thank you page

Navigate in your Shopify admin to Settings → Checkout and accounts. Scroll to Order status page add in “Additional scripts” below script (change your Spotler Activate account ID on line 6).

<!-- Squeezely purchase event -->
<script type="text/javascript">
(function(s,q,z,l,y){s._sqzl=s._sqzl||[];l=q.createElement('script'),
y=q.getElementsByTagName('script')[0];l.async=1;l.type='text/javascript';
l.defer=true;l.src=z;y.parentNode.insertBefore(l,y)})
(window,document,'https://squeezely.tech/tracker/SQ-2565XXX/sqzl.js');
let sqCurrency;
if (typeof Shopify !== 'undefined') {
sqCurrency = Shopify.currency.active;
}
window._sqzl = window._sqzl || [];
{% if order.id|json %}
window._sqzl.push({
"event" : "Purchase",
{% if customer %}
"firstname" : {{ customer.first_name|json }},
"lastname" : {{ customer.last_name|json }},
{% for customer in customer.addresses %}
"postcode" : {{ customer.zip|json }},
"city" : {{ customer.city|json }},
"country" : {{ customer.country_code|json }},
{% endfor %}
{% if customer.phone != null %}
"phone" : {{ customer.phone|json }},
{% endif %}
"email" : {{ customer.email|json }},
{% if customer.accepts_marketing == true %}
"newsletter" : "yes",
{% endif %}
{% endif %}
"orderid" : {{ order.id|json }},
"currency": sqCurrency,
"products": [
{% for line_item in line_items %}
{
"id": {{ line_item.sku|json }},
"name": {{ line_item.title|json }},
"price": {{ line_item.product.price|money_without_currency|replace: ',', '.' }},
"quantity": {{ line_item.quantity }},
},
{% endfor %}
],
});
{% elsif customer %}
window._sqzl.push({
"event" : "PrePurchase",
"firstname" : {{ customer.first_name|json }},
"lastname" : {{ customer.last_name|json }},
{% for customer in customer.addresses %}
"postcode" : {{ customer.zip|json }},
"city" : {{ customer.city|json }},
"country" : {{ customer.country_code|json }},
{% endfor %}
{% if customer.phone != null %}
"phone" : {{ customer.phone|json }},
{% endif %}
"email" : {{ customer.email|json }},
{% if customer.accepts_marketing == true %}
"newsletter" : "yes"
{% endif %}
});
{% else %}
console.log("No Squeezely purchase sent due to missing order information");
{% endif %}
</script>
<!-- End of Squeezely purchase event -->

Step 3: Using Shopify Privacy Consent

If you want to use shopify privacy consent, you will need to make sure squeezely is loaded after someone presses the accept button on your cookie banner. Here’s an example code snippet on how to do that. The loadSqueezely function name corresponds to the funtion name in step 1.

<script>
document.addEventListener('trackingConsentAccepted', () => {
loadSqueezely();
});
</script>

Step 4: Add webhooks

Go to the Apps page in Spotler Activate and select the Shopify connector. Copy your account's webhook URL.

Shopify 4.png

Go to your Shopify Store. Go to "Settings → Notifications". Scroll to the bottom of the page and click "Create Webhook". Create the following three webhooks, in JSON Format and With latest webhook API version:

  • Order Creation
  • Customer Create
  • Customer Update
  • Checkout Creation

With some webhooks, you need to add a parameter to the URL. Please look at the instructions in the Shopify app in Spotler Activate.

Step 5: Edit Spotler Activate settings

After adding the Webhooks in Shopify, you have generated a webhook signature (highlighted in yellow), for example:

Shopify 5.png

Copy this webhook signature. Go to the Spotler Activate Apps page and click on the Shopify app. Enter your Shopify Shop Url. Paste the webhook signature and click on "Save Channel".

Step 6: Add product link

Go to "Online Store → Themes → Actions → Edit code". Create a new template with name: page.squeezely-product-feed. Add the code below and save.

{%- layout none -%}<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>{{shop.name | escape_once }} Squeezely Feed</title>
<link>{{shop.url}}</link>
{% assign cnt = 0 %}
{% for product in collections.all.products %}
{% for variant in product.variants %}
{% assign cnt = cnt | plus: 1 %}
<!-- Item #{{ cnt }} -->
<item>
<id>{{variant.sku}}</id>
<external_object_id>{{variant.id}}</external_object_id>
<condition>new</condition>
<description>{{ product.description | strip_html | strip_newlines | escape_once }}</description>
<link>{{shop.url}}{{variant.url}}</link>
<currency>{{shop.currency}}</currency>
<price>{{variant.price | divided_by: 100.00 }}</price>
<inventory>{{ variant.inventory_quantity }}</inventory>
<brand>{{product.vendor | escape_once }}</brand>
<parent_id>{{ product.id }}</parent_id>
{% if variant.title == 'Default Title' %}
<title>{{ product.title | strip_html | strip_newlines | escape_once }}</title>
{% else %}
<title>{{ product.title | strip_html | strip_newlines | escape_once }} {{ variant.title | strip_html | strip_newlines | escape_once }}</title>
{% endif %}
<image_links>
{% for image in product.images %}
<image_link>https:{{ image | image_url}}</image_link>
{% endfor %}
</image_links>
<category_ids>
{% for collection in product.collections %}
<category_id>{{ collection.id }}</category_id>
{% endfor %}
</category_ids>
<availability>{% if variant.inventory_quantity > 0 %}in stock{% else %}out of stock{% endif %}</availability>
{% if product.options_with_values.size > 0 -%}
{% for optionobj in product.options_with_values -%}
{% assign optionname = 'option' | append: optionobj.position %}
{% if optionobj.name == 'size' or optionobj.name == 'Size' %}
{% if variant[optionname] %}
<size>{{ variant[optionname] }}</size>
{% endif %}
{% endif %}
{% if optionobj.name == 'color' or optionobj.name == 'Color' %}
{% if variant[optionname] %}
<color>{{ variant[optionname] }}</color>
{% endif %}
{% endif %}
{%- endfor %}
{%- endif %}
</item>
{% endfor %}
{% endfor %}
{% assign cnt = 0 %}
<categories>
{% for collection in collections %}
<category>
<id>{{ collection.id }}</id>
<title>{{ collection.title | strip_html | strip_newlines | escape_once }}</title>
<description>{{ collection.description | strip_html | strip_newlines | escape_once }}</description>
<link>{{shop.url}}{{ collection.url }}</link>
</category>
{% endfor %}
</categories>
</channel>
</rss>

Missing products? Use this template Shopify alternative feed template (pagination) instead of this template.

Go to "Online store → Pages → Add Page". Enter in"Title": squeezely-product-feed. Use the Theme template 'squeezely-product-feed':

Shopify 6.png

Make sure the url is created as: https://yourwebsite.com/pages/squeezely-product-feed. Click on "Save". Check that the url is created as: https://yourwebsite.com/pages/squeezely-product-feed 

After going through all the steps above, the installation is complete.

View incoming Shopify data

  • Events to check the incoming events, go to the Data page and scroll down. You should see that the tracked events have the active status.
  • Products to check the product sync, go the to Products page. You should see your product here. Click on a product to view the product fields.
  • Profiles to check a profile, look up your own cookie. Copy this and past this in the search bar on the 360 profile page.

Tracked events

The Shopify Plugin automatically receives the following events in Spotler Activate:

  • SessionStart
  • PersonalizationView
  • PersonalizationClick
  • PersonalizationClosed
  • PageView
  • ViewContent
  • ViewCategory
  • Search
  • EmailOptIn
  • AddToCart
  • RemoveFromCart
  • Purchase

With the Shopify Plugin, the following fields are sent per event:

Event Field
ViewContent Product array met id, name, price, language en quantity
ViewCategory Category_id
AddToCart Currency, Product array met id, name, price, language en quantity
Purchase Email, orderid, firstname, lastname, postcode, city, country, currency, userid, product array met id, name, price, language en quantityIf you want to sync more events or fields your can use Front End Tracking through Google Tag manager.

By default, Shopify does not allow access to the checkout page. The only method for measuring this is via a Shopify Plus merchant and modifying the checkout page with our tracker code and/or custom GTM events.

Product fields

The Shopify Plugin automatically updates the following product fields in Spotler Activate:

  • SKU/Product ID
  • Name
  • URL
  • Image (primary) + Image (additional)
  • Price
  • Currency
  • Availability
  • Inventory
  • Parent ID
  • Categories
  • Brand
  • Size
  • Color
  • Description
  • Condition

To update more product fields you can use a XML Feed.

Shopify alternative feed template (pagination)

In case you experience issues with products missing, you can use an alternative feed template. This utilizes Shopify’s pagination system to avoid their collection display limits. The template differences are:

  • We paginate the collection, meaning Shopify will automatically generate pages such as exampleshop.co.uk/pages/squeezely-product-feed?page=2 (as many pages as needed).
  • We list the next page link in the theme via the <nextpagelink> attribute. We then recursively retrieve each next page link until we reach the last page.
  • We only list the categories on the first page to avoid redundant data.

Template:

{%- layout none -%}<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>{{shop.name | escape_once }} Squeezely Feed</title>
<link>{{shop.url}}</link>
{% assign cnt = 0 %}
{% paginate collections.all.products by 50 %}
<nextpagelink>{{ paginate.next.url | prepend: shop.url }}</nextpagelink>
{% for product in collections.all.products %}
{% for variant in product.variants %}
{% assign cnt = cnt | plus: 1 %}
<!-- Item #{{ cnt }} -->
<item>
<id>{{variant.sku}}</id>
<external_object_id>{{variant.id}}</external_object_id>
<condition>new</condition>
<description>{{ product.description | strip_html | strip_newlines | escape_once }}</description>
<link>{{shop.url}}{{variant.url}}</link>
<currency>{{shop.currency}}</currency>
<price>{{variant.price | divided_by: 100.00 }}</price>
<inventory>{{ variant.inventory_quantity }}</inventory>
<brand>{{product.vendor | escape_once }}</brand>
<parent_id>{{ product.id }}</parent_id>
{% if variant.title == 'Default Title' %}
<title>{{ product.title | strip_html | strip_newlines | escape_once }}</title>
{% else %}
<title>{{ product.title | strip_html | strip_newlines | escape_once }} {{ variant.title | strip_html | strip_newlines | escape_once }}</title>
{% endif %}
<image_links>
{% for image in product.images %}
<image_link>https:{{ image | image_url}}</image_link>
{% endfor %}
</image_links>
<category_ids>
{% for collection in product.collections %}
<category_id>{{ collection.id }}</category_id>
{% endfor %}
</category_ids>
<availability>{% if variant.inventory_quantity > 0 %}in stock{% else %}out of stock{% endif %}</availability>
{% if product.options_with_values.size > 0 -%}
{% for optionobj in product.options_with_values -%}
{% assign optionname = 'option' | append: optionobj.position %}
{% if optionobj.name == 'size' or optionobj.name == 'Size' %}
{% if variant[optionname] %}
<size>{{ variant[optionname] }}</size>
{% endif %}
{% endif %}
{% if optionobj.name == 'color' or optionobj.name == 'Color' %}
{% if variant[optionname] %}
<color>{{ variant[optionname] }}</color>
{% endif %}
{% endif %}
{%- endfor %}
{%- endif %}
</item>
{% endfor %}
{% endfor %}
{% assign pagecount = paginate.current_page %}
{% endpaginate %}
{% assign cnt = 0 %}
{% if pagecount == 1 %}
<categories>
{% for collection in collections %}
<category>
<id>{{ collection.id }}</id>
<title>{{ collection.title | strip_html | strip_newlines | escape_once }}</title>
<description>{{ collection.description | strip_html | strip_newlines | escape_once }}</description>
<link>{{shop.url}}{{ collection.url }}</link>
</category>
{% endfor %}
</categories>
{% endif %}
</channel>
</rss>