> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abtestly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dev debugger

> window.__abtestly.debug(), the runtime's built-in explainer. Shows what happened, what fired, what did not.

When something in an experiment is not doing what you expect, the
first thing to reach for is the debugger. Runs entirely in the browser
and requires no dashboard access.

## Call it

Open DevTools on the site with the snippet installed:

```js theme={null}
window.__abtestly.debug()
```

Or, for a compact JSON blob you can paste into a bug report:

```js theme={null}
window.__abtestly.debug({ json: true })
```

## What it shows

* **Loaded experiments.** Every experiment the current config has for
  this site.
* **Assignments.** For each, whether the visitor entered the test and
  which variant they got.
* **Applied variants.** Which variants' JS and CSS actually ran on
  this page.
* **Events buffer.** The last ring buffer of events the runtime
  observed, bucketings, applies, beacons sent, activation triggers
  fired, SPA route changes.
* **Registered goals.** All goals from this site and whether each has
  fired yet in this session.

## Sensitive fields

Some fields, hashed visitor id, raw config blob, timings, are gated
on **sensitive** mode:

* **Preview mode**, sensitive fields are on by default.
* **Explicit toggle**, `localStorage.setItem('__abtestly_dev_sensitive', '1')`.

Without either, the debugger redacts sensitive fields with
`[sensitive]`. So a debug blob copied into a support ticket does not
leak anything.

## dev.apply

For prototyping:

```js theme={null}
window.__abtestly.dev.apply('experimentId')
```

Forces the variant's JS and CSS onto the current page **without**
bucketing and **without** firing any beacon. Useful for iterating on
variant code before deciding whether to launch. Ships nothing to
production.

## Event kinds in the buffer

* `config_loaded`, snippet fetched config.
* `consent_granted`, consent flipped to granted.
* `assignment`, visitor was bucketed (or not).
* `variant_applied`, variant JS/CSS applied.
* `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.
* `beacon`, a beacon was sent to `/e` or `/err`.
* `server_verdict`, preview-mode `POST /e/validate` returned the
  server's eligibility decision.

## Answering common questions

**"Why did my variant not apply?"**, check the assignment record; if
"not eligible", inspect audience rules; if bucketed but not applied,
look for a `variant_apply_error` in the buffer.

**"Why did my click goal not fire?"**, check `registered goals` in
the output; goal will be listed with its selector. Then click the
target and re-run debug to see if a `beacon` with the goal name
landed.

**"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).
