window.__abtestly.debug(), the runtime’s built in explainer. Shows what the snippet decided, what applied, and what it tried to send.
When something in an experiment is not doing what you expect, the first thing
to reach for is the debugger. It runs entirely in the browser and requires no
dashboard access.
Session. Snippet version, site id, domain, SPA mode, whether GA4 is
enabled, which product analytics adapters are on, the consent mode, and
whether this page load is live or preview.
Loaded experiments. Every experiment active on this page, with the
variant assigned.
Registered goals. Every goal the snippet registered, with its selector or
condition, its state, and how many times it has fired this page load.
Event log. A ring buffer of the last 100 events the runtime observed.
Older events are dropped and the count of dropped events is reported.
The debugger observes the snippet inside your browser. That is a real and
useful record of what the snippet decided and attempted, but it is not
confirmation that anything reached your results. Three states are distinct and
worth keeping apart:
Emitted. The snippet built an event and handed it to the browser. A
beacon event in the log with wouldSend: true means exactly this.
Sent. A transport actually accepted it. The debugger records
serverStatus: 'unknown' on a normal live send, because the beacon is fire
and forget and its network outcome is never awaited.
Accepted and recorded. The ingest endpoint validated the payload, it
survived filters such as blocked IPs and visitor opt out, and it was written
to your results. The debugger never observes this.
So “the goal fired” in the debugger means the snippet’s handler ran, not that a
conversion landed in your report. To confirm the latter, check the experiment’s
results.
The debugger masks a narrow set of fields: orderId and refundId inside
a goal event’s payload. They are shown as a short prefix and the last four
characters rather than in full.Masking is lifted when you pass includeSensitive: trueand one of these
is true:
The page is in preview mode.
You have set the opt in explicitly:
localStorage.setItem('abtestly_debug_sensitive', '1').
This gate is not access control, and it does not make a debug blob safe to
share. Anyone who can open DevTools on the page can set that localStorage key
themselves, and everything outside orderId and refundId is never masked at
all. A debug blob contains your site id, your domain, your experiment and
variant names, every goal selector and URL pattern, the page path, and the
browser’s user agent.Treat the output as internal. Read it before pasting it into a support ticket
or a public issue, and do not put anything confidential into variation code,
goal selectors, experiment names, or error payloads on the assumption that the
debugger will hide it.
Treats the experiment as active for the rest of the tab session, so your
onApply callbacks fire and SPA navigations re cycle the lifecycle. It does
not bucket the visitor, does not fire a beacon, and does not inject the
variation’s CSS or JS from the dashboard. It is a flag flip for the lifecycle
hooks, meant for iterating on variant code locally.
abtestly.dev.* is for the console and userscripts only. Do not leave it in
variation code; the dashboard editor will flag it.
variant_apply_error, variant code threw. Includes message and stack.
spa_route_change, SPA navigation handled.
spa_cleanup, variant cleanup ran on route change.
spa_reapply, variant re applied on a new matching route.
spa_stale_cancelled, an async apply detected supersession and bailed.
activation_view_armed, IntersectionObserver installed for a
When visible trigger.
preview_token_rejected, a preview link’s token was refused, with the
reason. Most often the token expired or preview links were revoked.
beacon, the snippet built an event for /e or /err. Carries
wouldSend: true, and suppressedReason: 'preview' when preview mode
stopped it leaving the browser. This records the attempt, not delivery.
server_verdict, preview mode only. Preview posts the would be payload
to /e/validate, which stores nothing, and records whether the server
would have accepted it. See the note below.
/e/validate runs the same payload parse, the same beacon schema check, and
the same site lookup as the real ingest endpoint, then returns
accepted: true or a reason such as invalid_json, invalid_beacon, or
site_not_found.It stops there. It does not apply blocked IP rules, does not count the
visitor, and does not write anything to your results. A verdict of accepted
means the payload is well formed and the site resolves, not that an equivalent
live event would be recorded.If the request itself fails or is blocked, the event records
serverStatus: 'unreachable' instead.
“Why did my variant not apply?” Look for an assignment event for that
experiment. If there is none and the experiment is missing from the loaded
list, it did not match: targeting, audiences, or consent. The debugger does not
record a reason for that, so narrow it by hand against the experiment’s
Locations and Audiences. If there is an assignment but no
variant_applied, look for a variant_apply_error in the buffer.“Why did my click goal not fire?” Check registered goals in the output; the
goal is listed with its selector and state. Click the target and re run
debug() to see whether a beacon event appeared.“Why is my experiment not in the debugger at all?” The config did not
include it. Either the experiment is not live, or you are on a page that does
not match its Location, or the site does not match the snippet (wrong snippet,
wrong domain).Last verified against the shipped snippet on 2026-09-01.
Last modified on August 31, 2026
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"ABTestly","description":"ABTestly documentation: code-first A/B testing for CRO developers, agencies, and technical growth teams. Covers experiment setup, targeting, analytics integrations, and the developer API.","colors":{"primary":"#2563EB","light":"#60A5FA","dark":"#1D4FD8"},"logo":{"light":"https://mintcdn.com/abtestly/00G4YX1JcYDGimmE/logo/light.svg?fit=max\u0026auto=format\u0026n=00G4YX1JcYDGimmE\u0026q=85\u0026s=8e30c68a69d5838fd283382cc9a3041c","dark":"https://mintcdn.com/abtestly/00G4YX1JcYDGimmE/logo/dark.svg?fit=max\u0026auto=format\u0026n=00G4YX1JcYDGimmE\u0026q=85\u0026s=26be4c014a0ada510816b8a49547f52a"},"favicon":"https://mintcdn.com/abtestly/EO3uzUwEIRnQ3Ov9/favicon.svg?fit=max\u0026auto=format\u0026n=EO3uzUwEIRnQ3Ov9\u0026q=85\u0026s=c40e32c2a3477e6ce9dfe2fec2977576","background":{"color":{"light":"#f2ede1","dark":"#262935"}},"navbar":{"links":[{"href":"https://abtestly.com/pricing","label":"Pricing"},{"href":"mailto:support@abtestly.com","label":"Support"}],"primary":{"type":"button","label":"Open dashboard","href":"https://app.abtestly.com"}},"footer":{"socials":{"github":"https://github.com/abtestly"}},"seo":{"metatags":{"og:site_name":"ABTestly Documentation","og:type":"website","og:logo":"https://abtestly.com/assets/favicon.svg","og:image":"https://docs.abtestly.com/images/og-image.png","og:image:width":"1200","og:image:height":"630","og:image:alt":"ABTestly Documentation. Code-first A/B testing, documented.","twitter:card":"summary_large_image","twitter:image":"https://docs.abtestly.com/images/og-image.png","twitter:image:alt":"ABTestly Documentation. Code-first A/B testing, documented.","og:description":"ABTestly documentation: code-first A/B testing for CRO developers, agencies, and technical growth teams. Covers experiment setup, targeting, analytics integrations, and the developer API.","twitter:site":"@abtestly"},"indexing":"all"},"metadata":{"timestamp":true},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"abtestly","hasAudioNarration":false,"actualSubdomain":"abtestly","customDomains":["docs.abtestly.com"],"gitSource":{"type":"github","owner":"maaislam","repo":"abtestly-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ab639727e9a03c18a5151a1","collectionId":"07e21d16-5bbf-465a-a29a-86ea6cdb120f","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ab639727e9a03c18a5151a1"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ab639727e9a03c18a5151a1","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Read results","count":13},{"language":"default","tag":"Build a test","count":10},{"language":"default","tag":"Developer reference","count":8},{"language":"default","tag":"Methodology","count":7},{"language":"default","tag":"Site settings","count":7},{"language":"default","tag":"Signals","count":6},{"language":"default","tag":"Target the right visitors","count":6},{"language":"default","tag":"Getting started","count":5},{"language":"default","tag":"Integrations","count":5},{"language":"default","tag":"Measure","count":5}],"searchSettings":{"maxResults":10}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"signals-pipeline.css","content":"@keyframes abtPipeMergeFlow{to{stroke-dashoffset:-14}}@keyframes abtPipeBeat{0%,to{opacity:0;transform:scale(.965)}6%{opacity:.9;transform:scale(1.004)}11%{opacity:1;transform:scale(1.012)}18%{opacity:.55;transform:scale(1.022)}26%{opacity:0;transform:scale(1.032)}}@keyframes abtPipeArrowGlide{0%,26%,to{opacity:.4;transform:translateX(-3px);color:var(--ink-5)}7%{opacity:1;transform:translateX(2px);color:var(--brand)}16%{opacity:.6;transform:translateX(3px);color:var(--brand)}}@keyframes abtReturnFlow{0%,44%{top:calc(100% - 8px);opacity:0}52%{top:calc(100% - 8px);opacity:1}88%{top:0;opacity:1}95%,to{top:0;opacity:0}}@keyframes abtPlLoopBeat{0%,50%,90%,to{opacity:.45}60%,82%{opacity:.95}}@keyframes abtPlLoopDot{0%,52%{left:calc(100% - 18px);opacity:0}57%{left:calc(100% - 18px);opacity:1}80%{left:9px;opacity:1}86%,to{left:9px;opacity:0}}.abt-signals-pipeline{--canvas:#f7f3ee;--paper:#fefdfb;--paper-2:#faf8f4;--well:#f3eee8;--line:#e9e2db;--line-2:#f3eee8;--line-strong:#d8d0c5;--ink:#0d253d;--ink-2:#273951;--ink-3:#5e6d85;--ink-4:#8a93a3;--ink-5:#c9c1b4;--brand:#5e6ad2;--brand-600:#4d59c4;--brand-700:#4434d4;--brand-soft:#eceefb;--brand-soft-2:#f4f6fc;--brand-ring:rgba(94, 106, 210, 0.35);--neg:#c2410c;--neg-soft:#f6e4d9;--warn:#9b6829;--warn-ink:#7a4d18;--warn-soft:#f5e9d4;--shadow-xs:0 1px 2px rgba(13, 37, 61, 0.04);--shadow-md:0 4px 12px rgba(13, 37, 61, 0.06);--r-xs:5px;--r-sm:7px;--r-md:9px;--r-lg:11px;--r-xl:14px;--r-2xl:18px;--r-pill:999px;--t-base:160ms;--ease:cubic-bezier(0.2, 0.7, 0.2, 1);--ease-spring:cubic-bezier(0.34, 1.32, 0.46, 1);--font-sans:system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;--font-mono:ui-monospace, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;color-scheme:light;width:100%;margin:1.6rem 0}html.dark .abt-signals-pipeline{--canvas:#09101b;--paper:#191d24;--paper-2:#1e232b;--well:#15181f;--line:#272c34;--line-2:#1b1f26;--line-strong:#353c47;--ink:#e8eaee;--ink-2:#c2c7ce;--ink-3:#9298a2;--ink-4:#767d88;--ink-5:#3a4048;--brand:#7480e8;--brand-600:#8b95ef;--brand-700:#b6bdf8;--brand-soft:rgba(116, 128, 232, 0.16);--brand-soft-2:rgba(116, 128, 232, 0.08);--brand-ring:rgba(116, 128, 232, 0.45);--neg:#e79457;--neg-soft:rgba(231, 148, 87, 0.18);--warn:#d9a44c;--warn-ink:#ecc480;--warn-soft:rgba(217, 164, 76, 0.18);--shadow-xs:0 1px 2px rgba(0, 0, 0, 0.4);--shadow-md:0 4px 12px rgba(0, 0, 0, 0.5);color-scheme:dark}.abt-signals-pipeline *,.abt-signals-pipeline ::after,.abt-signals-pipeline ::before{box-sizing:border-box}.abt-signals-pipeline .audit{container-type:inline-size;border:1px solid var(--line);border-radius:var(--r-2xl);background:radial-gradient(130% 90% at 0% 0%,var(--brand-soft-2) 0%,transparent 44%),var(--paper);box-shadow:var(--shadow-md);padding:30px 30px 32px;overflow:hidden;font-family:var(--font-sans);color:var(--ink);-webkit-font-smoothing:antialiased}.abt-signals-pipeline .pipe-cap{display:flex;justify-content:space-between;gap:16px;margin-bottom:20px;flex-wrap:wrap}.abt-signals-pipeline .pipe-cap span{font-family:var(--font-mono);font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--brand-700);text-wrap:pretty}.abt-signals-pipeline .pipe-cap .r{color:var(--ink-4)}.abt-signals-pipeline .pipe-cap .r::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--ink-5)}.abt-signals-pipeline .pipe-diagram{display:flex;align-items:stretch}.abt-signals-pipeline .pipe-inputs{flex:0 0 232px;display:flex;flex-direction:column;gap:10px}.abt-signals-pipeline .pipe-inputs .pnode{flex:1;flex-direction:row;align-items:flex-start;gap:11px;padding:13px}.abt-signals-pipeline .pipe-inputs .pn-ic{margin-top:1px}.abt-signals-pipeline .pipe-inputs .pn-col{display:flex;flex-direction:column;gap:7px;min-width:0}.abt-signals-pipeline .pipe-inputs .pn-n{margin-top:2px}.abt-signals-pipeline .pipe-merge{flex:0 0 50px;align-self:stretch;color:var(--line-strong)}.abt-signals-pipeline .pipe-merge svg{width:100%;height:100%;display:block}.abt-signals-pipeline .pipe-merge .pm-v{display:none}.abt-signals-pipeline .pipe-merge path{fill:none;stroke:currentColor;stroke-width:1.5}.abt-signals-pipeline .pchain{flex:1 1 0;display:flex;align-items:center}.abt-signals-pipeline .pipe-arrow{display:flex;align-items:center;justify-content:center;color:var(--ink-5);padding:0 7px;flex:0 0 auto}.abt-signals-pipeline .pipe-arrow svg{width:19px;height:19px}.abt-signals-pipeline .pnode{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px;box-shadow:var(--shadow-xs);display:flex;flex-direction:column;gap:9px;width:100%}.abt-signals-pipeline .pn-head{display:flex;align-items:center;gap:9px}.abt-signals-pipeline .pn-ic{width:30px;height:30px;flex:none;border-radius:var(--r-sm);background:var(--brand-soft);color:var(--brand);display:grid;place-items:center}.abt-signals-pipeline .pn-ic svg{width:16px;height:16px}.abt-signals-pipeline .pn-n{font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-4)}.abt-signals-pipeline .pn-t{font-size:13.5px;font-weight:500;color:var(--ink);letter-spacing:-.01em;line-height:1.25}.abt-signals-pipeline .pn-d{font-size:11.5px;line-height:1.45;color:var(--ink-3)}.abt-signals-pipeline .pnode.is-hub{border-color:var(--brand-ring);background:linear-gradient(180deg,var(--brand-soft-2),var(--paper) 72%)}.abt-signals-pipeline .pnode.is-fals .pn-ic{background:var(--neg-soft);color:var(--neg)}.abt-signals-pipeline .pn-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:1px;min-width:0}.abt-signals-pipeline .pchain,.abt-signals-pipeline .pn-col,.abt-signals-pipeline .pn-head,.abt-signals-pipeline .pnode{min-width:0}.abt-signals-pipeline .pn-d,.abt-signals-pipeline .pn-t{overflow-wrap:anywhere;text-wrap:pretty}.abt-signals-pipeline .pn-tag{font-family:var(--font-mono);font-size:9.5px;line-height:1.45;letter-spacing:.01em;color:var(--ink-3);background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-xs);padding:2px 6px;white-space:normal;max-width:100%;overflow-wrap:anywhere}.abt-signals-pipeline .pn-tag.b{color:var(--brand-700);background:var(--brand-soft);border-color:transparent}.abt-signals-pipeline .pn-tag.q{color:var(--warn-ink);background:var(--warn-soft);border-color:transparent}.abt-signals-pipeline .pipe-foot{display:flex;justify-content:space-between;align-items:center;gap:14px 28px;flex-wrap:wrap;margin-top:20px;padding-top:16px;border-top:1px solid var(--line-2);font-family:var(--font-mono);font-size:11px;color:var(--ink-4)}.abt-signals-pipeline .pipe-cap span,.abt-signals-pipeline .pipe-foot span{display:inline-flex;align-items:center;gap:7px}.abt-signals-pipeline .pipe-foot span::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--brand);flex:none}.abt-signals-pipeline .pipe-foot b{color:var(--ink-3);font-weight:500}.abt-signals-pipeline .pipe-return{display:none}@container (max-width: 980px){.abt-signals-pipeline .pipe-diagram{flex-direction:column;gap:10px;position:relative;padding-left:38px}.abt-signals-pipeline .pipe-inputs{flex:none;flex-direction:row}.abt-signals-pipeline .pipe-inputs .pnode{flex:1 1 0}.abt-signals-pipeline .pipe-merge{flex:none;height:36px;width:100%}.abt-signals-pipeline .pipe-merge .pm-h{display:none}.abt-signals-pipeline .pipe-merge .pm-v{display:block}.abt-signals-pipeline .pchain{flex:none}.abt-signals-pipeline .pipe-arrow{padding:2px 0;transform:rotate(90deg)}.abt-signals-pipeline .pipe-return{display:block;position:absolute;left:2px;top:20px;bottom:20px;width:28px;border:2px dashed var(--brand-ring);border-right:0;border-radius:var(--r-lg) 0 0 var(--r-lg);pointer-events:none}.abt-signals-pipeline .pipe-return::after{content:'';position:absolute;top:-5px;right:-8px;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:8px solid var(--brand)}.abt-signals-pipeline .pipe-return::before{content:'';position:absolute;left:-3px;top:0;width:8px;height:8px;border-radius:50%;background:var(--brand);box-shadow:0 0 0 4px var(--brand-soft);opacity:0}}@container (max-width: 620px){.abt-signals-pipeline .pipe-inputs{flex-direction:column}}@media (prefers-reduced-motion:no-preference){.abt-signals-pipeline .audit .pipe-merge path{stroke:var(--brand);stroke-dasharray:5 9;animation:abtPipeMergeFlow 1.4s linear infinite}.abt-signals-pipeline .audit .pnode{position:relative}.abt-signals-pipeline .audit .pnode::after{content:'';position:absolute;inset:-2px;border-radius:13px;box-shadow:0 0 0 1.5px var(--brand-ring),0 12px 36px -6px var(--brand-ring);opacity:0;pointer-events:none;transform-origin:center;animation:abtPipeBeat 8.5s cubic-bezier(.37,0,.34,1) infinite}.abt-signals-pipeline .audit .pnode.is-fals::after{box-shadow:0 0 0 1.5px var(--neg),0 12px 36px -6px var(--neg-soft)}.abt-signals-pipeline .audit .pipe-inputs .pnode:nth-child(1)::after{animation-delay:0s}.abt-signals-pipeline .audit .pipe-inputs .pnode:nth-child(2)::after{animation-delay:.13s}.abt-signals-pipeline .audit .pipe-inputs .pnode:nth-child(3)::after{animation-delay:.26s}.abt-signals-pipeline .audit .pipe-diagram>.pchain:nth-child(3) .pnode::after{animation-delay:1.05s}.abt-signals-pipeline .audit .pipe-diagram>.pchain:nth-child(5) .pnode::after{animation-delay:1.95s}.abt-signals-pipeline .audit .pipe-diagram>.pchain:nth-child(7) .pnode::after{animation-delay:2.85s}.abt-signals-pipeline .audit .pipe-diagram>.pchain:nth-child(9) .pnode::after{animation-delay:3.75s}.abt-signals-pipeline .audit .pipe-arrow svg{animation:abtPipeArrowGlide 8.5s cubic-bezier(.37,0,.34,1) infinite;will-change:transform,opacity}.abt-signals-pipeline .audit .pipe-diagram>.pipe-arrow:nth-child(4) svg{animation-delay:1.5s}.abt-signals-pipeline .audit .pipe-diagram>.pipe-arrow:nth-child(6) svg{animation-delay:2.4s}.abt-signals-pipeline .audit .pipe-diagram>.pipe-arrow:nth-child(8) svg{animation-delay:3.3s}}.abt-signals-pipeline .pipe-loop{position:relative;height:54px;margin:16px 8px 2px}.abt-signals-pipeline .pl-bracket{position:absolute;left:10px;right:10px;top:13px;bottom:8px;border:2px dashed var(--brand);border-top:0;border-radius:0 0 18px 18px;opacity:.55}.abt-signals-pipeline .pl-arrow{position:absolute;left:4px;top:1px;width:0;height:0;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:11px solid var(--brand)}.abt-signals-pipeline .pl-dot{position:absolute;bottom:4px;left:calc(100% - 18px);width:9px;height:9px;border-radius:50%;background:var(--brand);box-shadow:0 0 0 4px var(--brand-soft);opacity:0;z-index:2}.abt-signals-pipeline .pl-from,.abt-signals-pipeline .pl-to{position:absolute;top:2px;font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-4);background:var(--paper);padding:0 6px}.abt-signals-pipeline .pl-from{right:12px}.abt-signals-pipeline .pl-to{left:24px}.abt-signals-pipeline .pl-tag{position:absolute;left:50%;top:46px;transform:translate(-50%,-50%);display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11.5px;color:var(--brand-700);background:var(--paper);border:1px solid var(--brand-ring);border-radius:var(--r-pill);padding:6px 14px;box-shadow:var(--shadow-xs);white-space:nowrap}.abt-signals-pipeline .pl-tag svg{width:14px;height:14px;color:var(--brand)}@container (max-width: 980px){.abt-signals-pipeline .pipe-loop{height:auto;margin-top:16px;text-align:center}.abt-signals-pipeline .pl-arrow,.abt-signals-pipeline .pl-bracket,.abt-signals-pipeline .pl-dot,.abt-signals-pipeline .pl-from,.abt-signals-pipeline .pl-to{display:none}.abt-signals-pipeline .pl-tag{position:static;transform:none;white-space:normal}}@media (prefers-reduced-motion:no-preference){.abt-signals-pipeline .pl-bracket{animation:abtPlLoopBeat 8.5s ease-in-out infinite}.abt-signals-pipeline .pl-dot{animation:abtPlLoopDot 8.5s cubic-bezier(.45,.05,.3,1) infinite}.abt-signals-pipeline .pipe-return::before{animation:abtReturnFlow 8.5s cubic-bezier(.45,.05,.3,1) infinite}}.abt-signals-pipeline a.pnode{text-decoration:none;color:inherit;cursor:pointer}.abt-signals-pipeline .pipe-diagram .pnode:focus-within,.abt-signals-pipeline .pipe-diagram .pnode:hover{border-color:var(--brand-ring);box-shadow:var(--shadow-md)}.abt-signals-pipeline .pipe-diagram .pnode:focus-visible{outline:2px solid var(--brand);outline-offset:2px}@media (prefers-reduced-motion:no-preference){.abt-signals-pipeline .pipe-diagram .pnode{transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}}.sig-anchor{display:block;height:0;scroll-margin-top:5rem}"}],"page":{"pagePath":"preview/dev-debugger","slug":"/preview/dev-debugger","pageMetadata":{"title":"Dev debugger","description":"window.__abtestly.debug(), the runtime's built in explainer. Shows what the snippet decided, what applied, and what it tried to send.","href":"/preview/dev-debugger"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"window.__abtestly.debug(), the runtime’s built in explainer. Shows what the snippet decided, what applied, and what it tried to send.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`When something in an experiment is not doing what you expect, the first thing\nto reach for is the debugger. It runs entirely in the browser and requires no\ndashboard access.`}),`\n`,_jsx(Heading,{level:`2`,id:`call-it`,children:`Call it`}),`\n`,_jsx(_components.p,{children:`Open DevTools on the site with the snippet installed:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`__abtestly`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`debug`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Or, for a compact JSON blob you can paste into a bug report:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`__abtestly`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`debug`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`json:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` })`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The same object is also reachable as `,_jsx(_components.code,{children:`window.abtestly`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-it-shows`,children:`What it shows`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Session.`}),` Snippet version, site id, domain, SPA mode, whether GA4 is\nenabled, which product analytics adapters are on, the consent mode, and\nwhether this page load is `,_jsx(_components.code,{children:`live`}),` or `,_jsx(_components.code,{children:`preview`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Loaded experiments.`}),` Every experiment active on this page, with the\nvariant assigned.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Registered goals.`}),` Every goal the snippet registered, with its selector or\ncondition, its state, and how many times it has fired this page load.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Event log.`}),` A ring buffer of the last 100 events the runtime observed.\nOlder events are dropped and the count of dropped events is reported.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-the-debugger-does-not-prove`,children:`What the debugger does not prove`}),`\n`,_jsxs(_components.p,{children:[`The debugger observes the snippet `,_jsx(_components.strong,{children:`inside your browser`}),`. That is a real and\nuseful record of what the snippet decided and attempted, but it is not\nconfirmation that anything reached your results. Three states are distinct and\nworth keeping apart:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Emitted.`}),` The snippet built an event and handed it to the browser. A\n`,_jsx(_components.code,{children:`beacon`}),` event in the log with `,_jsx(_components.code,{children:`wouldSend: true`}),` means exactly this.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Sent.`}),` A transport actually accepted it. The debugger records\n`,_jsx(_components.code,{children:`serverStatus: 'unknown'`}),` on a normal live send, because the beacon is fire\nand forget and its network outcome is never awaited.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Accepted and recorded.`}),` The ingest endpoint validated the payload, it\nsurvived filters such as blocked IPs and visitor opt out, and it was written\nto your results. `,_jsx(_components.strong,{children:`The debugger never observes this.`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`So “the goal fired” in the debugger means the snippet’s handler ran, not that a\nconversion landed in your report. To confirm the latter, check the experiment’s\nresults.`}),`\n`,_jsx(Heading,{level:`2`,id:`sensitive-fields`,children:`Sensitive fields`}),`\n`,_jsxs(_components.p,{children:[`The debugger masks a `,_jsx(_components.strong,{children:`narrow`}),` set of fields: `,_jsx(_components.code,{children:`orderId`}),` and `,_jsx(_components.code,{children:`refundId`}),` inside\na goal event’s payload. They are shown as a short prefix and the last four\ncharacters rather than in full.`]}),`\n`,_jsxs(_components.p,{children:[`Masking is lifted when you pass `,_jsx(_components.code,{children:`includeSensitive: true`}),` `,_jsx(_components.strong,{children:`and`}),` one of these\nis true:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The page is in `,_jsx(_components.strong,{children:`preview mode`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`You have set the opt in explicitly:\n`,_jsx(_components.code,{children:`localStorage.setItem('abtestly_debug_sensitive', '1')`}),`.`]}),`\n`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`__abtestly`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`debug`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`json:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`includeSensitive:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` })`})]}),`\n`]})})}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`This gate is not access control, and it does not make a debug blob safe to\nshare.`}),` Anyone who can open DevTools on the page can set that localStorage key\nthemselves, and everything outside `,_jsx(_components.code,{children:`orderId`}),` and `,_jsx(_components.code,{children:`refundId`}),` is never masked at\nall. A debug blob contains your site id, your domain, your experiment and\nvariant names, every goal selector and URL pattern, the page path, and the\nbrowser’s user agent.`]}),_jsx(_components.p,{children:`Treat the output as internal. Read it before pasting it into a support ticket\nor a public issue, and do not put anything confidential into variation code,\ngoal selectors, experiment names, or error payloads on the assumption that the\ndebugger will hide it.`})]}),`\n`,_jsx(Heading,{level:`2`,id:`dev-apply`,children:`dev.apply`}),`\n`,_jsx(_components.p,{children:`For prototyping:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`abtestly`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`dev`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`apply`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'experimentId'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Treats the experiment as active for the rest of the tab session, so your\n`,_jsx(_components.code,{children:`onApply`}),` callbacks fire and SPA navigations re cycle the lifecycle. It does\n`,_jsx(_components.strong,{children:`not`}),` bucket the visitor, does not fire a beacon, and does not inject the\nvariation’s CSS or JS from the dashboard. It is a flag flip for the lifecycle\nhooks, meant for iterating on variant code locally.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`abtestly.dev.*`}),` is for the console and userscripts only. Do not leave it in\nvariation code; the dashboard editor will flag it.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`event-kinds-in-the-buffer`,children:`Event kinds in the buffer`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`config_loaded`}),`, snippet fetched config.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`consent_granted`}),`, consent flipped to granted.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`assignment`}),`, visitor was bucketed (or not).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`variant_applied`}),`, variant JS/CSS applied.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`variant_apply_error`}),`, variant code threw. Includes message and stack.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`spa_route_change`}),`, SPA navigation handled.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`spa_cleanup`}),`, variant cleanup ran on route change.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`spa_reapply`}),`, variant re applied on a new matching route.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`spa_stale_cancelled`}),`, an async apply detected supersession and bailed.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`activation_view_armed`}),`, `,_jsx(_components.code,{children:`IntersectionObserver`}),` installed for a\n`,_jsx(_components.strong,{children:`When visible`}),` trigger.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`preview_token_rejected`}),`, a preview link’s token was refused, with the\nreason. Most often the token expired or preview links were revoked.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`beacon`}),`, the snippet built an event for `,_jsx(_components.code,{children:`/e`}),` or `,_jsx(_components.code,{children:`/err`}),`. Carries\n`,_jsx(_components.code,{children:`wouldSend: true`}),`, and `,_jsx(_components.code,{children:`suppressedReason: 'preview'`}),` when preview mode\nstopped it leaving the browser. This records the attempt, not delivery.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`server_verdict`}),`, `,_jsx(_components.strong,{children:`preview mode only`}),`. Preview posts the would be payload\nto `,_jsx(_components.code,{children:`/e/validate`}),`, which stores nothing, and records whether the server\n`,_jsx(_components.strong,{children:`would have accepted`}),` it. See the note below.`]}),`\n`]}),`\n`,_jsxs(Heading,{level:`3`,id:`what-server_verdict-actually-checks`,children:[`What `,_jsx(_components.code,{children:`server_verdict`}),` actually checks`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`/e/validate`}),` runs the same payload parse, the same beacon schema check, and\nthe same site lookup as the real ingest endpoint, then returns\n`,_jsx(_components.code,{children:`accepted: true`}),` or a reason such as `,_jsx(_components.code,{children:`invalid_json`}),`, `,_jsx(_components.code,{children:`invalid_beacon`}),`, or\n`,_jsx(_components.code,{children:`site_not_found`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`It stops there. It does `,_jsx(_components.strong,{children:`not`}),` apply blocked IP rules, does not count the\nvisitor, and does not write anything to your results. A verdict of `,_jsx(_components.code,{children:`accepted`}),`\nmeans the payload is well formed and the site resolves, not that an equivalent\nlive event would be recorded.`]}),`\n`,_jsxs(_components.p,{children:[`If the request itself fails or is blocked, the event records\n`,_jsx(_components.code,{children:`serverStatus: 'unreachable'`}),` instead.`]}),`\n`,_jsx(Heading,{level:`2`,id:`answering-common-questions`,children:`Answering common questions`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`“Why did my variant not apply?”`}),` Look for an `,_jsx(_components.code,{children:`assignment`}),` event for that\nexperiment. If there is none and the experiment is missing from the loaded\nlist, it did not match: targeting, audiences, or consent. The debugger does not\nrecord a reason for that, so narrow it by hand against the experiment’s\nLocations and Audiences. If there `,_jsx(_components.strong,{children:`is`}),` an assignment but no\n`,_jsx(_components.code,{children:`variant_applied`}),`, look for a `,_jsx(_components.code,{children:`variant_apply_error`}),` in the buffer.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`“Why did my click goal not fire?”`}),` Check registered goals in the output; the\ngoal is listed with its selector and state. Click the target and re run\n`,_jsx(_components.code,{children:`debug()`}),` to see whether a `,_jsx(_components.code,{children:`beacon`}),` event appeared.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`“Why is my experiment not in the debugger at all?”`}),` The config did not\ninclude it. Either the experiment is not live, or you are on a page that does\nnot match its Location, or the site does not match the snippet (wrong snippet,\nwrong domain).`]}),`\n`,_jsx(_components.p,{children:`Last verified against the shipped snippet on 2026-09-01.`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Dev debugger","description":"window.__abtestly.debug(), the runtime's built in explainer. Shows what the snippet decided, what applied, and what it tried to send.","href":"/preview/dev-debugger"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Call it","slug":"call-it","depth":2,"children":[]},{"title":"What it shows","slug":"what-it-shows","depth":2,"children":[]},{"title":"What the debugger does not prove","slug":"what-the-debugger-does-not-prove","depth":2,"children":[]},{"title":"Sensitive fields","slug":"sensitive-fields","depth":2,"children":[]},{"title":"dev.apply","slug":"dev-apply","depth":2,"children":[]},{"title":"Event kinds in the buffer","slug":"event-kinds-in-the-buffer","depth":2,"children":[{"title":"What server_verdict actually checks","slug":"what-server_verdict-actually-checks","depth":3,"children":[]}]},{"title":"Answering common questions","slug":"answering-common-questions","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/abtestly/2b7ba09c10a131d7/chat-widget.js","/_mintlify/custom/abtestly/99bdab09a5894d14/consent.js","/_mintlify/custom/abtestly/247c45f8fadb8f9c/docs-code-copy.js","/_mintlify/custom/abtestly/8b522d54658179ab/ga4-init.js"],"subdomain":"abtestly","siteName":"ABTestly","title":"Dev debugger - ABTestly","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-01T01:54:18.558Z","gitLastModified":"2026-08-31T23:13:15.000Z","originalFileLocation":"preview/dev-debugger.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"window.__abtestly.debug(), the runtime\u0026#x27;s built in explainer. Shows what the snippet decided, what applied, and what it tried to send.\">\u003cmeta data-mint-head name=\"application-name\" content=\"ABTestly\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Dev debugger - ABTestly\">\u003cmeta data-mint-head property=\"og:description\" content=\"ABTestly documentation: code-first A/B testing for CRO developers, agencies, and technical growth teams. Covers experiment setup, targeting, analytics integrations, and the developer API.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"ABTestly Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.abtestly.com/preview/dev-debugger\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://docs.abtestly.com/images/og-image.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Dev debugger - ABTestly\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"ABTestly documentation: code-first A/B testing for CRO developers, agencies, and technical growth teams. Covers experiment setup, targeting, analytics integrations, and the developer API.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://docs.abtestly.com/images/og-image.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/abtestly/8M9DcmNH08KxZUPp/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"ABTestly\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2563EB\">\u003cmeta data-mint-head name=\"og:logo\" content=\"https://abtestly.com/assets/favicon.svg\">\u003cmeta data-mint-head name=\"og:image:alt\" content=\"ABTestly Documentation. Code-first A/B testing, documented.\">\u003cmeta data-mint-head name=\"twitter:image:alt\" content=\"ABTestly Documentation. Code-first A/B testing, documented.\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.abtestly.com/preview/dev-debugger\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/preview/dev-debugger.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.abtestly.com/#organization\",\"name\":\"ABTestly\",\"url\":\"https://docs.abtestly.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/abtestly/00G4YX1JcYDGimmE/logo/light.svg?fit=max\u0026auto=format\u0026n=00G4YX1JcYDGimmE\u0026q=85\u0026s=8e30c68a69d5838fd283382cc9a3041c\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.abtestly.com#website\",\"name\":\"ABTestly\",\"url\":\"https://docs.abtestly.com\",\"publisher\":{\"@id\":\"https://docs.abtestly.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.abtestly.com/preview/dev-debugger#webpage\",\"url\":\"https://docs.abtestly.com/preview/dev-debugger\",\"name\":\"Dev debugger\",\"description\":\"window.__abtestly.debug(), the runtime's built in explainer. Shows what the snippet decided, what applied, and what it tried to send.\",\"dateModified\":\"2026-08-31T23:13:15.000Z\",\"isPartOf\":{\"@id\":\"https://docs.abtestly.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.abtestly.com/preview/dev-debugger#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.abtestly.com/preview/dev-debugger#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Preview \u0026 QA\",\"item\":\"https://docs.abtestly.com/preview/preview-modal\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dev debugger\",\"item\":\"https://docs.abtestly.com/preview/dev-debugger\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.abtestly.com/preview/dev-debugger#article\",\"headline\":\"Dev debugger\",\"name\":\"Dev debugger\",\"description\":\"window.__abtestly.debug(), the runtime's built in explainer. Shows what the snippet decided, what applied, and what it tried to send.\",\"url\":\"https://docs.abtestly.com/preview/dev-debugger\",\"mainEntityOfPage\":{\"@id\":\"https://docs.abtestly.com/preview/dev-debugger#webpage\"},\"image\":\"https://docs.abtestly.com/images/og-image.png\",\"dateModified\":\"2026-08-31T23:13:15.000Z\",\"publisher\":{\"@id\":\"https://docs.abtestly.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.abtestly.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"ABTestly\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"ABTestly","nav":{"global":null,"groups":[{"group":"Getting started","pages":[{"title":"ABTestly Documentation: Code-first A/B Testing","sidebarTitle":"Introduction","href":"/introduction"},{"title":"Run your first A/B test in about fifteen minutes","sidebarTitle":"Quickstart","href":"/quickstart"},{"title":"How ABTestly works","href":"/concepts/how-it-works"},{"title":"Documentation index","href":"/index"},{"title":"Documentation changelog","href":"/changelog"}]},{"group":"Install","pages":[{"title":"Install the snippet","href":"/install/snippet"},{"title":"Verify the snippet is working","href":"/install/verify"},{"title":"Single-page apps","href":"/install/spa"},{"title":"Consent \u0026 deferred mode","href":"/install/consent"},{"title":"Visitor opt-out","href":"/install/opt-out"}]},{"group":"Build a test","pages":[{"title":"Create an experiment","href":"/build/create"},{"title":"JavaScript and CSS variations","sidebarTitle":"Variations","href":"/build/variations"},{"title":"Review changes before you save","sidebarTitle":"Review changes","href":"/build/review-changes"},{"title":"Code history","href":"/build/code-history"},{"title":"Code check","href":"/build/code-check"},{"title":"Dev libraries","href":"/build/dev-libraries"},{"title":"Split URL redirect tests","sidebarTitle":"Redirect tests","href":"/build/redirect-tests"},{"title":"Clone an experiment","href":"/build/clone"},{"title":"Schedule an experiment","href":"/build/schedule"},{"title":"Autosave and drafts","href":"/build/autosave"}]},{"group":"Target the right visitors","pages":[{"title":"Targeting overview","href":"/targeting/overview"},{"title":"URL rules","href":"/targeting/url-rules"},{"title":"Audiences","href":"/targeting/audiences"},{"title":"Geo targeting","href":"/targeting/geo"},{"title":"Saved Locations \u0026 Audiences","href":"/targeting/saved-lists"},{"title":"Activation triggers","href":"/targeting/activation-triggers"}]},{"group":"Mutual exclusion groups","pages":[{"title":"Exclusion groups overview","href":"/exclusion-groups/overview"},{"title":"How allocation works","href":"/exclusion-groups/how-it-works"},{"title":"Long-term holdouts","href":"/exclusion-groups/holdouts"},{"title":"Managing membership","href":"/exclusion-groups/managing"}]},{"group":"Measure","pages":[{"title":"A/B test goals in ABTestly","sidebarTitle":"Goals overview","href":"/goals/overview"},{"title":"A/B test conversion goals: clicks, forms, revenue and custom events","sidebarTitle":"Goal types","href":"/goals/types"},{"title":"System default goals","sidebarTitle":"System defaults","href":"/goals/system-defaults"},{"title":"A/B test guardrail metrics and primary goals","sidebarTitle":"Primary vs guardrail","href":"/goals/primary-vs-guardrail"},{"title":"A/B test goal tracking health","sidebarTitle":"Goal firing health","href":"/goals/health"}]},{"group":"Read results","pages":[{"title":"Reading a result","href":"/results/reading-a-result"},{"title":"The three statistics engines","href":"/results/engines"},{"title":"Revenue metrics","href":"/results/revenue-metrics"},{"title":"Segments","href":"/results/segments"},{"title":"Change the baseline","href":"/results/baseline"},{"title":"Time to decision","href":"/results/time-to-decision"},{"title":"Business impact projection","href":"/results/business-impact"},{"title":"Compare LCP between A/B test variants","sidebarTitle":"Speed guardrail","href":"/results/speed-guardrail"},{"title":"The Exact Experiment Ledger","href":"/results/exact-ledger"},{"title":"Detect sample ratio mismatch and broken experiment allocation","sidebarTitle":"Sample ratio mismatch","href":"/results/srm"},{"title":"Editing a running A/B test without invalidating the results","sidebarTitle":"Editing a running test","href":"/results/editing-a-running-test"},{"title":"What the affected page loads count on your results means","sidebarTitle":"Variation errors","href":"/results/variation-errors"},{"title":"Exports","href":"/results/exports"}]},{"group":"Methodology","pages":[{"title":"Methodology","sidebarTitle":"Overview","href":"/methodology/overview"},{"title":"Underneath the statistics","sidebarTitle":"Underneath the statistics","href":"/methodology/underneath-the-statistics"},{"title":"Minimum detectable effect","sidebarTitle":"Minimum detectable effect","href":"/methodology/minimum-detectable-effect"},{"title":"Test duration","sidebarTitle":"Test duration","href":"/methodology/test-duration"},{"title":"The peeking problem","sidebarTitle":"Peeking","href":"/methodology/peeking"},{"title":"Confidence intervals","sidebarTitle":"Confidence intervals","href":"/methodology/confidence-intervals"},{"title":"Sample ratio mismatch","sidebarTitle":"Sample ratio mismatch","href":"/methodology/sample-ratio-mismatch"}]},{"group":"Signals","pages":[{"title":"Signals overview","href":"/signals/overview"},{"title":"Scan a page","href":"/signals/scan-a-page"},{"title":"Connect Google Analytics","href":"/signals/connect-google-analytics"},{"title":"Prioritize A/B test ideas: PXL scores and evidence","sidebarTitle":"Read a scan","href":"/signals/read-a-scan"},{"title":"Signals evidence contract","href":"/signals/evidence-contract"},{"title":"Build a test from an idea","href":"/signals/build-a-test"}]},{"group":"Preview \u0026 QA","pages":[{"title":"Preview links","href":"/preview/preview-modal"},{"title":"Forced variation","href":"/preview/forced-variation"},{"title":"QA session links and the QA overlay","sidebarTitle":"QA session links","description":"The QA Overlay tab issues a site wide QA session link today. The on page overlay panel itself has not shipped yet.","href":"/preview/qa-overlay"},{"title":"Dev debugger","href":"/preview/dev-debugger"}]},{"group":"Site settings","pages":[{"title":"General settings","description":"The site-wide knobs. Name, domain, project timezone, currency, default statistics engine.","href":"/settings/general"},{"title":"Snippet panel","href":"/settings/snippet-panel"},{"title":"Analytics adapters","href":"/settings/analytics-adapters"},{"title":"SPA support panel","href":"/settings/spa-panel"},{"title":"Global JS","href":"/settings/global-js"},{"title":"Blocked IPs","href":"/settings/blocked-ips"},{"title":"Danger zone","href":"/settings/danger-zone"}]},{"group":"Team \u0026 access","pages":[{"title":"Members and roles","href":"/team/members-and-roles"},{"title":"Permissions catalog","href":"/team/permissions-catalog"},{"title":"Activity log","href":"/team/activity-log"}]},{"group":"Assets","pages":[{"title":"Upload an asset","href":"/assets/upload"},{"title":"How assets are served","href":"/assets/serving"},{"title":"Recycle bin","href":"/assets/recycle-bin"}]},{"group":"Integrations","pages":[{"title":"GA4 dataLayer integration","href":"/integrations/ga4-datalayer"},{"title":"GA4 export","href":"/ga4-export"},{"title":"GA4 BigQuery analysis","href":"/ga4-bigquery"},{"title":"Product analytics","href":"/product-analytics"},{"title":"Google Tag Manager","href":"/integrations/gtm"}]},{"group":"Billing","pages":[{"title":"ABTestly plans: limits, upgrades, downgrades and cancellation","sidebarTitle":"Plans \u0026 pricing","href":"/plans"},{"title":"The 14 day free trial","href":"/billing/trial"},{"title":"What is a Monthly Tracked User (MTU)","href":"/billing/mtu"},{"title":"Refunds and cancellation","href":"/billing/refunds"}]},{"group":"Trust \u0026 compliance","pages":[{"title":"Trust and compliance","href":"/trust-and-compliance"}]},{"group":"Developer reference","pages":[{"title":"window.abtestly API","href":"/developer/window-abtestly-api"},{"title":"REST API","href":"/developer/rest-api"},{"title":"Beacon protocol","href":"/developer/beacon-protocol"},{"title":"Bucketing model","href":"/developer/bucketing"},{"title":"Runtime bindings","href":"/developer/runtime-bindings"},{"title":"SPA lifecycle","href":"/developer/spa-lifecycle"},{"title":"Errors and telemetry","href":"/developer/errors-and-telemetry"},{"title":"Rate limits","href":"/developer/rate-limits"}]},{"group":"Troubleshooting","pages":[{"title":"ABTestly Script Not Working: Installation Troubleshooting","sidebarTitle":"Snippet not firing","href":"/troubleshooting/snippet-not-firing"},{"title":"Why A/B Test Results Look Wrong: SRM, Revenue and Attribution","sidebarTitle":"Numbers look wrong","href":"/troubleshooting/numbers-look-off"},{"title":"Troubleshoot CMP Consent and Deferred A/B Testing","sidebarTitle":"Consent not granting","href":"/troubleshooting/consent-stuck"},{"title":"Exclude Internal and QA Traffic from A/B Tests","sidebarTitle":"Own visits blocked","href":"/troubleshooting/blocked-ip"},{"title":"A/B Testing Diagnostic Reference: Error Codes and Debug Report","sidebarTitle":"Diagnostic reference","href":"/troubleshooting/diagnostic-reference"}]}]},"title":"Dev debugger - ABTestly","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":[],"chunks":[]}