Skip to content

Example of Shopify's Dawn theme working with Partytown (Password: partydawn)

Notifications You must be signed in to change notification settings

pridyok/shopify-partydawn

 
 

Repository files navigation

Partydawn

Example of Shopify's Dawn theme working with Partytown. Example site is up at https://partydawn.myshopify.com (password: partydawn).

Currently included in this repo are different ways of how to integrate Partytown:

  • GTM (through Shopify's Web Pixel)
  • Matomo (working without consent)
  • Klaviyo (dynamically injected based on consent)
  • Trekkie (altered Shopify's own tracking to work with Partytown)
    • Official Google Analytics 4 Integration
    • Official Facebook Integration

Usage

  • Clone the repo
  • Set up a Shopify development store with an app that manages cookie consent (the example uses Consentmo)
  • shopify theme dev --store=YOUR_STORE
  • Set up a partytown proxy worker and app proxy
    • Note: a skeleton app is fine for this because you really only need the proxy settings. Using the CLI is the easiest option
  • Create a new Custom Web Pixel with the contents of backend/pixel/gtm.js
  • Add the contents of backend/checkout/additional.liquid to Settings-> Checkout -> Order Status Page Additional Scripts
  • Connect Google Analytics using the official integration
  • Connect Facebook using the official integration
  • Go to the Theme Customizer -> Theme Settings -> Partydawn and fill out the settings as needed

Manually Open the Consent

When using Consentmo and want to test different settings with tracking, you can open your browser's developer console and invoke showPreferences(). It works differently with other cookie consent apps. I only mention this because adding a button to reopen consent is a premium feature within Consentmo and I was lazy enough not to add a button myself.

Google Tag Manager

  • snippets/header-partytown-analytics.liquid
  • snippets/global-partytown.liquid
  • backend/pixel/gtm.js

Shopify uses Web Pixels to hook into customer events. Although Web Pixels are JavaScript snippets, you can't get Partytown to work because it's a sandboxed environment in an iframe without access to the top frame. To install the Tag Manager inside the Pixel I basically followed the official documentation, with the exception that we don't want to load the GTM script directly in the sandbox.

Instead we inject the script as text/partytown in the regular page and create an event bridge between the Pixel and the main page using the sessionStorage that is available in the Pixel. We push events in the storage, pick them up on the main page, and forward them to Partytown:

// inside the Pixel
browser.sessionStorage.setItem(`pt_dl_` + inc++, JSON.stringify(data));

// on the main page
function isSessionStorageAvailable() {
  var test = 'test';
  try {
    sessionStorage.setItem(test, test);
    sessionStorage.removeItem(test);
    return true;
  } catch (e) {
    return false;
  }
}

if (isSessionStorageAvailable()) {
  var inc = 0;
  window.setInterval(function () {
    while (sessionStorage.getItem('pt_dl_' + inc) !== null) {
      window.dataLayer.push(JSON.parse(sessionStorage.getItem('pt_dl_' + inc)));
      sessionStorage.removeItem('pt_dl_' + inc);
      inc++;
    }
  }, 1000);
}

If sessionStorage is not available the Pixel installs the GTM conventionally. This is also done on checkout pages which can't be directly controlled.

Web Pixel play nicely with the integrated consent. They follow the rules defined on Sales Channels -> Online Store -> Preferences -> Customer Privacy. Whenever it feels appropriate to hook into Shopify's customer events for tracking purposes, this is the way to go.

You can certainly also use window.postMessage to build an event bridge between the Web Pixel (iframe) and the top frame. But I chose sessionStorage since it's directly supported by the Web Pixel API.

Tagging Server

You can test a server implementation by altering the tag manager URL in the theme settings partydawn_gtm_server. It's impossible to create first-party cookies from the server with a dev store setup though. You cannot solve cross-domain. I tried a app proxies and use https://partydawn.myshopify.com/a/sgtm as the server url, but routing the request through Shopify's app logic eats all cookies alive. And because you cannot attach a domain to a dev shop you're out of options. So there's unfortunately no way to test whether cookies get correctly set with sgtm working inside partytown.

There's no cookie banner on the test site so be warned...

I've set up a small test site that uses a subdomain for the tagging server. While testing, I noticed that cookies from the tagging server that are served through HTTP Set-Cookie headers are not set properly. I realized that for whatever reason even when setting withCredentials, XMLHttpRequest is unable to send or set cookies inside Web Workers. fetch doesn't suffer from the same issue.

I've posted the issue here: QwikDev/partytown#501

Since it might be a platform issue, the only real way around this seems to be using a shim that implements the original XMLHttpRequest API, but uses fetch under the hood. https://github.com/apple502j/xhr-shim/blob/main/src/index.js is a nice starting point, but you also at least need to add onprogress and onreadystatechange for most scripts to work. When using SGTM + PT + XHR_REWRITE on the test site, the underlying Cloudflare URL Proxy automatically applies a shim and the cookies are correctly set.

This is a bit of a pain and I'm hoping to be able to provide a fix within Partytown in the future. Again: This is only an issue if working with a tagging server or relying on anything else that sets cookies through the Set-Cookie HTTP header. All document.cookie from text/partytown work just fine.

There's no cookie banner on the test site so be warned...

Matomo

  • snippets/global-partytown.liquid
  • snippets/matomo-tracking.liquid
  • backend/checkout/additional.liquid

There might be tracking that you can run regardless of the consent. You can just add it as text/partytown and Partytown will pick it up. Please note that you need to add additional tracking inside Settings-> Checkout -> Order Status Page Additional Scripts. This enables you to track the checkout as well. Unfortunately we can't use Web Pixels here because they only run when the user consents. There is no way to add Pixels based on the user consent. This also means you unfortunately cannot track any checkout sub steps, just the conversion. But in most cases this should be fine.

Klaviyo

  • snippets/global-partytown.liquid
  • snippets/klaviyo-tracking.liquid

There's also tracking that works outside Shopify's consumer events, but needs to respect user consent. Klaviyo is such an example. It's already known to work with Partytown and can be integrated easily. You just have to use the Customer Privacy API that Shopify offers.

(async function () {
  function waitForCustomerPrivacy() {
    return new Promise(function (resolve) {
      var interval = setInterval(function () {
        if (window.Shopify && window.Shopify.customerPrivacy) {
          clearInterval(interval);
          resolve();
        }
      }, 100);
    });
  }

  await waitForCustomerPrivacy();

  if (window.Shopify.customerPrivacy.thirdPartyMarketingAllowed()) {
    startKl();
  } else {
    document.addEventListener('visitorConsentCollected', function (event) {
      if (event.detail.thirdPartyMarketingAllowed) {
        startKl();
      }
    });
  }
})();

Note that the functions expects another script to init the API as described here, but you can also do this yourself. Usually the consent integration / app takes care of it. For Klaviyo you need to follow the official integration guide, but don't use the App Embed.

Also remember to inform Partytown that Klaviyo has been added:

window.dispatchEvent(new CustomEvent('ptupdate'));

Trekkie

  • snippets/global-partytown.liquid
  • assets/trekkie-partytown.js

Trekkie is Shopify's own tracking engine and gets loaded as part of the content_for_header blackbox. We can thankfully still manipulate inline scripts using a MutationObserver. Changing the type to text/partytown will prevent script execution and the script will instead be processed by Partytown. You need to rewire a couple more inline scripts as shown in assets/trekkie-partytown.js. Any script containing ShopifyAnalytics needs to get added to the Partytown instance and remain on the main page. Otherwise the site starts to throw errors.

Using the standard integrations for Google Analytics and Facebook with "partytowned" Trekkie leads to the attached pixels also being loaded within a Web Worker. I haven't fully tested this method, so treat it with caution and confirm that the data is correctly being collected by the third partys vendors.

You can also block trekkie using the partydawn_trekkie_disabled theme setting to test other Facebook and GA4 implementations (like GTM/SGTM).

Testing Improvements With Lighthouse

With the setup you can easily switch between Partytown and conventional tracking and compare the speed benefits. I installed a lot of app clutter on the shop because admittedly Dawn is pretty fast with and without tracking in its original version. In a usual production environment you will inevitably add apps and fill the store with JavaScript that you often cannot directly control. That's when Partytown might be able to give you a bit relief, because you start to see the usual issues.

Tracking Type Page Performance Link
Conventional Index 86 Click
Conventional Collection 77 Click
Conventional Product 77 Click
Partytown Index 97 Click
Partytown Collection 97 Click
Partytown Product 92 Click

Resources and Credits

A Word Of Caution

Please note that this is not the intended way of tracking in Shopify OS 2.0. Anything used here can break at any time if Shopify decides to change the way Trekkie or Web Pixels work. In a production environment you need to have a dev watching over your site or Partytown might cause more harm than good. Any theme should have a "kill switch" to return to conventional tracking in case something breaks.

Other than that: Have fun offloading your tracking scripts!

About

Example of Shopify's Dawn theme working with Partytown (Password: partydawn)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Liquid 68.5%
  • CSS 21.1%
  • JavaScript 10.4%