waitForElement Resolve a promise once a selector exists, with a timeout safety net.
javascript Copy
function waitForElement(selector, { root = document.body, timeout = 8000 } = {}) {
return new Promise((resolve, reject) => {
const found = root.querySelector(selector);
if (found) return resolve(found);
const obs = new MutationObserver(() => {
const el = root.querySelector(selector);
if (el) { obs.disconnect(); resolve(el); }
});
obs.observe(root, { childList: true, subtree: true });
setTimeout(() => { obs.disconnect(); reject(new Error('Timeout: ' + selector)); }, timeout);
});
}onRouteChange (MutationObserver) Re-run your variant code when an SPA changes route without a full page load.
javascript Copy
function onRouteChange(callback) {
let last = location.pathname + location.search;
const fire = () => {
const now = location.pathname + location.search;
if (now !== last) { last = now; callback(now); }
};
new MutationObserver(fire).observe(document.body, { childList: true, subtree: true });
window.addEventListener('popstate', fire);
}WTO goal tracking Fire a Webtrends Optimize goal when the conversion event happens.
javascript Copy
function trackWtoGoal(goalId) {
if (window.wt_sdc_namespace && window.wt_sdc_namespace.dcsMultiTrack) {
window.wt_sdc_namespace.dcsMultiTrack(
'DCS.dcsuri', '/goal/' + goalId,
'WT.ti', 'Experiment Goal: ' + goalId
);
}
}GA4 event tracking Send a custom event to GA4 with experiment + variant labels.
javascript Copy
function trackGa4(eventName, params = {}) {
if (typeof window.gtag !== 'function') return;
window.gtag('event', eventName, {
experiment_id: params.experimentId,
variant_id: params.variantId,
...params,
});
}Variant assignment from cookie Persist a 50/50 split per visitor using a first-party cookie.
javascript Copy
function assignVariant(experimentId) {
const key = 'exp_' + experimentId;
const existing = document.cookie.split('; ').find((c) => c.startsWith(key + '='));
if (existing) return existing.split('=')[1];
const variant = Math.random() < 0.5 ? 'control' : 'v1';
const oneYear = 60 * 60 * 24 * 365;
document.cookie = key + '=' + variant + '; path=/; max-age=' + oneYear + '; SameSite=Lax; Secure';
return variant;
}Anti-flicker shield Hide the testable region for up to 4s, lift on variant apply or timeout.
javascript Copy
(function antiFlicker(){
const style = document.createElement('style');
style.id = 'wto-anti-flicker';
style.textContent = '.wto-hide { opacity: 0 !important; transition: opacity .2s; }';
document.head.appendChild(style);
document.documentElement.classList.add('wto-hide');
const lift = () => document.documentElement.classList.remove('wto-hide');
window.__liftAntiFlicker = lift;
setTimeout(lift, 4000);
})();