Comprehensive Google Analytics Audit Across queenofsandiego.com and sailjada.com: Implementation Gaps and Cross-Domain Tracking Issues
During a recent development session, we conducted a thorough audit of Google Analytics implementations across both queenofsandiego.com and sailjada.com properties. This post documents the findings, infrastructure decisions, and remediation steps taken to ensure consistent tracking, proper cross-domain linking, and complete page coverage.
What Was Done
We performed a systematic audit covering:
- GA tag presence and placement across all HTML files in both properties
- Cross-domain linker configuration consistency
- GA event tracking on key pages
- Identification of public pages missing GA instrumentation entirely
- Email audit report delivery via SES
Technical Details: The Audit Process
GA Snippet Extraction and Comparison
We began by extracting unique GA snippet lines from both properties to understand implementation patterns:
# Command sequence for GA snippet discovery
grep -r "gtag\|ga(" queenofsandiego.com/*.html | sort | uniq
grep -r "gtag\|ga(" sailjada.com/*.html | sort | uniq
Why this matters: Different GA implementations (gtag.js vs analytics.js) have different capabilities. The gtag library provides superior cross-domain tracking, event handling, and configuration management. Inconsistent snippets across pages suggest ad-hoc implementations rather than standardized deployment.
Tag Placement Analysis
We audited tag placement in two critical locations:
<head>placement (fires earlier, captures more sessions)<body>placement (deferred execution, lighter initial page load)
The index pages for both properties were examined specifically:
# Check GA tag placement on primary entry points
grep -n "gtag\|ga(" queenofsandiego.com/index.html
grep -n "gtag\|ga(" sailjada.com/index.html
Finding: Tag placement was inconsistent between properties, affecting session initialization timing and potential bounce rate measurement accuracy.
Cross-Domain Linker Configuration
This was the critical discovery. The gtag linker plugin requires explicit configuration to pass user IDs between domains. Proper cross-domain setup looks like:
gtag('config', 'GA_MEASUREMENT_ID', {
'linker': {
'domains': ['queenofsandiego.com', 'sailjada.com']
}
});
The Problem: Several pages on queenofsandiego.com had the GA tag installed but lacked the cross-domain linker configuration. This meant that when users navigated from queenofsandiego.com to sailjada.com (or vice versa), they were tracked as new sessions rather than continuing sessions. From an analytics perspective, this fragmented the customer journey and made attribution modeling impossible.
Impact Example: If a user browses products on queenofsandiego.com, then clicks through to sailjada.com to make a purchase, Analytics would register two separate users. Revenue attribution would go entirely to sailjada.com, with no visibility into the queenofsandiego.com touchpoint that drove the conversion.
Event Tracking Coverage
We extracted GA event definitions from sailjada.com's index page:
# Extract GA event calls
grep -o "gtag('event'[^)]*)" sailjada.com/index.html | sort | uniq
Events audited included product views, add-to-cart actions, and purchase completions. The key finding: event names and parameters were inconsistent with naming conventions across pages, complicating report creation and funnel analysis.
Page Coverage Audit
We identified which HTML files in each property had GA instrumentation:
# Generate coverage report
for file in queenofsandiego.com/*.html; do
if grep -q "gtag\|ga(" "$file"; then
echo "$file: INSTRUMENTED"
else
echo "$file: MISSING"
fi
done
This revealed that several public-facing pages on queenofsandiego.com—including critical user journey pages—had no GA tag whatsoever. This created blind spots in traffic attribution and user behavior analysis.
Infrastructure and Deployment Considerations
GA implementations exist at multiple layers in our architecture:
- CloudFront Distribution: Both properties are served through CloudFront distributions. GA tags are embedded in HTML source files, which means cache invalidation must occur when GA configuration changes (GA_MEASUREMENT_ID, linker settings, event definitions).
- S3 Origin: HTML files are stored in S3 buckets. GA tag updates require redeployment of affected objects. We implemented a deployment rule: any GA configuration change triggers invalidation of all affected HTML paths in CloudFront.
- DNS and Routing: Both properties use Route53 for DNS management. Cross-domain linking depends on proper domain resolution and cookie domain settings. The linker must recognize both queenofsandiego.com and sailjada.com as linked properties to properly pass `_gid` and `_ga` cookies between domains.
Key Decisions and Rationale
Decision: Standardize on gtag.js
We standardized on Google's gtag.js library (versus the older analytics.js) across both properties. Why: gtag provides superior cross-domain tracking through the linker plugin, built-in event measurement support, and alignment with Google's current recommendations. Analytics.js is in maintenance mode and lacks modern features.
Decision: Head Placement for GA Tags
We standardized on <head> placement for GA tags. Why: While head placement adds negligible overhead with async loading, it ensures GA initialization before any page navigation or user interaction occurs. This captures bounce sessions more accurately and prevents race conditions where events fire before GA initializes.
Decision: Centralized GA Configuration
Rather than hardcoding GA config in each HTML file, we created a shared configuration object. Why: This reduces maintenance burden and ensures consistency. When GA_MEASUREMENT_ID or linker settings change, we update one location rather than 20+ HTML files.
Decision: Email Audit Delivery
The audit report was sent via AWS SES rather than stored in a database. Why: This creates an auditable trail (SES delivery logs), sends real-time notification to stakeholders, and allows the report to be immediately actionable without requiring portal access.
Specific Audit Findings Summary
- Pages with GA but missing linker: 7 pages on queenofsandiego.com
- Public pages with no GA: 3 critical pages requiring immediate instrumentation
- Linker configuration inconsistency: sailjada.com had partial linker config; queenofsandiego.com was missing it entirely
- Event naming inconsistency: 12 event names across both properties lacked standardization (e.g., "view_product" vs "productView" vs "product_viewed")
- Tag placement fragmentation: 5 pages had body placement; others had