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:
- Background service worker — Captures network requests via
chrome.webRequestAPI - DevTools panel — Renders the main UI with request list, detail tabs, and toolbars
- Content scripts — Intercepts data layer pushes in the page’s MAIN world
- 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:
- 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. - 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:
- URL parsing — Query string parameters are extracted and URL-decoded
- POST body parsing — JSON and form-encoded POST bodies are parsed
- 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.)
- 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:
- MAIN world script (
data-layer-main.js) — Runs in the page’s JavaScript context and proxieswindow.dataLayer.push(),window.utag.link(),window.utag.view(),adobeDataLayer,window.analytics.track(), andwindow.digitalData - ISOLATED world script (
data-layer-bridge.js) — Acts as a relay between the MAIN world and the extension, forwarding intercepted pushes viapostMessage - 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:
- TagDragon detects an Adobe Launch library URL on the page
- When you select an environment, a redirect rule is created that rewrites the Launch URL from one environment to another
- The redirect happens at the network level — the page’s HTML is not modified
- Rules persist in
chrome.storage.localper 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.
Related
- Privacy & Security — Permissions and data handling details
- Features — Complete feature overview
- Contributing — How to extend TagDragon with new providers