Concepts

Understanding Tags, Triggers, and Zones — the building blocks of YourTM.

Overview

YourTM uses three core concepts to manage tracking and analytics on your website:

🌐 Your Website
YourTM Runtime
Zones
Which pages?
  • global
  • checkout
  • product
Triggers
When to fire?
  • page-load
  • click
  • scroll
Variables
What data?
  • cartTotal
  • userId
  • orderValue
Tags
What to execute?
  • GA4 Pageview
  • Meta Pixel
  • Custom tracking

Tags

Tags are the code that gets executed when certain conditions are met. They typically send data to analytics platforms, load third-party scripts, or perform custom tracking.

T What is a Tag?

A tag is a TypeScript module that defines tracking behavior. It specifies what code to run, when to run it (triggers), and where to load it (zones).

Tag Structure

yourtm/tags/ga4-pageview.ts
import { defineTag } from '@yourtm/core'

export default defineTag({
  // Identification
  name: 'GA4 Pageview',
  description: 'Track page views in Google Analytics 4',

  // When to fire
  triggers: ['page-load'],

  // Where to load
  zones: ['global'],

  // Required consent
  consent: ['analytics'],

  // Priority (higher = fires first)
  priority: 100,

  // One-time setup (loads external scripts)
  async setup() {
    const script = document.createElement('script')
    script.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX'
    script.async = true
    document.head.appendChild(script)

    window.dataLayer = window.dataLayer || []
    window.gtag = function() { dataLayer.push(arguments) }
    window.gtag('js', new Date())
  },

  // Runs every time the trigger fires
  execute(ctx) {
    window.gtag('config', 'G-XXXXX', {
      page_title: ctx.dataLayer?.page?.title || document.title,
      page_location: ctx.url.href,
    })
  },
})

Tag Properties

name string Human-readable name for the tag
description string? Optional description of what the tag does
triggers string[] Array of trigger IDs that fire this tag
zones string[] Array of zone IDs where this tag loads
consent string[]? Required consent categories (e.g., ['analytics'])
priority number? Execution priority (0-100, higher fires first)
setup () => void? One-time initialization (load scripts, etc.)
execute (ctx) => void Called each time the trigger fires

Triggers

Triggers define when tags should fire. They listen for specific events on the page and activate associated tags when conditions are met.

What is a Trigger?

A trigger listens for browser events (page load, clicks, scrolls, etc.) and fires tags when the event occurs. Multiple tags can share the same trigger.

Built-in Trigger Types

pageview PageviewTrigger Fires on page load or virtual page views
click ClickTrigger Fires when elements matching a selector are clicked
scroll ScrollTrigger Fires at specific scroll depth percentages
visibility VisibilityTrigger Fires when elements become visible in viewport
timer TimerTrigger Fires after a specified time delay
form FormTrigger Fires on form submission
custom CustomTrigger Fires on custom dataLayer events

Trigger Examples

yourtm/triggers/scroll-75.ts
import { defineTrigger } from '@yourtm/core'

export default defineTrigger({
  name: 'Scroll 75%',
  type: 'scroll',
  config: {
    threshold: 75,    // Fire at 75% scroll depth
    once: true,       // Only fire once per page
  },
})
yourtm/triggers/add-to-cart.ts
import { defineTrigger } from '@yourtm/core'

export default defineTrigger({
  name: 'Add to Cart Click',
  type: 'click',
  config: {
    selector: '[data-action="add-to-cart"], .add-to-cart-btn',
    checkChildElements: true,  // Include clicks on child elements
  },
})
yourtm/triggers/form-submit.ts
import { defineTrigger } from '@yourtm/core'

export default defineTrigger({
  name: 'Contact Form Submit',
  type: 'form',
  config: {
    selector: '#contact-form',
    waitForValidation: true,
  },
})

Variables

Variables are reusable data points that can be used across multiple tags. They allow you to define a piece of data once (like a Product ID or a Cookie value) and use it everywhere.

V What is a Variable?

A variable is a dynamic value extracted from the dataLayer, cookies, URL, or custom JavaScript. The YourTM runtime resolves these values lazily only when a tag requests them.

Variable Types

DataLayer datalayer Reads a value from the dataLayer using dot notation
Cookie cookie Reads a value from a browser cookie
URL url Extracts query parameters, path segments, or hash
Computed computed A custom TypeScript function that calculates a value

Defining Variables

yourtm/variables/ecommerce.ts
import { defineDataLayerVariable, defineComputedVariable } from '@yourtm/core'

// Simple DataLayer variable
export const cartTotal = defineDataLayerVariable({
  name: 'cartTotal',
  path: 'ecommerce.cart.total',
  default: 0
})

// Complex computed variable
export const orderValue = defineComputedVariable({
  name: 'orderValue',
  compute: (ctx) => {
    const items = ctx.dataLayer.ecommerce?.items || []
    return items.reduce((sum, item) => sum + (item.price * item.quantity), 0)
  }
})

Using Variables in Tags

Variables are available on the ctx.variables object in the tag's execute function.

yourtm/tags/ga4-purchase.ts
export default defineTag({
  name: 'GA4 Purchase',
  execute(ctx) {
    // Access variables directly
    const value = ctx.variables.orderValue
    const currency = ctx.variables.currencyCode || 'USD'

    gtag('event', 'purchase', {
      value: value,
      currency: currency
    })
  }
})

Zones

Zones define where tags should load. They segment your website into logical areas, ensuring only relevant tags are loaded on each page.

📍 What is a Zone?

A zone is a collection of pages defined by URL patterns. Tags specify which zones they belong to, and only load on pages that match those zones. This keeps bundles small and performant.

The "Load vs. Fire" Distinction:

