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

# Custom Code

> Add CSS or JavaScript to a test group of any test, so a variant can change how the page looks or behaves without a theme edit.

Custom code is CSS or JavaScript that runs for one test group, on every page the test runs on, whatever the test type.

## When to use it

* **Style a test group beyond what the editor offers.** A price test's Variant A hides the compare-at price on the blue snowboard product page with three lines of CSS.
* **Render something the theme does not have.** A shipping test's Variant A draws a free shipping bar above the header, reading the visitor's threshold from the [JavaScript API](/api-reference/browser-api).
* **Send the assignment to a tool that has no integration.** Push one event to a tag manager for the test group the visitor landed in.
* **Run a helper in every test group.** Control can carry code too, so a tracking snippet or a shared helper runs for the whole test.

## When NOT to use it

* **You want to edit text, images, or links on the page.** Use a [visual editor test](/experiments/visual-editor-test) instead. Its changes are scoped to the element, hide it until the change lands, and need no code.
* **The change belongs to one page only.** Custom code runs on every page in the test. Scope the test with [page targeting](/targeting/page-targeting) first, or use a [template test](/experiments/template-test).
* **The code changes a price, a shipping rate, or an offer.** Those are the test itself. Use a [price test](/experiments/price-test), a [shipping test](/experiments/shipping-test), or an [offer test](/experiments/offer-test), and read the result from the JavaScript API if you need to render it.

## How it works

Each test group has its own CSS and JavaScript. When a visitor lands on a page in the test, ABConvert assigns them to a test group and puts that test group's code on the page. Only the assigned test group's code runs; no other test group's code reaches that visitor.

1. The test's script resolves the visitor's test group.
2. The test group's CSS is added to the page head at once.
3. The test group's JavaScript runs at the time you chose: before the page shows, or after the page loads.

Theme, template, redirect, and visual editor tests usually decide before the page paints, so their code is on the page before anything shows. A price test, or any test that targets visitors by country, waits for the visitor's country on their first visit. During that wait the page stays hidden when a test group has CSS or JavaScript set to run before the page shows, so the visitor only sees the changed page. JavaScript set to run after the page loads never holds the page back. Shipping, offer, and checkout tests load after the page has parsed, to keep the storefront fast, so their code runs then, on the page the visitor already sees.

<Note>
  The page stays hidden for every test group, Control included, and never longer than a few seconds: if the test has not decided by then, the page shows and the code runs when it does. A page that hid only for one variant would measure the wait, not the change. If anti-flicker is turned off in your settings, the page is never hidden.
</Note>

## Setup

<Steps>
  <Step title="Open the changes step of any test">
    Open the **Custom Code** card in the step where you set up each test group.
  </Step>

  <Step title="Add code to a test group">
    Click **Add code** on a test group, and write CSS or JavaScript. Control is an ordinary test group here.
  </Step>

  <Step title="Choose when JavaScript runs">
    **Before the page shows** suits text or layout changes: visitors only see the changed page. Slow code delays the page. **After the page loads** suits tracking or popups: the page shows without waiting, and visitors may see the page change.
  </Step>
</Steps>

Try it: add `body { outline: 4px solid red }` to Variant A of a draft test, open the preview link, and switch test groups from the preview bar.

## Reading the test from your code

Custom JavaScript can read the visitor's test group, price, shipping rates, and offer through [`window.ABConvert`](/api-reference/browser-api). Push your code into `window.ABConvertQueue` and it runs once every test on the page has decided:

```js theme={null}
window.ABConvertQueue = window.ABConvertQueue || [];
window.ABConvertQueue.push(function (ABConvert) {
  var bar = document.querySelector('.shipping-bar');
  if (!bar) return;
  bar.hidden = false;
  bar.textContent = 'Free shipping on orders over $75';
});
```

See [JavaScript API examples](/api-reference/browser-api-examples) for a free shipping bar, a bundle block, and an offer banner.

## Common mistakes

* **Reading an element that is not on the page yet.** Code that runs before the page shows can run before the page has a `<body>`. Build the elements you render into inside the `window.ABConvertQueue` callback, or choose **After the page loads**.
* **Waiting for the page to load before changing what the visitor sees.** The visitor sees the original until the wait is over. Put styling in CSS, which applies before the page shows, and change an element the moment it appears, for example with a `MutationObserver`, rather than on `DOMContentLoaded`.
* **Putting the same code on every variant.** If every test group runs it, put it on Control too, or the test measures the code instead of the change.
* **Testing code only on the page you wrote it for.** Custom code runs on every page in the test. Check a collection page and the cart before launch.

## FAQ

<AccordionGroup>
  <Accordion title="Does a JavaScript error break the test?">
    No. A script that throws is reported to ABConvert and the rest of the test runs as normal. A script that does not parse is refused when you save.
  </Accordion>

  <Accordion title="Is there a size limit?">
    Each block is limited to 50,000 characters. The code is added to every page in the test, so keep it short.
  </Accordion>

  <Accordion title="Can I edit custom code on a running test?">
    No. Custom code is part of the test's setup and is locked once the test is running, like a price or a shipping rate. End the test and create a new one to change it.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.