0
Skip to Content
Camp Quest NorthWest
Camp Quest NorthWest
Registration
Volunteers
Life At Camp
About Us
Donate
Camp Quest NorthWest
Camp Quest NorthWest
Registration
Volunteers
Life At Camp
About Us
Donate
Registration
Volunteers
Life At Camp
About Us
Donate

Mailing Address

Camp Quest NorthWest
PO Box 18047
Tacoma, WA 98419

Information

Contact Us
Meeting MinutesCalendar
Donate

Camp Quest NorthWest is accredited by the American Camp Association.

Camp Quest NorthWest is a licensed affiliate of Camp Quest, Inc.

/** * Camp Quest Northwest A/B Testing Module * * Enhanced A/B testing infrastructure using Statsig and GA4 * Compatible with Squarespace Code Injection * * VERSION: 1.0.0 * LAST UPDATED: 2026-04-18 * * CONSTITUTION ALIGNMENT: * - Principle II: Conversion Optimization * - All pages emit metrics * - Mobile-first design */ (function() { 'use strict'; // ============================================ // CONFIGURATION // ============================================ var CQAB = window.CQAB || {}; // Statsig configuration CQAB.config = { // Your existing client API key (from Code Injection) statsigApiKey: 'client-v71t0wdZ3erybYH5gaY4zYKBvGyFdl0ZDs2CB3oDy5J', // GA4 measurement ID ga4Id: 'G-PCSSKGYTGW', // UltraCamp domain for attribution ultracampDomain: 'ultracamp.com', // Cookie expiration (days) cookieDays: 30, // Debug mode (set true to see console logs) debug: false }; // ============================================ // UTILITY FUNCTIONS // ============================================ /** * Generate or retrieve stable user ID * Uses cookies first, then sessionStorage, then generates new */ CQAB.getUserId = function() { var userId = CQAB.getCookie('cq_user_id'); if (userId) return userId; userId = sessionStorage.getItem('cq_user_id'); if (userId) { CQAB.setCookie('cq_user_id', userId, CQAB.config.cookieDays); return userId; } // Generate new ID userId = 'cq_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); sessionStorage.setItem('cq_user_id', userId); CQAB.setCookie('cq_user_id', userId, CQAB.config.cookieDays); if (CQAB.config.debug) console.log('[CQAB] New user ID:', userId); return userId; }; /** * Get cookie value */ CQAB.getCookie = function(name) { var matches = document.cookie.match(new RegExp( '(?:^|; )' + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)' )); return matches ? decodeURIComponent(matches[1]) : null; }; /** * Set cookie value */ CQAB.setCookie = function(name, value, days) { var expires = ''; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = '; expires=' + date.toUTCString(); } document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/; SameSite=Lax'; }; /** * Get variant for an experiment with persistence */ CQAB.getVariant = function(experimentName, defaultVariant) { defaultVariant = defaultVariant || 'control'; var cookieKey = 'cq_exp_' + experimentName + '_variant'; var storedVariant = CQAB.getCookie(cookieKey); if (storedVariant) return storedVariant; // Check sessionStorage as fallback var sessionVariant = sessionStorage.getItem(cookieKey); if (sessionVariant) { CQAB.setCookie(cookieKey, sessionVariant, CQAB.config.cookieDays); return sessionVariant; } // Check Statsig if available var variant = defaultVariant; try { if (window.Statsig && window.Statsig.getExperiment) { var exp = window.Statsig.getExperiment(experimentName); if (exp) { variant = exp.get('variant', defaultVariant); } } } catch (e) { if (CQAB.config.debug) console.log('[CQAB] Statsig not ready, using default'); } // Store the variant sessionStorage.setItem(cookieKey, variant); CQAB.setCookie(cookieKey, variant, CQAB.config.cookieDays); if (CQAB.config.debug) console.log('[CQAB] Variant for', experimentName, ':', variant); return variant; }; /** * Track page view with experiment attribution */ CQAB.trackPageView = function(experiments) { experiments = experiments || []; var pageViewData = { page: window.location.pathname, timestamp: new Date().toISOString(), user_id: CQAB.getUserId() }; // Add experiment variants experiments.forEach(function(exp) { pageViewData[exp.name + '_variant'] = CQAB.getVariant(exp.name, exp.default); }); // Log to GA4 if (window.gtag) { window.gtag('event', 'page_view', pageViewData); } // Log to Statsig if available if (window.statsigCore) { window.statsigCore.logEvent('page_view', pageViewData); } if (CQAB.config.debug) console.log('[CQAB] Page view tracked:', pageViewData); }; /** * Track conversion event with experiment attribution */ CQAB.trackConversion = function(goalName, value, experiments) { experiments = experiments || []; value = value || 0; var conversionData = { goal: goalName, value: value, timestamp: new Date().toISOString(), user_id: CQAB.getUserId(), page: window.location.pathname }; // Add experiment variants experiments.forEach(function(exp) { conversionData[exp.name + '_variant'] = CQAB.getVariant(exp.name, exp.default); }); // Log to GA4 if (window.gtag) { window.gtag('event', goalName, conversionData); } // Log to Statsig if available if (window.statsigCore) { window.statsigCore.logEvent('conversion_' + goalName, conversionData); } if (CQAB.config.debug) console.log('[CQAB] Conversion tracked:', conversionData); }; /** * Track exposure event (when user is assigned to a variant) */ CQAB.trackExposure = function(experimentName) { var variant = CQAB.getVariant(experimentName); if (window.gtag) { window.gtag('event', 'exp_exposure', { experiment: experimentName, variant: variant, user_id: CQAB.getUserId() }); } if (CQAB.config.debug) console.log('[CQAB] Exposure:', experimentName, variant); }; /** * Decorate UltraCamp links with experiment attribution */ CQAB.decorateUltracampLinks = function(experiments) { experiments = experiments || []; var links = document.querySelectorAll('a[href*="' + CQAB.config.ultracampDomain + '"]'); links.forEach(function(link) { // Skip if already decorated if (link.dataset.cqDecorated) return; link.dataset.cqDecorated = 'true'; // Add experiment params try { var url = new URL(link.href); experiments.forEach(function(exp) { var variant = CQAB.getVariant(exp.name, exp.default); url.searchParams.set('exp_' + exp.name, variant); }); link.href = url.toString(); } catch (e) { // Invalid URL, skip return; } // Add click listener for conversion tracking link.addEventListener('click', function() { CQAB.trackConversion('ultracamp_click', 1, experiments); }, { once: true }); }); }; /** * Run an A/B test with redirect (legacy style for /camp pages) */ CQAB.runRedirectTest = function(experimentName, variantAPath, variantBPath) { variantAPath = variantAPath || '/camp-a'; variantBPath = variantBPath || '/camp-b'; var variant = CQAB.getVariant(experimentName, 'A'); var targetPath = (variant === 'B') ? variantBPath : variantAPath; // Track exposure CQAB.trackExposure(experimentName); // Redirect if on base path if (window.location.pathname === '/camp') { window.location.replace(targetPath); } }; // ============================================ // AUTO-INITIALIZATION // ============================================ /** * Initialize when Statsig is ready */ CQAB.waitForStatsig = function(callback) { var maxAttempts = 50; var attempts = 0; var check = function() { attempts++; if (window.Statsig && window.Statsig.instance) { callback(); return; } if (attempts < maxAttempts) { setTimeout(check, 50); } }; check(); }; /** * Main initialization */ CQAB.init = function() { if (CQAB.config.debug) console.log('[CQAB] Initializing...'); // Wait for Statsig then track page view CQAB.waitForStatsig(function() { // Track page view with known experiments CQAB.trackPageView([ { name: 'camp_landing_test_1', default: 'A' } ]); // Track initial exposure CQAB.trackExposure('camp_landing_test_1'); // Decorate UltraCamp links CQAB.decorateUltracampLinks([ { name: 'camp_landing_test_1', default: 'A' } ]); }); // Also try immediately in case Statsig is already loaded if (window.Statsig && window.Statsig.instance) { CQAB.trackPageView([{ name: 'camp_landing_test_1', default: 'A' }]); CQAB.trackExposure('camp_landing_test_1'); CQAB.decorateUltracampLinks([{ name: 'camp_landing_test_1', default: 'A' }]); } }; // ============================================ // HELPERS FOR SPECIFIC TESTS // ============================================ /** * Homepage conversion test */ CQAB.homepageTest = { name: 'homepage_cta_test', variants: { control: { cta: 'Register Now', color: 'primary' }, treatment: { cta: 'Save Your Spot', color: 'accent' } }, track: function() { CQAB.trackPageView([{ name: this.name, default: 'control' }]); } }; /** * Registration page test */ CQAB.registrationTest = { name: 'registration_flow_test', variants: { control: { layout: 'single_page' }, treatment: { layout: 'wizard' } }, track: function() { CQAB.trackConversion('registration_start', 1, [{ name: this.name, default: 'control' }]); } }; /** * Donation page test */ CQAB.donationTest = { name: 'donation_amounts_test', track: function(amount) { CQAB.trackConversion('donation_made', amount || 0, [{ name: this.name, default: 'control' }]); } }; // Expose to global window.CQAB = CQAB; // Auto-init on DOM ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', CQAB.init); } else { CQAB.init(); } })();