/Docs

Single Page Apps

A vs B has built-in support for single-page applications (SPAs). When a visitor navigates between pages without a full browser reload, the snippet automatically re-evaluates experiments for the new URL. No extra configuration is required in most cases.

The problem with SPAs

In a traditional website, every link click triggers a full page load. The browser re-downloads the HTML, re-runs all scripts including the snippet, and everything starts fresh. The snippet has no problem with this.

In a single-page application, clicking a link just swaps out the content in the browser without reloading the page. The URL changes, but the snippet does not re-run from scratch. Without special handling, the snippet would only evaluate experiments on the initial page load — any experiments targeting other URLs would never run.

How A vs B handles SPA navigation

A vs B patches the browser's History API (pushState and replaceState) and also listens for the popstate event (the browser back/forward buttons). When any of these fire, the snippet detects the route change and automatically:

  1. Removes all currently active variation CSS and JavaScript (cleaning up the previous page's experiments).
  2. Re-runs your Project JavaScript.
  3. Re-evaluates all experiments against the new URL and audience conditions.
  4. Injects the appropriate variation code for any experiments that match the new URL.

Importantly, the visitor's variation assignments are preserved across navigations. If a visitor was bucketed into Variant 1 of an experiment, they stay in Variant 1 every time they visit a page where that experiment runs — even after navigating away and back.

Enabling SPA support

SPA support is configured per project. To turn it on:

  1. Go to Project Settings → Configuration.
  2. Find the Single Page App toggle and enable it.
  3. Save your settings.

When this setting is enabled, the snippet activates its History API patching logic. When it is disabled, the snippet does not listen for route changes (suitable for traditional multi-page websites).

Tip
If you are unsure whether your site is an SPA, check whether clicking links causes a full page reload (the browser's loading spinner appears in the tab) or an instant content swap (no spinner). If it is an instant swap, enable SPA mode.

Framework-specific notes

React

If you are using React with React Router or a similar library, SPA mode works out of the box. Place the snippet in your index.html (or whatever file contains your root HTML) and enable SPA mode in project settings.

Next.js

For Next.js App Router projects, place the snippet in your root app/layout.tsx inside the <head> element using Next.js's Script component or a plain script tag. Enable SPA mode in project settings.

app/layout.tsx
tsx
1export default function RootLayout({ children }: { children: React.ReactNode }) {
2 return (
3 <html lang="en">
4 <head>
5 <script
6 id="avsb"
7 src="https://cdn.avsb.cloud/snippet.js?id=YOUR_SNIPPET_KEY"
8 />
9 </head>
10 <body>{children}</body>
11 </html>
12 )
13}

Vue

For Vue CLI or Vite-based Vue apps, place the snippet in your index.html file (at the project root) inside the <head> element. Enable SPA mode in project settings.

Angular

For Angular apps, place the snippet in your src/index.html file inside the <head> element. Enable SPA mode in project settings.

Hash-based routing
If your SPA uses hash-based routing (URLs like example.com/#/page), route changes do not trigger pushState or popstate. In this case, A vs B may not detect navigation. Most modern SPAs use the History API instead. If you are using hash routing and need SPA support, contact support for guidance.

Testing SPA mode

To confirm SPA mode is working, open your browser's DevTools console and navigate between pages. You should see A vs B log messages indicating it is re-evaluating experiments on each navigation (visible when experiment debug mode is on — see Verifying Installation).