Analytics Shopify

sag_organic and product_sync in Google Analytics

Last Updated: April 5, 2023

If you installed the Google sales channel on Shopify, you may have noticed a rise in strange referrals in your Google Analytics reports: Medium = product_sync and Campaign = sag_organic

Where do sag_organic and product_sync come from?

When the Google sales channel uploades your product feed to Google Merchant Center / Google Shopping, it appends the following UTM tags to the product url:

UTM TagValue

The following querystring is appended to your product’s link url:


Why do we need these UTM parameter?

Today, these UTM tags are no longer needed and should be stripped out from your product’s links.

They are a leftover from when Shopify first implemented the Google sales channel. They were Shopify’s way of helping you track the organic free traffic coming from Google Shopping. The intention was to help you separate Organic Google Shopping traffic from Organic Google Search Traffic.

The ability to get this granular is good, but the above implementation changed Google Analytic’s default behaviour, which is usually unwelcome (in particular when the change is unexpected).

A major problem with the Shopify implementation, is that they didn’t include a canonical_link as part of the feed. The canonical link ensures that only the “clean” version (without UTM tags) of the product link gets include into Google’s search index. Without this, you risk having your organic search traffic comign in with these UTM tags as well.

What does sag_organic mean?

The “SAG” in sag_organic stands for Surfaces Across Google.

Surfaces Across Google was the name of the Google feature that enabled “free shopping listings”. It has since been renamed to “free shopping listings” and the name “SAG” is no longer used.

Fixing your Product Urls

If you have Auto-Tagging properly configured in both Google Ads and in Google Merchant Center, then Google Analytics will be able to properly differentiate between Paid and Organic Shopping traffic.

Step 1
Rewrite the UTM tags

This will remove all UTM parameters from your Product Links

  1. Go to Merchant Center > Products > Feeds
  2. Click on the Content API feed
  3. Click on the Feed Rules tab
  4. Click the big blue PLUS + button, type link in the field, and select link from the drop down.
  5. For Data Source, select Set to, type link and select link from the Primary Feed: Content API list.
  6. Click OK
  7. Set the default behaviour if the link is blank to “Leave Blank”
  8. Now go to Modifications > Add Modification
  9. Choose Optimize URL > Set Parameter
FunctionParameter Name
Remove Parameterutm_source
Remove Parameterutm_medium
Remove Parameterutm_campaign
Remove Parameterutm_content
  1. Click OK and look in the right side column preview to see if the link has been properly updated.
  2. Click Save as Draft and Apply

Step 2
Set your Canonical Link

This will ensure that only the “clean” version (without UTM tags) of the product link gets include into Google’s search index.

“If you use tracking parameters in your link attributes, it is recommend that you use the canonical_link attribute to provide a canonical URL. Use the canonical_link attribute to ensure that products are associated with the correct URL in the Google Search index.”

Google Merchant Center Help
  1. Go to Merchant Center > Products > Feeds
  2. Click on the Content API feed
  3. Click on the Feed Rules tab
  4. Click the big blue PLUS + button to add a new Rule and type canonical and choose canonical link from the drop down.
  5. For Data Source, select Set to, type link and select link from the Processed Attributes list.
  6. Click OK
  7. Change the default behaviour if canonical_link has no value to “leave blank”
  8. Add Modification > Find and Replace
    Now we need to add two Find & Replace operations. One to remove the UTM tags and another to remove the Currency parameter that Shopify also appends.
1&?utm_.+?(&|$)$(leave blank)Search as regular expression
2&currency=(…)(leave blank)Search as regular expression
  1. Click OK and look in the right side column preview to see if the new link looks nice and clean. It should only have the variant id in there.
  2. Click Save as Draft and Apply
Your canonical feed rules should look something like the above

Step 3
Configure Auto-Tagging

This will configure Google Ads and Google Merchant Center to properly tag your product urls, and Google Analytics not to override that tagging:

  1. Google Ads (in the left hand menu)
    Settings > Account Settings > Auto Tagging: ON
  2. Google Merchant Center:
    Gear Icon > Conversion Settings > Auto Tagging: ON
  3. Google Analytics:
    Property Settings > Advanced Settings > Allow Manual Tagging to Override: OFF


You may need to wait a few hours for your feed to be update with the new values, but this *should* give you the default vanilla base setup that Google expects in Analytics.

