BSP Google Tag Support

Non-Server-Side Tagging Architecture | Bright Side Plumbing | March 23, 2026

This document covers BSP client-side (non-SST) Google Tag implementation. No server-side tagging container is in use. All tags fire client-side via GTM + direct snippets.

Current Tag Architecture

GTM
GTM-M3L9374
GA4
G-R9K15PMWPR
Google Ads
AW-17179856077
Offline Upload
GCLID Pipeline

Active Tag IDs

GTM ContainerGTM-M3L9374LIVE
GA4 PropertyG-R9K15PMWPR (298578347)LIVE
Google Ads (Active)AW-17179856077 (726-955-5791)LIVE
MCC Account844-909-2450LIVE

Deactivated / Removed

AW-404985988Old Ads accountDEACTIVATED
AW-242993149Site Kit remnantDEACTIVATED
Facebook PixelRemoved Jul 2025REMOVED
HotjarRemoved Nov 2024REMOVED
HubSpot AnalyticsRemoved Oct 2025REMOVED

ServiceTitan Iframe + GTM

Can We Put GTM on the ServiceTitan Booking Iframe?

NO. The ServiceTitan scheduling iframe is a cross-origin embed. GTM cannot fire inside a third-party iframe due to browser same-origin policy. This is a fundamental browser security restriction, not a configuration issue.

What This Means

What We CAN Track

WhatHowStatus
Iframe load (page with iframe viewed)GTM page view trigger on parent pageWORKING
"Book Now" button click (opens iframe)GTM click trigger on button elementWORKING
Booking completedST webhook / API callback to NexusVIA API
GCLID passed to STNexus GCLID bridge (cookie to webhook to ST custom field)WORKING
Form submission on OUR formsGTM form submit triggerWORKING

Alternatives to Iframe GTM

  • postMessage API -- ST would need to implement window.parent.postMessage() from inside their iframe to send events to our page. ST does NOT currently support this. Would need to request from ST.
  • ST Webhooks -- When a booking is created in ST, a webhook fires to our Nexus bridge. This IS working via nexus_gclid_bridge.py on port 8503.
  • Redirect thank-you page -- If ST redirects to a callbrightside.com thank-you page after booking, we can fire a GTM conversion there. Requires ST configuration.
  • Enhanced Conversions -- EC4L captures hashed email/phone from our OWN forms, not from the ST iframe.

Conversion Actions Audit (69 Total)

CRITICAL: 69 conversion actions found. Many duplicates inflating conversion counts. Smart Bidding is optimizing against junk signals.

What Should Be PRIMARY (Real Leads)

Conversion ActionTypeCountStatus
Offline Job CompletionUPLOAD_CLICKSMANY_PER_CLICKPRIMARY
Click-to-CallWEBSITE_CALLONE_PER_CLICKPRIMARY
Website Contact Form (pick ONE)WEBPAGEONE_PER_CLICKPRIMARY
Book appointmentWEBPAGEONE_PER_CLICKPRIMARY
Lead form - SubmitLEAD_FORM_SUBMITONE_PER_CLICKPRIMARY
Calls from ads (ONE_PER_CLICK only)AD_CALLONE_PER_CLICKPRIMARY

Duplicates to Fix

ProblemActionsFix
Calls from ads x2 ENABLEDONE_PER + MANY_PER both PRIMARYRemove MANY_PER version
Clicks to call x2Both GOOGLE_HOSTED, both PRIMARYRemove one
Website Contact Form x2Both WEBPAGE, both PRIMARYRemove one
GA4 events doubled9 events have ENABLED + HIDDEN copiesDelete HIDDEN copies
ST Job Completed vs Offline JobPossible duplicate upload pipelinesClarify which is active

Junk PRIMARY Conversions (Demote to SECONDARY)

