# Run your first AB test

Compare content variations and measure their impact.

In this tutorial, you will set up an [experiment](/explanation/experiment) on a hero section. You will track CTA clicks with a goal event, create an experiment with two variants, and learn how to read the results.

## Prerequisites

Before you start, make sure you have:

- A [Croct account](https://app.croct.com/signup) with a workspace and application set up.
- A project with the `home-hero` slot set up and rendering content. If you have not done this yet, start by [creating a slot](/immersion/tutorials/get-started/content-management).

## Track the conversion goal

Before launching the experiment, set up the event that measures success. You will track when a user clicks the hero CTA button.

![Conversion event tracking](/assets/immersion/tutorials/get-started/ab-testing/goal-completed.png)

Update the hero component you created earlier to fire a [goal completed](/reference/event/types/engagement/goal-completed) event on the CTA click:

**Plug JS — JavaScript**

```js
import croct from '@croct/plug';

async function renderHero() {
  const {content} = await croct.fetch('home-hero');

  document.querySelector('#hero-title').textContent = content.title;
  document.querySelector('#hero-subtitle').textContent = content.subtitle;

  const button = document.querySelector('#hero-cta');

  button.textContent = content.button.label;
  button.href = content.button.link;

  button.addEventListener('click', () => {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  });
}

renderHero();
```

**Plug JS — TypeScript**

```ts
import croct from '@croct/plug';

async function renderHero(): Promise<void> {
  const {content} = await croct.fetch('home-hero');

  document.querySelector<HTMLElement>('#hero-title')!.textContent = content.title;
  document.querySelector<HTMLElement>('#hero-subtitle')!.textContent = content.subtitle;

  const button = document.querySelector<HTMLAnchorElement>('#hero-cta')!;

  button.textContent = content.button.label;
  button.href = content.button.link;

  button.addEventListener('click', () => {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  });
}

renderHero();
```

**Plug React — JavaScript**

```jsx
import {useContent, useCroct} from '@croct/plug-react';

export function HomeHero() {
  const content = useContent('home-hero');
  const croct = useCroct();

  function handleClick() {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{content.title}</h1>
      <p>{content.subtitle}</p>
      <a href={content.button.link} onClick={handleClick}>{content.button.label}</a>
    </div>
  );
}
```

**Plug React — TypeScript**

```tsx
import type {ReactElement} from 'react';
import {useContent, useCroct} from '@croct/plug-react';

export function HomeHero(): ReactElement {
  const content = useContent('home-hero');
  const croct = useCroct();

  function handleClick(): void {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{content.title}</h1>
      <p>{content.subtitle}</p>
      <a href={content.button.link} onClick={handleClick}>{content.button.label}</a>
    </div>
  );
}
```

**Plug Next — JavaScript**

```jsx
'use client';

import {useContent, useCroct} from '@croct/plug-next';

export function HomeHero() {
  const content = useContent('home-hero');
  const croct = useCroct();

  function handleClick() {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{content.title}</h1>
      <p>{content.subtitle}</p>
      <a href={content.button.link} onClick={handleClick}>{content.button.label}</a>
    </div>
  );
}
```

**Plug Next — TypeScript**

```tsx
'use client';

import type {ReactElement} from 'react';
import {useContent, useCroct} from '@croct/plug-next';

export function HomeHero(): ReactElement {
  const content = useContent('home-hero');
  const croct = useCroct();

  function handleClick(): void {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{content.title}</h1>
      <p>{content.subtitle}</p>
      <a href={content.button.link} onClick={handleClick}>{content.button.label}</a>
    </div>
  );
}
```

**Plug Hydrogen — JavaScript**

```jsx
import {useLoaderData} from '@remix-run/react';
import {useCroct} from '@croct/plug-hydrogen';
import {fetchContent} from '@croct/plug-hydrogen/server';

export async function loader({context}) {
  const {content} = await fetchContent('home-hero', {scope: context});

  return {hero: content};
}

export default function Index() {
  const {hero} = useLoaderData();
  const croct = useCroct();

  function handleClick() {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{hero.title}</h1>
      <p>{hero.subtitle}</p>
      <a href={hero.button.link} onClick={handleClick}>{hero.button.label}</a>
    </div>
  );
}
```

**Plug Hydrogen — TypeScript**

```tsx
import type {ReactElement} from 'react';
import {useLoaderData} from '@remix-run/react';
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {useCroct} from '@croct/plug-hydrogen';
import {fetchContent} from '@croct/plug-hydrogen/server';

export async function loader({context}: LoaderFunctionArgs) {
  const {content} = await fetchContent('home-hero', {scope: context});

  return {hero: content};
}

export default function Index(): ReactElement {
  const {hero} = useLoaderData<typeof loader>();
  const croct = useCroct();

  function handleClick(): void {
    croct.track('goalCompleted', {
      goalId: 'hero-cta-click',
    });
  }

  return (
    <div>
      <h1>{hero.title}</h1>
      <p>{hero.subtitle}</p>
      <a href={hero.button.link} onClick={handleClick}>{hero.button.label}</a>
    </div>
  );
}
```

**Plug Vue**

```vue
<script setup>
import {useContent, useCroct} from '@croct/plug-vue'

const {data} = useContent('home-hero')
const croct = useCroct()

function handleClick() {
    croct.track('goalCompleted', {
        goalId: 'hero-cta-click',
    })
}
</script>

<template>
    <div v-if="data">
        <h1>{{ data.title }}</h1>
        <p>{{ data.subtitle }}</p>
        <a :href="data.button.link" @click="handleClick">{{ data.button.label }}</a>
    </div>
</template>
```

**Plug Nuxt**

```vue
<script setup>
import {useCroct} from '@croct/plug-nuxt'

const {data} = await useContent('home-hero')
const croct = useCroct()

function handleClick() {
    croct.track('goalCompleted', {
        goalId: 'hero-cta-click',
    })
}
</script>

<template>
    <div v-if="data">
        <h1>{{ data.content.title }}</h1>
        <p>{{ data.content.subtitle }}</p>
        <a :href="data.content.button.link" @click="handleClick">{{ data.content.button.label }}</a>
    </div>
</template>
```

**Plug PHP**

```php
<?php
use Croct\Plug\Croct;

$croct = Croct::fromDotenv();
$hero = $croct->fetchContent('home-hero')->getContent();
Croct::emitCookies();
?>
<div>
    <h1><?= $hero['title'] ?></h1>
    <p><?= $hero['subtitle'] ?></p>
    <a id="hero-cta" href="<?= $hero['button']['link'] ?>"><?= $hero['button']['label'] ?></a>
</div>

<script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>
<script>
  croct.plug(<?= json_encode($croct->getPlugOptions()) ?>);

  document.querySelector('#hero-cta').addEventListener('click', () => {
    croct.track('goalCompleted', {goalId: 'hero-cta-click'});
  });
</script>
```

**Plug Symfony**

```twig
<div>
    <h1>{{ hero.title }}</h1>
    <p>{{ hero.subtitle }}</p>
    <a id="hero-cta" href="{{ hero.button.link }}">{{ hero.button.label }}</a>
</div>

{% apply croct %}
    document.querySelector('#hero-cta').addEventListener('click', () => {
        croct.track('goalCompleted', {goalId: 'hero-cta-click'});
    });
{% endapply %}
```

**Plug Laravel**

```blade
<div>
    <h1>{{ $hero['title'] }}</h1>
    <p>{{ $hero['subtitle'] }}</p>
    <a id="hero-cta" href="{{ $hero['button']['link'] }}">{{ $hero['button']['label'] }}</a>
</div>

@croct
    document.querySelector('#hero-cta').addEventListener('click', () => {
        croct.track('goalCompleted', {goalId: 'hero-cta-click'});
    });
@endcroct
```

**Plug Drupal**

```twig
<h1>{{ hero.title }}</h1>
<p>{{ hero.subtitle }}</p>
<a id="hero-cta" href="{{ hero.button.link }}">{{ hero.button.label }}</a>

{% apply croct %}
    document.querySelector('#hero-cta').addEventListener('click', () => {
        croct.track('goalCompleted', {goalId: 'hero-cta-click'});
    });
{% endapply %}
```

This event feeds the [experiment's performance dashboard](/reference/analytics/experiment/overview), allowing you to compare conversion rates across variants.

## Create the experiment

Now set up the experiment in the admin app:

1. Open the [experiences page](https://app.croct.com/redirect/organizations/-organization-/workspaces/-workspace-/experiences) and create a new experience targeting all users.

2. Click the **Slot** tab and select the `home-hero` slot.

3. Click the **Experiment** tab and give it a name, for example `Hero CTA copy test`.

4. Select the goal `hero-cta-click` that you created in the last step, and determine the percentage of eligible users who will participate in your experiment. In this case, set it to 100%.

5. Set up two variants and split traffic evenly between them (50/50):

   - **Variant A**: `Get started`
   - **Variant B**: `Start your free trial`

6. Open de **Content** tab and define the content for each variant:

   - **Variant A**: Click **Options** () and copy the content from the slot.
   - **Variant B**: Click **Options** (), copy the content from the slot, and change the CTA label to `Start your free trial`.

7. Click **Publish** and launch the experience.

## Try it out

Verify that the experiment is serving both variants:

1. **Open an incognito tab**

   Load your application and note which button label you see.

2. **Open another incognito tab**

   Each tab starts a new session, so the experiment randomly assigns a variant.

3. **Compare**

   After a few attempts, you should see both `Get started` and `Start your free trial`.

![Variants content](/assets/immersion/tutorials/get-started/ab-testing/experiment-content.png)

## Read the results

Once the experiment has collected enough data:

1. **Open the experiment dashboard**

   Go to your experiment and click the **Overview** tab.

2. **Check the performance per goal**

   Look at the [Performance per Goal](/reference/analytics/experiment/widgets/performance-per-goal) widget. Select the `hero-cta-click` goal to compare conversion rates between variant A and variant B.

3. **Decide the winner**

   When the experiment reaches statistical stability, and one variant outperforms the other, you can declare a winner. Then, you can apply the winning content to the experience and stop the experiment.

## Explore

- [Audiences](/explanation/audience/introduction): Discover what an audience is and how it works.
- [Analytics](/reference/analytics/experiment/overview): Understand how your experiments perform across key metrics.
