Skip to main content

How TagDragon Works

TagDragon is a Chrome DevTools extension built on Manifest V3. It captures tracking network requests, identifies which provider sent them, and decodes the parameters into human-readable format. Here’s how each step works.

Architecture Overview

TagDragon consists of four components that communicate via Chrome extension messaging:

  1. Background service worker — Captures network requests via chrome.webRequest API
  2. DevTools panel — Renders the main UI with request list, detail tabs, and toolbars
  3. Content scripts — Intercepts data layer pushes in the page’s MAIN world
  4. Extension popup — Shows quick stats and actions from the Chrome toolbar
┌─────────────┐     webRequest      ┌──────────────────┐
│  Inspected   │ ──── events ────→  │  Background       │
│  Page        │                    │  Service Worker   │
│              │     postMessage    └────────┬─────────┘
│  Content     │ ←────────────────→          │ chrome.runtime
│  Script      │  data layer pushes          │ sendMessage
│  (MAIN +     │                              ↓
│   ISOLATED)  │                    ┌──────────────────┐
└─────────────┘                    │  DevTools Panel   │
                                    │  (request list,   │
                                    │   detail tabs,    │
                                    │   DataLayer,      │
                                    │   consent panel)  │
                                    └──────────────────┘

Request Capture Pipeline

Step 1: Network interception

The background service worker registers chrome.webRequest.onBeforeRequest listeners for all URLs (<all_urls> host permission). Every HTTP/HTTPS request from the inspected tab is observed in real-time.

Key points:

  • Passive observation — TagDragon reads requests but never modifies or blocks them (except the optional Adobe Environment Switcher)
  • DevTools-only — Requests are only captured while DevTools is open on the inspected tab
  • No replay — TagDragon does not re-send or cache any request data externally

Step 2: Provider matching

Each captured URL is matched against TagDragon’s library of 59 provider patterns. The matching uses a two-stage pipeline for performance:

  1. Domain index (fast path) — A pre-built Map<hostname, providerIndices> extracts the hostname from the URL and checks known domains. Most matches are resolved here without regex evaluation.
  2. Regex fallback (slow path) — If no domain match is found, the URL is tested against generic patterns that don’t have a specific domain.

First match wins — providers are ordered by specificity. For example, tealiumEventstream is checked before tealium because collect.tealiumiq.com/event is more specific than collect.tealiumiq.com.

Step 3: Parameter decoding

Once a provider is identified, its decode() function is called with the request data:

  1. URL parsing — Query string parameters are extracted and URL-decoded
  2. POST body parsing — JSON and form-encoded POST bodies are parsed
  3. Provider-specific logic — Each provider has custom decoding that maps raw parameter names to human-readable labels and groups them into categories (Event Parameters, User Properties, Traffic Sources, Device Info, etc.)
  4. Value translation — Base64-encoded values are decoded, URL-encoded strings are unescaped, and known enum values are labeled

Step 4: Display

The decoded request is sent to the DevTools panel, where it appears in the request list with:

  • Provider color and icon
  • Event name (extracted from the decoded parameters)
  • Timestamp, status code, duration, and size

Data Layer Interception

The DataLayer tab uses a different capture mechanism — content scripts injected into the page:

  1. MAIN world script (data-layer-main.js) — Runs in the page’s JavaScript context and proxies window.dataLayer.push(), window.utag.link(), window.utag.view(), adobeDataLayer, window.analytics.track(), and window.digitalData
  2. ISOLATED world script (data-layer-bridge.js) — Acts as a relay between the MAIN world and the extension, forwarding intercepted pushes via postMessage
  3. DevTools panel — Receives pushes and renders them in the DataLayer tab with source identification, diff computation, and correlation matching

This two-script architecture is required because Chrome extensions cannot directly access the page’s JavaScript context (MAIN world) — they need the isolated bridge for security.

Adobe Environment Switcher

Uses chrome.declarativeNetRequest API to create dynamic redirect rules:

  1. TagDragon detects an Adobe Launch library URL on the page
  2. When you select an environment, a redirect rule is created that rewrites the Launch URL from one environment to another
  3. The redirect happens at the network level — the page’s HTML is not modified
  4. Rules persist in chrome.storage.local per hostname

Data Storage

All data is stored exclusively in chrome.storage.local:

  • Settings — User preferences (max requests, theme, default tab, etc.)
  • Hidden providers — Provider filter state
  • Adobe redirects — Per-hostname environment selections
  • Session data — Temporary request stats for the popup (not persisted across restarts)

No data is ever sent to external servers, synced to Google accounts, or stored in cookies.

Was this page helpful?

Start typing to search docs...