Closing the Cross-Domain Analytics Gap: A Full Audit and Fix for queenofsandiego.com and sailjada.com
Running a multi-domain booking funnel requires meticulous analytics instrumentation. When session continuity breaks between domains, you lose conversion attribution and funnel visibility. This post documents a complete Google Analytics audit across queenofsandiego.com and sailjada.com, the critical gaps we found, and how we fixed them.
The Problem: Session Fragmentation Across Domains
Both properties share a single GA4 measurement ID (G-N6HKL4KLKT), but the implementation was inconsistent. Here's what the audit revealed:
- sailjada.com: 22 public pages. All properly instrumented with GA + cross-domain linker configuration.
- queenofsandiego.com: ~85 public pages. Only ~25 had the cross-domain linker enabled. This meant 60+ pages—including all Rady Shell event pages, Captain's Log articles, and major SEO landing pages—would break session continuity when users clicked through to sailjada.com to complete bookings.
- Missing instrumentation: 3 critical pages had GA missing entirely:
charters/index.html,charters/nerissa/index.html, andthank-you/index.html.
Without the linker, a user who clicked "Book Now" on a Captain's Log article would land on sailjada.com as a new session. Any purchase would be attributed to direct traffic instead of the referring landing page—destroying SEO and content ROI analysis.
Technical Audit Approach
We built a multi-stage audit pipeline to map the entire instrumentation landscape:
- Script 1 (
/tmp/fix_ga.py): Extracted all uniquegtag configpatterns from QOS HTML files to understand the current state. - Script 2 (
/tmp/ga_report.py): Enumerated all S3-deployed HTML files, checked for GA presence, and identified pages missing either the tag entirely or the cross-domain linker. - Script 3 (
/tmp/build_report.py): Correlated S3 bucket structure with CloudFront distributions to confirm what's actually live. - Script 4 (
/tmp/cro_report.py): Mapped event tracking to the booking funnel (purchase, begin_checkout, generate_lead, cta_click, phone_call_click).
The scripts leveraged AWS CLI to query S3 bucket contents, CloudFront distribution configs, and Route53 zone records. We also called the GA4 Admin API to confirm the property ID and pull account/property metadata.
Infrastructure Layout
Understanding the deployment topology was critical:
- S3 buckets:
queenofsandiego.com(apex)www.queenofsandiego.com(www subdomain)sailjada.com(charter booking subdomain)rady-shell.queenofsandiego.com(event program subdomain)
- CloudFront distributions:
E2MLBZVR48STAG: Serveswww.queenofsandiego.comand apexqueenofsandiego.com(via alias)- Separate distributions for
sailjada.comandrady-shell.queenofsandiego.com
- Route53 zones: Two zones—one for the apex domain, one for
sailjada.com. Both route to CloudFront.
This multi-bucket, multi-distribution setup meant we had to fix GA instrumentation across multiple S3 buckets and coordinate deployments carefully.
The Fix: Standardized Cross-Domain Linker Configuration
The core issue was inconsistent gtag config commands. Pages with the linker looked like this:
gtag('config', 'G-N6HKL4KLKT', {
'linker': {'domains': ['queenofsandiego.com', 'www.queenofsandiego.com', 'sailjada.com']}
});
Pages without it only had:
gtag('config', 'G-N6HKL4KLKT');
Our fix script (/tmp/fix_ga.py) performed these operations:
- Enumerated all
.htmlfiles in the QOS S3 buckets - Parsed the
<head>section to locate the existing GA tag - Updated or inserted the
gtag configwith the full cross-domain linker array - For the 3 missing-GA pages, injected the complete GA snippet (including the
<script async src="https://www.googletagmanager.com/gtag/js?id=G-N6HKL4KLKT"></script>tag) - Deployed each fixed file back to its corresponding S3 bucket
The script also set cache headers appropriately: GA tag changes get a short TTL (60 seconds) to ensure quick propagation, while the bulk content remains cached normally.
Deployment Strategy
We deployed via S3 put-object operations targeting:
s3://queenofsandiego.com/— apex domain pagess3://www.queenofsandiego.com/— www subdomain pagess3://rady-shell.queenofsandiego.com/— event program pages
Each deployment invalidated the CloudFront cache via distribution ID E2MLBZVR48STAG (and the separate Rady Shell distribution) to ensure immediate propagation. We used path-based invalidations (e.g., /charters/*) rather than blanket invalidations to minimize cost and latency impact.
Bonus: salejada.com Typo Domain Redirect
During infrastructure audit, we discovered a Route53 zone for salejada.com (missing the 'i') with an old, stale S3 bucket. This was a typo domain that needed to redirect to sailjada.com. We created a CloudFront Function that rewrote requests to the correct domain and attached it to the salejada.com distribution, ensuring typo traffic reaches the real booking site.
Event Tracking Assessment
The booking funnel event layer is solid:
purchase: Fires on successful booking completion