```html

Multi-Site Modal Unification & GA Tag Audit: Bringing Sailjada.com to Production Quality

What Was Done

Over the course of a focused development session, we identified and resolved a critical production issue on sailjada.com's booking experience, consolidated a fragmented modal widget across 17 subpages, and uncovered a Google Analytics ownership/tagging problem affecting two separate business units.

The core work:

  • Extracted a shared booking modal widget from queenofsandiego.com's homepage
  • Built a reusable jada-modal.js asset and refactored it into a proper IIFE (Immediately Invoked Function Expression) to avoid global scope pollution
  • Patched all 17 sailjada.com subpages to use the unified modal instead of inline, broken calendar code
  • Staged the changes in an S3 bucket + CloudFront distribution for testing before promoting to production
  • Discovered that QuickDumpNow.com (a different business) was being managed under the JADA Google account, creating GA/GSC ownership entanglement
  • Identified missing GA tags on QDN inner pages and created remediation cards

Technical Details: Modal Consolidation

Source Analysis & Extraction

The queenofsandiego.com homepage at /index.html contained a sophisticated Stripe-integrated booking modal. We mapped the modal across four source files to understand the pattern:

  • Modal trigger: CTA buttons with class .reserve-btn
  • Modal container: <div id="booking-modal"> with anchor ID references for Stripe embedded forms
  • State management: Vanilla JavaScript event listeners on modal open/close
  • Styling: Inline CSS within <style> tags, using f-strings for dynamic values
  • External dependencies: Stripe.js loaded asynchronously, Google Analytics tag (G-N6HKL4KLKT)

Key discovery: The modal's f-string templating used Python-style braces {variable}, which required careful parsing to avoid CSS brace conflicts.

Widget Extraction & IIFE Wrapping

We extracted the modal's JavaScript into /assets/js/jada-modal.js and wrapped it in an IIFE to prevent global namespace contamination:

(function() {
  // Modal open/close handlers
  // Event delegation for all .reserve-btn elements
  // Stripe form initialization
  // GA event tracking
})();

This pattern allows the script to be loaded on any page without conflicts. The IIFE exposes only necessary globals: the modal container reference and the open/close methods are internal to the closure.

Dependency Resolution

The modal depends on three external libraries loaded before the IIFE:

  • <script src="https://js.stripe.com/v3/"></script> — Stripe payment form (must load before IIFE initializes)
  • <script async src="https://www.googletagmanager.com/gtag/js?id=G-N6HKL4KLKT"></script> — Google Analytics
  • DOM availability — modal container must exist before IIFE runs

We ensured script load order in the patched subpages by placing jada-modal.js at the end of <body>, after the modal HTML.

Infrastructure: S3, CloudFront, and Staging

S3 Staging Bucket

We deployed to a separate S3 bucket for staging, with structure mirroring production:

s3://sailjada-staging/
  ├── index.html
  ├── crew/
  │   └── index.html
  ├── about/
  │   └── index.html
  ├── assets/
  │   ├── js/
  │   │   └── jada-modal.js  (new shared asset)
  │   └── css/
  └── ... (15 more subpages)

All 17 HTML files were patched to reference /assets/js/jada-modal.js instead of inline scripts.

CloudFront Distribution & Cache Invalidation

We used a staging CloudFront distribution (separate from production) to test the changes over HTTPS with the same TLS/performance characteristics as production.

Critical lesson: We initially invalidated using wildcard paths (/*), which was inefficient. We switched to granular invalidation of exact paths:

aws cloudfront create-invalidation \
  --distribution-id E1ABC2DEF34GHI \
  --paths "/crew/index.html" "/assets/js/jada-modal.js" "/about/index.html" \
  --region us-east-1

This approach reduces CloudFront processing and ensures targeted cache busting.

Production Promotion

Once staging verified correctly, we:

  1. Snapshotted the current production bucket state (for rollback ability)
  2. Synced staging bucket contents to production S3
  3. Invalidated the same 17 paths in the production CloudFront distribution (ID varies by region)
  4. Ran smoke tests against the production URL (https://sailjada.com/crew/, etc.) to verify modal functionality

GA Tag Audit: The Ownership Problem

While testing, we discovered a critical issue: QuickDumpNow.com's Google Search Console property was accessible via the JADA business account (jadasailing@gmail.com), not by QDN's own admin account.

Analysis:

  • JADA properties (sailjada.com, queenofsandiego.com) correctly use GA tag G-N6HKL4KLKT
  • QDN homepage correctly uses GA tag G-539T97NM1Z
  • However, QDN inner pages (/book, /track, /service-areas/carlsbad/) are missing the GA tag entirely
  • QDN's Google Search Console and GSC sitemap submissions are owned by jadasailing@gmail.com, not QDN's admin

This creates two problems:

  • Analytics blind spot: QDN traffic on inner pages isn't tracked, making performance analysis impossible
  • Ownership/compliance risk: JADA controls QDN's search visibility and can modify indexing rules without QDN's knowledge

We created two kanban cards to address this:

  1. t-77babced (GSC ownership transfer): Transfer quickdumpnow.com GSC property to admin@quickdumpnow.com
  2. t-77babcee (GA tag deployment on QDN inner pages): Audit and patch all QDN subpages to