<p><a href="https://plugins.craftcms.com/optimum?craft4" rel="nofollow noreferrer">https://plugins.craftcms.com/optimum?craft4</a></p>
<p><a href="https://github.com/matfish2/craft-optimum" rel="nofollow noreferrer">https://github.com/matfish2/craft-optimum</a></p>
<p>The Optimum plugin allows for server-side A/B/n testing in Craft.
You can set multiple experiments on the same page, each with unlimited variants. The plugin automatically sends the data to a GA4 custom dimension.</p>
<p>Full disclosure: I'm the author.</p>

CC BY-SA 4.0
2023-07-15T09:29:54.707Z
2023-07-15T09:29:54.707Z
Matanya
<p>You can set a cookie from your template, which assigns visitors to specific groups:</p>
<hr />
<p><strong>Craft 2:</strong> <em>(Use the <a href="https://github.com/lewisjenkins/craft-lj-cookies" rel="nofollow noreferrer">LJ Cookies</a> plugin)</em></p>

<pre class="lang-twig prettyprint-override"><code>{% set testGroup = craft.lj_cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.lj_cookies.set('group', testGroup, expires) %}
{% endif %}
</code></pre>
<p><strong>Craft 3:</strong></p>
<pre class="lang-twig prettyprint-override"><code>{% set testGroup = craft.app.request.cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.app.response.cookies.add(create({
         class: 'yii\\web\\Cookie',
         name: 'group',
         value: testGroup,
         httpOnly: true
    })) %} 
{% endif %}
</code></pre>
<hr />
<p>And then reference that <code>testGroup</code> variable whenever you need to know which group they’re in:</p>
<pre class="lang-twig prettyprint-override"><code>{% switch testGroup %}
    {% case 'a' %}
        ....
    {% case 'b' %}
        ....
{% endswitch %}
</code></pre>
<p>The nice thing about this approach is that you can actually have multiple sets of test groups at the same time, using different cookie/variable names. You’re also not limited to two groups per set.</p>

CC BY-SA 3.0
2015-10-26T12:40:29.627Z
Awesome, thanks Brandon.
Leah
CC BY-SA 4.0
2022-04-13T12:35:46.993Z
Thanks, is this still the best approach for AB testing 3 years later?
mateostabio
CC BY-SA 4.0
2022-07-19T17:30:37.243Z
@mateostabio I would saying cookies is still a viable option. Without any account based system in place it's really a easy and low maintenance way of doing A/B testing
James White
CC BY-SA 4.0
2015-10-16T14:46:59.037Z
2022-07-19T07:20:07.620Z
2022-07-19T07:20:07.620Z
Brandon Kelly
<p>What's your process for A/B testing a Craft entry? I'm curious about how you'd structure alternative content for a page within Craft and what tools you'd use to measure the results.</p>

<p>Any comments appreciated - I know there are lots of different ways you could approach this!</p>

<templating><conditional><content>
A/B testing - how to in Craft?
# A/B testing - how to in Craft?

(Asked by: username_0 on 2015-10-15)

What's your process for A/B testing a Craft entry? I'm curious about how you'd structure alternative content for a page within Craft and what tools you'd use to measure the results.

Any comments appreciated - I know there are lots of different ways you could approach this!

**Tags:** templating, conditional, content


---

## 2 answers

### Answer by username_2 on 2015-10-16. Score: 14 | Accepted answer

You can set a cookie from your template, which assigns visitors to specific groups:

Craft 2: (Use the LJ Cookies plugin)
{% set testGroup = craft.lj_cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.lj_cookies.set('group', testGroup, expires) %}
{% endif %}

Craft 3:
{% set testGroup = craft.app.request.cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.app.response.cookies.add(create({
         class: 'yii\\web\\Cookie',
         name: 'group',
         value: testGroup,
         httpOnly: true
    })) %} 
{% endif %}


And then reference that testGroup variable whenever you need to know which group they’re in:
{% switch testGroup %}
    {% case 'a' %}
        ....
    {% case 'b' %}
        ....
{% endswitch %}

The nice thing about this approach is that you can actually have multiple sets of test groups at the same time, using different cookie/variable names. You’re also not limited to two groups per set.

> **Comments:**
> **username_0**: Awesome, thanks Brandon.  
> **username_3**: Thanks, is this still the best approach for AB testing 3 years later?  
> **username_4**: @username_3 I would saying cookies is still a viable option. Without any account based system in place it's really a easy and low maintenance way of doing A/B testing  

---

### Answer by username_1 on 2023-07-15. Score: 1

<https://plugins.craftcms.com/optimum?craft4>

<https://github.com/matfish2/craft-optimum>

The Optimum plugin allows for server-side A/B/n testing in Craft.
You can set multiple experiments on the same page, each with unlimited variants. The plugin automatically sends the data to a GA4 custom dimension.

Full disclosure: I'm the author.


---

