pex

Client-Side Experiments

The Apex snippet runs A/B tests directly in the browser. It fetches your active experiments, assigns each visitor to a variant deterministically, and applies DOM changes — all before the page becomes visible.

How Experiments Are Fetched

On every page load, the snippet calls the experiments endpoint:

GET/api/experiments/active?key=PROJECT_KEY

Returns all active experiments for the project

The response is an array of experiment objects, each containing variant definitions, traffic split, target URL, and conversion goal configuration. Results are cached in memory for 5 minutes to minimize network requests across page navigations.

Variant Assignment

Each visitor is assigned to a variant using deterministic hashing. The snippet computes a MurmurHash of the visitor ID concatenated with the experiment ID:

hash = murmurhash3(visitorId + experimentId)
bucket = hash % 100
variant = bucket < trafficSplit ? "control" : "variant_b"

This guarantees the same visitor always sees the same variant — no server-side state required. The assignment is stable across sessions, devices (same browser), and page reloads.

Info

The trafficSplit value represents the percentage of traffic that sees the control. A 50/50 split means trafficSplit = 50.

Page Targeting

Experiments can be restricted to specific pages via the targetUrl field. The snippet normalizes both the experiment URL and the current page URL (stripping www., trailing slashes, and protocol) before comparing. If no targetUrl is set, the experiment runs on every page.

Variant Types

Text Changes

The most common variant type. The snippet finds a DOM element by CSS selector and replaces its text content.

{
  "type": "text",
  "selector": "h1.hero-title",
  "originalValue": "Grow your business",
  "value": "Scale faster with Apex"
}

If the selector doesn't match, the snippet falls back to text-based matching — it scans heading, paragraph, button, and link elements for content matching originalValue. This makes experiments resilient to minor markup changes.

Redirect Variants

Instead of modifying the DOM, redirect variants send the visitor to a different URL entirely.

{
  "redirectUrl": "https://example.com/landing-v2"
}

Redirects happen immediately after variant assignment, before any other DOM processing.

Hide / Show

Toggle element visibility. Useful for testing whether removing or adding a section improves conversions.

{ "type": "hide", "selector": ".testimonials-section" }
{ "type": "show", "selector": ".pricing-cta", "value": "flex" }

HTML and Image Swaps

Replace inner HTML or swap image sources for richer variant changes.

{ "type": "html", "selector": ".cta-block", "value": "<a href='/start' class='btn'>Get Started Free</a>" }
{ "type": "image", "selector": ".hero-image", "value": "https://cdn.example.com/hero-v2.jpg" }

Warning

HTML variants are sanitized — script, iframe, object, and embed tags are automatically stripped to prevent XSS.

Anti-Flicker Mechanism

To prevent visitors from seeing the original content before variants are applied, the snippet sets document.documentElement.style.opacity = "0" immediately on load. Once experiment changes are applied (or if no experiments match the page), opacity is restored to 1 with a 50ms CSS transition. A 100ms safety timeout ensures the page is never hidden indefinitely.

MutationObserver Guard

For text changes, the snippet attaches a MutationObserver to the modified element. If a client-side framework (React, Vue, etc.) re-renders and overwrites the variant text, the observer re-applies it. The guard auto-disconnects after 5 seconds to avoid long-term overhead.

Preview Mode

Test any variant without affecting live traffic by adding query parameters to your URL:

https://yoursite.com/landing?_apex_preview=variant_b&_apex_exp=exp-123
ParameterRequiredDescription
_apex_previewYesThe variant ID to force (e.g., variant_b)
_apex_expNoLimit preview to a specific experiment ID

In preview mode, a green banner appears at the top of the page confirming which variant you're viewing. Preview visits are not counted in experiment results.

Tip

Use preview mode to QA your experiments before activating them. Share preview links with your team for design review.

Conversion Goals

Experiments can define a conversion goal that the snippet automatically tracks. Supported goal types:

  • Click — Fires when a visitor clicks an element matching the goal's CSS selector
  • Pageview — Fires when the visitor reaches a specific URL path
  • File download — Fires when a visitor clicks a link to a file with a matching extension (e.g., .pdf, .zip)
  • Engaged time — Fires when a visitor is actively engaged for a threshold number of seconds (idle time and hidden tabs are excluded)

Goal conversions are sent as goal_conversion events with the experiment and variant attached. See Custom Events for the event payload format.

Next Steps