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