> ## 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.

# Preview links

> See any variant on your live site before you launch — without affecting your test data. Preview drafts, respect targeting, and share a link with your team.

A preview link opens your real site with one specific variant rendered —
exactly as a matching visitor would see it — **without starting the test and
without recording any data**. Use it to QA a change before you launch, to
sanity-check a running variant, or to send a colleague a link so they can see
the variant for themselves.

It works on **draft** experiments (before you've ever launched) and on
**running** ones, and the link is **shareable** — anyone who opens it on your
site sees the same thing.

## Get a preview link

<Steps>
  <Step title="Open the experiment">
    In your dashboard, go into the site and open the experiment.
  </Step>

  <Step title="Find the variant">
    In the **Variations** list, each variant row has a **Preview** button.
  </Step>

  <Step title="Open or copy">
    Click **Preview**, then **Open in new tab** to view it yourself, or
    **Copy URL** to test in another browser or share with a teammate.
  </Step>
</Steps>

The link is just your test's page URL with one extra parameter:

```
https://acme.com/checkout?abtestly_preview=<experimentId>:<variantKey>
```

When you open it on your site, the snippet renders that variant and shows a
small **Preview** badge in the corner (see [The preview badge](#the-preview-badge)).

<Note>
  The page the link points at comes from the **target URL** you set in the
  experiment's **Basics** step. If you didn't set one, it falls back to your
  site's home page — so set a target URL if your test runs on a specific page.
</Note>

## What you can preview

* **Drafts, before launch.** You don't have to start a test to see it on your
  live site. This is the main reason to use a preview link — check your work
  on the real page first.
* **Running variants.** Confirm a live variant looks right, or compare it
  against the control.
* **The control.** Pick the control variant's key (often `control`) to preview
  the original, unchanged page within the same flow.

## Targeting is respected

A preview link forces the **variant choice** — but it still runs the
experiment's normal **targeting**, **locations**, and **audiences**. So the
preview shows what a *real matching visitor* would see:

* If the page and visitor **match** the experiment's conditions, the variant
  renders.
* If they **don't match** (wrong URL, wrong country/device, etc.), you see the
  **original page** — the same as a non-eligible visitor.

<Tip>
  If your variant doesn't appear, the most common cause is targeting: you're
  previewing on a page or in a context the test doesn't target. Double-check the
  experiment's [Locations and Audiences](/targeting-overview) against the page
  you're opening.
</Tip>

## Preview multiple tests at once

To see how several tests look **combined on one page**, separate the pairs with
commas:

```
https://acme.com/?abtestly_preview=<expA>:<v1>,<expB>:<v2>
```

Each test is resolved and targeting-checked independently — if one doesn't
match the page, the others still apply. You can preview up to **10** tests in a
single link.

## The preview badge

While a preview link is active, a small **Preview** badge appears in the
corner of the page. Each previewed test is shown as a row in the badge —
`Homepage CTA: [Variant B ▾]` — with the dropdown letting you switch to a
different variant of that test in place.

* **Switch variants from the badge.** Open the dropdown next to a test name
  and pick a different variant. The page does a **full reload** with the new
  variant forced — you don't have to go back to the dashboard or copy a new
  link. The full reload guarantees the snippet re-runs cleanly against the
  new variant whether the link uses the query-string form or the hash form
  (see [Single-page apps and the hash form](#single-page-apps-and-the-hash-form)).
  When previewing multiple tests, you get one dropdown per test on the same
  badge.
* **Drag it anywhere.** The badge is a floating pill you can grab and move, so
  it never hides the element you're trying to check. Its position is remembered
  for the rest of your session.
* **Exit preview.** Click **Exit ✕** on the badge to leave preview mode — it
  clears the session and strips the preview parameter from the URL, returning
  you to the normal page.

<Note>
  Variant labels in the dropdown come from the **variant name** you set in the
  dashboard ("Shorter headline", "Sticky CTA"). If a variant has no name, it's
  labeled **Original** for the control row or **Variant 1 / 2 / …** for the
  others.
</Note>

## Staying in preview as you click around

Once you open a preview link, preview mode **persists across pages in the same
browser tab** for up to **1 hour**, even if you navigate to URLs that don't
carry the parameter. This lets you click through a multi-step flow (e.g. a
checkout funnel) while still seeing your variants. It ends when the hour
elapses, when you click **Exit ✕**, or when you close the tab.

## Single-page apps and the hash form

Most preview links use a normal query parameter (`?abtestly_preview=…`). A few
frameworks (some Next.js, Remix, and Nuxt setups) reject *unknown* query
parameters at the server and return a 404 before the page ever loads.

If your query-parameter link 404s, use the **hash form** instead — a hash
fragment never reaches the server, so the app can't reject it:

```
https://acme.com/checkout#abtestly_preview=<experimentId>:<variantKey>
```

It also works inside hash-router URLs, e.g.
`https://acme.com/#/products/123?abtestly_preview=<expId>:<variant>`. Both
shapes are parsed identically and pass the same security checks.

<Note>
  Switching variants from the badge's dropdown writes the updated token back
  to whichever channel you started with — a hash-form preview keeps using the
  hash on subsequent switches, so SPAs that reject unknown query params
  don't break mid-session. Each switch triggers a full page reload either
  way, so the snippet always boots fresh on the new variant rather than
  trying to swap variants in place.
</Note>

See [Single-page apps](/spa-support) for more on running tests in
client-side routed apps.

## Iterating locally without a preview link

If you're writing variant code locally and want fast feedback in your
own browser (devtools console, a userscript, a browser extension) you
can activate the experiment without a preview URL by calling, from the
console on your own site:

```js theme={null}
window.abtestly.dev.apply('your-exp-id');
```

This treats the experiment as active for the rest of the tab session —
your `onApply` callbacks fire, and SPA navigations re-cycle the
lifecycle (cleanup, then re-apply) the same way they would for a real
visitor. It does NOT inject the variant's CSS or JS from the dashboard;
it's a flag-flip for the lifecycle hooks. Read more in
[Single-page apps → dev.apply](/spa-support#abtestlydevapplyexpid--local-qa-only).

<Warning>
  `abtestly.dev.*` is console / userscript only. Don't leave it in
  variant code — the dashboard editor will flag it.
</Warning>

## Requirements and safety

For a preview link to work, and to keep it from being abused:

* **The snippet must be installed** on the page, loaded over **HTTPS**. See
  [Installing the snippet](/snippet-install).
* **Preview only activates on your registered domain** (or any of its
  subdomains — and `localhost` for local development). The same link pasted on
  a different site does nothing, so it can't be used to inject your variant
  code onto a third-party page.
* **A link can only preview your own site's tests.** Even on your domain, the
  snippet refuses to render an experiment that belongs to a different site.
* **No data is ever recorded.** Preview never buckets the visitor and never
  sends analytics — so previewing, or sharing the link with your whole team,
  **cannot pollute your results**.

<Warning>
  A preview link is **public**: anyone who has it, and who meets the targeting
  conditions on your domain, can see the variant — including unlaunched drafts.
  The link doesn't expose your dashboard or any visitor data, but treat it like
  any shareable URL and don't post it somewhere you wouldn't want a draft test
  seen.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="I opened the link but I still see the original page">
    Usually targeting. The link forces the variant *only* on pages and
    visitors that match the experiment's Locations and Audiences. Confirm
    you're on a targeted URL and that your context (country, device, etc.)
    matches. Also check the variant key in the link matches a real variant.
  </Accordion>

  <Accordion title="The link returns a 404 before the page loads">
    Your framework is rejecting the unknown query parameter. Use the
    [hash form](#single-page-apps-and-the-hash-form)
    (`#abtestly_preview=…`) instead — it never reaches the server.
  </Accordion>

  <Accordion title="Nothing happens at all — no badge, no change">
    The snippet probably isn't loading, or you're not on the registered
    domain. Open DevTools → Console and check `window.__ABTESTLY_CONFIG__`
    returns your config (see [Verify installation](/quickstart#4-verify-installation)).
    Preview also requires HTTPS and only activates on your registered domain or
    a subdomain of it.
  </Accordion>

  <Accordion title="Will previewing affect my test results?">
    No. Preview mode never assigns the visitor to a bucket and never sends any
    analytics events. You can preview and share links freely without touching
    your numbers.
  </Accordion>
</AccordionGroup>

If a preview still behaves unexpectedly after these checks, email
[support@abtestly.com](mailto:support@abtestly.com) with the link and the page
you're testing — we'll help you track it down.

***

## Start testing

<Card title="Create a free ABTestly account" icon="flask" href="https://app.abtestly.com/sign-up" horizontal>
  The free tier covers 3,000 monthly tracked users and one active experiment, no credit card. Edge-served snippet, with sample size and confidence intervals shown on every result.
</Card>
