Skip to content

Track JS

The Track components provide declarative analytics tracking, defined entirely in HTML/Twig/Liquid attributes — no custom JavaScript required. A provider-agnostic core (AbstractTrack) is shipped as two ready-to-use variants selected by component name:

  • Track pushes the resolved payload to window.dataLayer (GTM / GA4).
  • TrackShopify publishes it through window.Shopify.analytics.publish.

TrackContext lets you factor shared data out of individual events and inherit it from ancestors.

Table of content

Usage

Register the components you need in your application:

js
import { Base, createApp } from '@studiometa/js-toolkit';
import { Track, TrackShopify, TrackContext } from '@studiometa/ui';

class App extends Base {
  static config = {
    name: 'App',
    components: {
      Track,
      TrackShopify,
      TrackContext,
    },
  };
}

createApp(App);

Then declare what to track with data-track:<event> attributes. The value can be a bare event name (data-track:click="add_to_cart") or, when an event needs its own structured data, a JSON payload whose event key holds the name. Data shared by every event on the element can be provided through a <script data-ref="payload"> child or a data-option-payload attribute.

Click tracking

Track user interactions with data-track:click:

Page-load tracking

Use the reserved mounted event to dispatch on mount (e.g. a page view):

Impression tracking

The reserved view event dispatches when the element enters the viewport (via IntersectionObserver). Add .once to fire a single impression, and tune visibility with the threshold option.

Shared context

Wrap a section in TrackContext to provide data inherited by every descendant Track. Context is deep-merged up the whole ancestor chain — the nearest context wins. Author it in a <script data-ref="context" type="application/json"> (safe with Liquid/Twig, even with quotes in values) or, for simple cases, a data-option-context attribute.

Custom events

Track a CustomEvent emitted by third-party scripts and pull values from its detail with the $detail.* placeholder syntax:

Multiple events

Declare several data-track:* attributes on one element to track independent events, each with its own payload and modifiers:

Choosing a provider

The provider is chosen by the component name, so switching destinations is a one-token change in the markup:

html
<!-- Google Tag Manager / dataLayer -->
<button data-component="Track" data-track:click='{"event": "add_to_cart"}'>Add to cart</button>

<!-- Shopify storefront analytics -->
<button data-component="TrackShopify" data-track:click='{"event": "my_app:add_to_cart"}'>
  Add to cart
</button>

TrackShopify uses the payload's event value as the published event name. Shopify recommends namespacing custom events (e.g. my_app:add_to_cart). To send to another destination, extend Track and override its dispatch() method.

WARNING

Payloads are serialised into the DOM (attribute or <script>), so they are visible in the page source. Never put personal data (emails, names, user IDs) in a tracking payload — resolve sensitive values at runtime via a CustomEvent and $detail.* instead, and gate TrackShopify on the visitor's analytics consent where required.