It's important to understand the difference between a Zone and a Trigger:

  • Zones (Load): Control which JavaScript bundles are downloaded by the browser. A zone like checkout ensures checkout-related tags only load when a user is in the checkout flow.
  • Triggers (Fire): Control when a loaded tag actually executes its code (e.g., on a specific button click or a specific pageview within that zone).

By separating these, YourTM achieves superior performance. For example, you can bundle all checkout tags into one file (Zone: /checkout/**) but only fire the "Purchase" tag on the final step (Trigger: /checkout/success).

Zone Structure

yourtm/zones/checkout.ts
import { defineZone } from '@yourtm/core'

export default defineZone({
  name: 'checkout',
  description: 'Checkout and payment flow pages',
  match: {
    // Match any of these pathname patterns
    pathname: [
      '/checkout',
      '/checkout/*',
      '/cart',
      '/payment/*',
      '/order/confirmation',
    ],
  },
})

URL Matching

Zones support glob-style URL pattern matching:

/checkout exact Matches exactly /checkout
/checkout/* wildcard Matches /checkout/shipping, /checkout/payment, etc.
/products/** deep wildcard Matches any depth under /products
/blog/:slug parameter Matches /blog/my-post, /blog/another-post

Common Zones

yourtm/zones/global.ts
import { defineZone } from '@yourtm/core'

export default defineZone({
  name: 'global',
  description: 'Loads on all pages',
  match: {
    pathname: ['**'],  // Match everything
  },
})
yourtm/zones/product.ts
import { defineZone } from '@yourtm/core'

export default defineZone({
  name: 'product',
  description: 'Product detail pages',
  match: {
    pathname: ['/products/*', '/p/*', '/item/*'],
  },
})

YourTM has built-in consent management. Tags specify which consent categories they require, and only fire when the user has granted that consent.

Consent Categories

necessary always on Essential functionality (session, security)
analytics optional Usage analytics (GA4, Mixpanel, etc.)
marketing optional Advertising and remarketing pixels
preferences optional Personalization and preferences

Setting Consent

// In your consent banner / CMP integration
window.YTM.setConsent({
  necessary: true,
  analytics: true,
  marketing: false,
  preferences: true,
})

Tag with Consent

export default defineTag({
  name: 'Meta Pixel',
  triggers: ['page-load'],
  zones: ['global'],
  consent: ['marketing'],  // Only fires if marketing consent granted
  execute(ctx) {
    fbq('track', 'PageView')
  },
})

Data Layer

The data layer is a JavaScript object that stores page and event data. Tags can read from it to send enriched data to analytics platforms.

Pushing to Data Layer

// On your website
window.YTM.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T12345',
    value: 99.99,
    currency: 'USD',
    items: [
      { item_id: 'SKU123', item_name: 'Widget', price: 99.99 }
    ]
  }
})

Reading in Tags

export default defineTag({
  name: 'GA4 Purchase',
  triggers: ['purchase-event'],
  execute(ctx) {
    const { transaction_id, value, currency, items } = ctx.dataLayer.ecommerce
    gtag('event', 'purchase', {
      transaction_id,
      value,
      currency,
      items,
    })
  },
})

Execution Context

Every tag's execute() function receives a context object with useful information about the current page and event.

Context Properties

ctx.url URL Current page URL object (href, pathname, search, etc.)
ctx.dataLayer object Current data layer state
ctx.event Event? Browser event that triggered (for click, form, etc.)
ctx.element Element? DOM element that triggered (for click, visibility, etc.)
ctx.consent object Current consent state

Tag Lifecycle

Understanding the tag lifecycle helps you write efficient tags.

1

Load core.js

The tiny (~2KB) runtime engine is downloaded.

2

Match Zones

The runtime detects the current URL and determines which zone bundles to load.

3

Load zone-*.js

Only the specific bundles matching the active zones are loaded.

4

Register Tags

Tags from the loaded bundles are registered into the runtime.

5

Run setup()

One-time initialization occurs (e.g., injecting third-party vendor scripts).

Wait for Trigger

The runtime listens for browser events (clicks, scrolls, pageviews).

🛡️

Check Consent

When a trigger fires, the runtime verifies the user has granted required consent.

🔄

Resolve Variables

Any variables used by the tag (dataLayer, cookies, etc.) are resolved lazily.

Run execute()

The tag's execute function is called, sending data to the analytics platform.

Bundle Architecture

YourTM compiles your tags into optimized JavaScript bundles, organized by zone.

Bundle Types

core.js ~2KB Runtime engine, trigger system, consent management
zone-global.js varies Tags in the global zone (loaded on all pages)
zone-checkout.js varies Tags only needed on checkout pages
zone-product.js varies Tags only needed on product pages
Tip: Use zones strategically to keep bundles small. A checkout-only conversion pixel doesn't need to load on your blog pages.

Runtime

The YourTM runtime is a lightweight JavaScript engine that manages tag execution.

Runtime API

// Available on window.YTM

// Initialize (called automatically)
YTM.init()

// Register a tag (called by zone bundles)
YTM.registerTag(tagDefinition)

// Set consent state
YTM.setConsent({ analytics: true, marketing: false })

// Push to data layer
YTM.push({ event: 'purchase', value: 99 })

// Access internal state (for debugging)
YTM._state.tags       // Map of registered tags
YTM._state.triggers   // Map of registered triggers
YTM._state.consent    // Current consent state

Performance

YourTM is designed for maximum performance with minimal impact on your site.

Performance Features

Performance Budgets

Configure budgets in yourtm.config.ts:

budgets: {
  maxBundleSize: 100_000,   // 100KB total
  maxTagSize: 10_000,       // 10KB per tag
  warnOnSlowTags: 100,      // Warn if tag takes >100ms
}