Conversion ActionWhy It Is Junk
Contact (Page load /contact)Page load is not a lead. Inflates numbers.
Local actions - Menu viewsPlumber does not have a menu.
Local actions - Website visitsMANY_PER_CLICK page view. Not a conversion.
YouTube follow-on viewsNot a lead.
Store visitsBSP does not track store visits.
Smart campaign ad clicks to callRedundant with "Calls from ads."

Legacy / Dead (Remove)

ActionReason
zzz. Book Now - Housecall Button ClickHCP removed. BSP uses ServiceTitan.
zzz. Call From Pop-UpAlready REMOVED status.
Form Submission (UA Goal)Universal Analytics sunset 2023.
Phone Call - Click to Call (UA Goal)Universal Analytics sunset 2023.
Header Call ButtonREMOVED.
12 total REMOVED actionsCleanup clutter.

GCLID Attribution Pipeline

How GCLID Flows (Non-SST)

1. Ad Click
?gclid=abc123
2. JS Capture
WP Snippet #39
3. Cookie
nexus_gclid (90d)
4. Hidden Fields
Form submission
5. Bridge
Port 8503
6. ServiceTitan
Custom field

Exclusions Required

WordPress Code Snippets (Tag-Related)

IDNamePurposeStatus
#9ST Web Scheduler WidgetServiceTitan booking iframe on 21 pagesACTIVE
#10ST Widget CSSStyling for ST booking widgetACTIVE
#22GTM + Ads TagGTM-M3L9374 + AW-17179856077 global tagACTIVE
#26Blog Template CSSBlog archive stylingACTIVE
#35Blog ArchiveBlog listing pageACTIVE
#37Blog Archive FiltersCategory filters for blogACTIVE
#39GCLID CaptureCaptures ?gclid= from URL into cookie + hidden fieldsACTIVE
#49WP Rocket ExclusionExcludes GCLID script from WP Rocket delayACTIVE

Tag Coverage

40+ pages still NOT verified with AW-17179856077. Service area pages, sewer, drain, trenchless pages need verification. Snippet #22 fires globally via Code Snippets but page-level confirmation needed.

Pages Confirmed Tagged

  • Homepage (callbrightside.com)
  • Contact page (/contact)
  • About page (/about)
  • Main service pages (~18 pages)

Pages Needing Verification

  • All service area pages (city-specific)
  • Sewer repair/replacement pages
  • Drain cleaning pages
  • Trenchless pages
  • Blog posts
  • Landing pages for Google Ads campaigns

Enhanced Conversions (EC4L)

EC4L StatusDEPLOYED (Mar 16-17)
What it capturesHashed email/phone from OUR contact forms
What it CANNOT captureData inside ST iframe (cross-origin blocked)
Offline conversions uploaded39 jobs / $54K+ (as of Mar 17)
Upload scriptnexus_offline_conversions.py on VM

Action Items for Nikhil Call

  1. Validate which conversion actions are PRIMARY -- only 6 should be primary (see table above)
  2. Remove duplicate conversions -- Calls from ads, Clicks to call, Website Contact Form all have duplicates
  3. Demote junk to SECONDARY -- Page loads, menu views, store visits, YouTube views
  4. Delete legacy UA goals -- Universal Analytics sunset in 2023
  5. Delete HIDDEN GA4 duplicates -- 9 events imported twice
  6. Confirm ST iframe limitations -- No GTM inside iframe, attribution via webhook only
  7. Verify AW-17179856077 fires on ALL pages -- 40+ pages potentially untagged
  8. Confirm offline upload pipeline -- Offline Job Completion vs ST Job Completed (API), pick one

Mar 24, 2026 -- CRITICAL TRACKING FIXES

GA4 was DARK for 7 days (Mar 17-24). Zero conversions recorded. Root cause: triple blocker discovered and removed.

Blocker 1: WPConsent Plugin

DEACTIVATED

Cookie consent banner was blocking ALL script execution until user clicked accept. Most mobile users never clicked. GA4, Google Ads, and Meta Pixel all silent.

