How It Works
AttributionHub works in four stages on every page load: detect, classify, store, and populate.
The Attribution Pipeline
Stage 1: Detect
When a page loads, the script reads:
- URL parameters —
utm_source,utm_medium,utm_campaign,utm_content,utm_term, and any custom fields - Click IDs —
gclid(Google),msclkid(Microsoft),fbclid(Meta),ttclid(TikTok),li_fat_id(LinkedIn), and more - Referrer — the
document.referrerURL - Landing URL — the current page URL and path
Stage 2: Classify
Using the detected signals, the script classifies the visit into one of 20+ channel groups using a priority-based rule system:
- Check for explicit channel signals (e.g.,
utm_medium=cpcwith a search source = “Paid Search”) - Check for click IDs (e.g.,
gclidpresent = likely Google Ads) - Match the referrer against known domains (200+ search engines, 80+ social networks, 18+ AI assistants)
- Fall back to medium-based classification
- Default to Direct (no referrer, no UTMs) or “Referral” (unknown external referrer)
Stage 3: Store
The classified data is saved as a touch snapshot in localStorage. Three snapshots are maintained:
| Touch Type | Key Prefix | Behavior |
|---|---|---|
| First Touch | ah_ft_ | The first non-direct visit. Locked permanently once set. Never overwritten. |
| Latest Touch | ah_lt_ | Updated on every page load, including direct visits. |
| Latest Non-Direct | ah_lnd_ | Updated only when the visit comes from an external source. Preserved across direct revisits. |
Additional stored values:
ah_visitor_id— a unique UUID generated on the first visitah_touch_count— number of non-direct visits (incremented only on external traffic)
Stage 4: Populate
The script discovers forms on the page and fills matching hidden fields with attribution data. See Conversion Tracking for the full form population architecture, supported platforms, and field mapping details.
Touch Snapshot Lifecycle
Here is how the three touch types behave across multiple visits:
Visit 1: Google Ads click
first = { channel: "Paid Search", source: "Google" }
latest = { channel: "Paid Search", source: "Google" }
latestND = { channel: "Paid Search", source: "Google" }
Visit 2: Direct (typed URL)
first = { channel: "Paid Search", source: "Google" } -- unchanged
latest = { channel: "Direct", source: "Direct" } -- updated
latestND = { channel: "Paid Search", source: "Google" } -- preserved
Visit 3: LinkedIn organic post
first = { channel: "Paid Search", source: "Google" } -- unchanged
latest = { channel: "Organic Social", source: "LinkedIn" }
latestND = { channel: "Organic Social", source: "LinkedIn" }
Visit 4: Direct (bookmark)
first = { channel: "Paid Search", source: "Google" } -- unchanged
latest = { channel: "Direct", source: "Direct" } -- updated
latestND = { channel: "Organic Social", source: "LinkedIn" } -- preservedDirect visits update the latest touch but intentionally do not overwrite the first or latest-non-direct touches, preserving the original marketing source.
Deep Dives
Channel Detection
Full classification logic, detection priority, recognised sources, and examples for all 20+ channel groups.
Organic & Direct Traffic
How organic search is detected from referrers, how direct visits are classified, and tips to reduce untracked traffic.
Paid Traffic Detection
Click IDs, paid medium keywords, and how paid signals shift classification to paid channel variants.
Conversion Tracking
Form population, supported platforms, field mapping, dynamic form support, and conversion metadata.