Paid Shopping traffic will show up as google/cpc while Free Shopping traffic will show up as google/organic (or as “Shopping free listings” in GA4)

Related Resources

Analytics Shopify

Fix Product Performance Reports in Google Analytics with Shopify

By default, Shopify sends transactions to Google Analytics with a unique product title for each product variant. This causes the Product Performance Report to be split on the variant level instead of at the product level as it was intended.

This is how Shopify data shows up by default in the Product Performance Report. Notice that the various “Trillium Parka” variants are ungrouped because of the different size and color information in the product name. This makes it difficult to see “Revenue by Product” for all “Trillium Parkas”.

If, for example. you are selling winter boots, and someone buys a size 10 in Black, Shopify will send the product name as “Winter Boots – 10 / Black” instead of just “Winter Boots“. This is a bug as as the variant details are already included in the Google Analytics “Product Variant” column.

The Solution: GA Custom Data Import

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

1: Export your Product Data

First we need to export all our product data – we can accomplish this by creating a custom Collection Template that generates a CSV report instead of the standard HTML.

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: ',','' | remove: '"' | remove: "'" | strip_html | strip }},{{variant.title | replace: ',','' | remove: '"' | remove: "'" | strip_html | strip }}{% 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:
  • View source in your browser and save as HTML
  • Rename the file with a CSV extension (eg: google-analytics-product-data-import.csv)

2: Setup and Import the data into Google Analytics

WARNING! You can really mess up your Google Analytics data if things go wrong. I highly recommend that 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

3: Verify your new data

The data upload will only affect data from this date forward. So your old data will not be fixed. But your future data will be nice and clean… Until you add new products to your store, in which case you will have to repeat this process.

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.


Shopify Cancelled Orders and Google Analytics

DEPRECATED: This code is no longer supported. Although it probably still works, please use at your own risk!

By default, when you cancel an order in Shopify, that transaction remains as positive revenue in your Google Analytics.

To “cancel” the transaction in Google Analytics you have to send a negated version of the transaction. To do this in Shopify you have to create a Webhook on Order Cancelled that hits a script (located on the same root domain as your store) that will call server side Google Analytics e-commerce code to negate the transaction.

Webhook Endpoint Dependencies


Place the following code into a file that will act as your Order Cancelled Webhook endpoint (ie:

Make sure you:

  • Update the script to use your GA Account Id and Root Domain.
  • Change the path of autoload.php to point at your php-ga library
use UnitedPrototype\GoogleAnalytics;
require_once '../includes/autoload.php'; // Update to point at your php-ga install

$GA_AccountId = 'UA-********-1'; // Update with your GA account
$GA_domain = ''; // Update with your root domain
$webhookContent = '';
// Read the webhook content
$webhook = fopen('php://input' , 'rb');
while (!feof($webhook)) {
  $webhookContent .= fread($webhook, 4096);

if (!empty($webhookContent)) {
  // Convert the webhook content into an array
  $shopifyOrder = json_decode($webhookContent, true);

  $tracker = new GoogleAnalytics\Tracker($GA_AccountId, $GA_domain);

  $visitor = new GoogleAnalytics\Visitor();

  $session = new GoogleAnalytics\Session();

  $page = new GoogleAnalytics\Page($_SERVER['REQUEST_URI']);
  $page->setTitle('Order Cancelled');

  $tracker->trackPageview($page, $session, $visitor);

  $transaction = new GoogleAnalytics\Transaction();

  foreach ( $shopifyOrder['line_items'] as $product ) {
    $item = new GoogleAnalytics\Item();

  $tracker->trackTransaction($transaction, $session, $visitor);

Setup the Webhook in Shopify

In your Admin dashboard go to:

  • Settings > Notifications > Webhooks (at the bottom)
  • Create a Webhook
  • Event: Order Cancellation // Format: JSON // URL: The full url of your php file


  • Google Analytics: Got to the Real Time > Content report
  • Shopify: Click “Send test notification” link beside your webhook.
  • Google Analytics: You should see a page request popup with your script name
  • Google Analytics: Wait a few hours and then (for transactions to register) and then go to Conversions > Ecommerce > Product Performance and you should see a sledge-hammer and wire-cutter products (the Shopify sample data) along with negative quantities and value.

Related Resources