A/b testing, setting content globally


Hello everyone,

Last November we started a project with multiple domains and languages.
Currently we’re upgrading from Kirby 2.0 to 3.1.1, and also releasing new functions on our project.

What we’ve done so far:

Now we run into some problems we hope to solve.

Generally we can say that we run multiple A/B tests over the whole site.
We specificed each usergroup so far as a own language, were “de” is set as the default.
The logic how we set A or B is no problem, but getting the right content without a redirect.
In general we have example.com/de/home, but decided sometimes to show version B of it under the same url.

Behind it looks like we render: example.com/de2/home, but the URL should stay the same.

Is it possible in the template (or in a plugin) to set something like this:

Thanks for your help,


Routes to the rescue.

Inside your route, conditionally set $site->visit($page, $lang) to the desired language and return the page.


Routes could help indeed, but I’m wondering what the SEO impact will be of rendering different pages on the same URL’s? :thinking:


SEO shouldn’t have a big impact, Google for example can handle JavaScript and A/B tests.

Text: content de

Text: content de __ 2


Kirby::plugin('testing/ab', [
    'routes' => [
            'pattern' => '/de/(:all)',
            'action'  => function() {
                return site()->visit(page(), 'de2');


<?= $page->text()->kt(); ?>


content de

Am I missing something?



Something like this, of course with an if statement that checks your A/B-test condition and some if statement that check if the page exists:

Kirby::plugin('testing/ab', [
    'routes' => [
            'pattern' => '/de/(:all)',
            'action'  => function($uri) {
                  $page = page($uri);
                  site()->visit($page, 'de2');
                  return $page;      

Don’t know if the above pattern works for the home page, you might have to make the all placeholder optional.



The code above is working perfectly. Run into an issue where my controller always redirect on itself on a missing language.

Is there another possibility to only affect the content elements?
And not the header/footer snippets?



What do you mean with missing language?



if (!in_array($kirby->language()->code(), $kirby->option('languages'))) {
    $go = $page->url($kirby->option('language'));

Was part of the legacy code.


Well, yes, you could also use some logic in the template/controller and then display either then content from de or de2, depending. on group.


should do the job.