Fix: Plugin deactivated. BSP is US-only, GDPR consent not legally required.

Blocker 2: CHEQ/ClickCease

DELETED + PAUSED

CHEQ Essentials WP plugin (installed by old agency Jun 2025) was inactive but cached ghost code. GTM Tags 35 (ClickCease, installed Mar 2025), 37, 40 (CHEQ Essentials) were active in GTM, potentially blocking conversion events.

Fix: Plugin deleted. GTM tags 35/37/40 paused in Version 45.

Blocker 3: Bot Filter Snippet #32

DEACTIVATED

Our own Code Snippet "Nexus Bot Traffic Filter for GA4" was setting window['ga-disable-G-R9K15PMWPR'] = true for detected bots. The navigator.plugins.length === 0 check was catching mobile browsers as bots.

Fix: Snippet deactivated. Need to rewrite with less aggressive bot detection.

Blocker 4: Site Kit Double-Tagging

FIXED VIA SNIPPET #52

Google Site Kit was loading its own GA4 tag (G-R9K15PMWPR) PLUS consent mode defaults that set analytics_storage: "denied". This conflicted with GTM's GA4 Configuration Tag (Tag 9). Two GA4 instances fighting for the same property.

Fix: Code Snippet #52 disables Site Kit's GA4 output. GTM is now the sole GA4 handler.

GTM Container State (Version 45)

TagNameStatusNotes
5Google Ads Conversion LinkerACTIVERequired for conversion tracking
9GA4 Configuration TagACTIVEG-R9K15PMWPR, fires on all pages
29GA4 Contact Us Form SubmitACTIVEFires on Thank You page view
30GA4 Call Button ClickACTIVEFires on tel: link clicks
35Click CeasePAUSEDOld agency, Mar 2025. Blocking conversions.
37Cheq Essentials TagPAUSEDOld agency, Jun 2025. Ghost code.
40Cheq Essentials JS DisabledPAUSEDOld agency, Jun 2025.
43Nexus GCLID + UTM CaptureACTIVECaptures click IDs for offline conversions
44GA4 generate_leadACTIVEUnified conversion tag, fires on calls + forms
45Google Ads Conversion TrackingACTIVEAW-17179856077
46Google Tag for adsACTIVEGlobal site tag
48Website Contact Form TagACTIVEAW-17179856077, element visibility trigger
49Enhanced Conversions PostMessageACTIVEListens for ST iframe data
50Meta Pixel - BSPACTIVEPixel 3167212453476317, reinstalled Mar 24

Conversion Actions (Google Ads)

ActionTypeStatusBiddable
Click-to-CallWEBSITE_CALLENABLEDPRIMARY
Calls from adsAD_CALLENABLEDPRIMARY
Submit lead formWEBPAGE_CODELESSENABLEDPRIMARY
Website Contact FormWEBPAGEENABLEDPRIMARY
ST Job Completed (API)UPLOAD_CLICKSENABLEDPRIMARY (changed Mar 24)
Website Contact Form (old)WEBPAGEENABLEDSECONDARY (demoted Mar 24, duplicate)
Map DirectionsGOOGLE_HOSTEDENABLEDSECONDARY (demoted, not a real lead)

Active Support Tickets

Ticket 2-6744000040441 (Dhina): Enhanced Conversions for Leads. Confirmed postMessage bridge approach works for ST iframe. PII must be captured via GTM tags. Tag 49 is the bridge.

Ticket 2-5436000040393 (Nikhil): Tag Implementation consultation. Response expected Mar 25. In consultation with internal team.

DEACTIVATED ACCOUNT STILL ON SITE: AW-242993149 was being loaded by Site Kit. Snippet #52 removes it. However, verify it does not reappear after Site Kit updates.

Updated March 24, 2026 10:30 PM CT | Trust Engine Verified | GTM Version 45