Gidsen

A/B-testen integreren met Voluum, Redtrack en ClickFlare

Inleiding In de wereld van digitale marketing is A/B-testen essentieel voor succesvolle campagnes. LanderLab biedt nu een geweldige tool om A/B-testen server-side op te zetten, waarbij je dezelfde URL gebruikt om verschillende varianten af te wisselen.

Bruno Agalliu3 min leestijd

Inleiding

In de wereld van digitale marketing is A/B-testen essentieel voor succesvolle campagnes. LanderLab biedt nu een geweldige tool om A/B-testen server-side op te zetten, waarbij je dezelfde URL gebruikt om verschillende varianten af te wisselen. Met deze update kunnen gebruikers hun landingspagina A/B-testen en de resultaten dubbelchecken in de tracker van hun voorkeur.

Waarom A/B-testen met LanderLab?

De meeste marketeers gebruiken hun eigen trackingsoftware, zoals ClickFlare, Voluum of Redtrack, om landingspagina’s te splittesten, en in de meeste gevallen is dat meer dan voldoende. Toch zijn er situaties waarin splittesten met een tracker niet mogelijk is. Premium verkeersbronnen staan geen redirects toe: de uiteindelijke bestemmings-URL moet gelijk zijn aan de URL van de landingspagina.

Daar komt LanderLab van pas met zijn server-side A/B-testen, waarmee een redirect in de flow verdwijnt. In dit artikel lees je meer over hoe A/B-testen in LanderLab werkt. En het beste is: LanderLab laat zich integreren met de meeste moderne trackers.

A/B-test

Het concept is eenvoudig: de A/B-tests van LanderLab combineren met de direct tracking-methode die elke tracker biedt. Om de basis te dekken, laat dit artikel zien hoe je deze setup implementeert met ClickFlare, Voluum en Redtrack.

A/B-testen opzetten met ClickFlare

De direct tracking-methode van ClickFlare vormt de perfecte combinatie voor deze setup. Beide platforms zijn immers gemaakt en ontwikkeld door hetzelfde bedrijf, dus het ligt voor de hand om ze beter met elkaar te integreren. In dit artikel lees je meer over de direct tracking die ClickFlare biedt.

Voor deze setup volg je 2 basisstappen, en dezelfde stappen kun je toepassen op Voluum en Redtrack. De eerste stap is het definiëren van een nieuwe trackingparameter om de variantID in ClickFlare te rapporteren.

VariantID in ClickFlare

Om de variantID in onze tracker bij te houden, moeten we een paar wijzigingen aanbrengen in het direct tracking-script. Het volgende script bevat 2 variabelen die moeten worden vervangen: “REPLACE_ME_CAMPAIGN_ID” en “REPLACE_ME_CUSTOM_DOMAIN”. Zodra dat klaar is, moet de hele code worden geplaatst in LanderLab onder Settings > Custom Code > Header Section.

<script> ! function() {
    "use strict";
    var t = "lp_ref",
        n = "cpid",
        e = "lpurl",
        r = "REPLACE_ME_CUSTOM_DOMAIN",
        c = "(?<domain>http(?:s?)://[^/]*)".concat("/cf/click"),
        a = "(?:(?:/(?<cta>[1-9][0-9]*)/?)|(?:/))?",
        i = "^".concat(c).concat(a).concat("(?:$|(\\?.*))"),
        o = 'javascript:window.clickflare.l="(?<original_link>'.concat(c).concat(a, '("|(\\?[^"]*"))).*'),
        s = function() {
            return new RegExp(i, "")
        },
        u = function() {
            return new RegExp(o, "")
        };
    function l(t) {
        var n = function(t) {
            return t.replace(s(), (function(t) {
                for (var n = [], e = 1; e < arguments.length; e++) n[e - 1] = arguments[e];
                var c = n[n.length - 1].domain;
                return t.replace(c, r)
            }))
        }(t);
        return 'javascript:window.clickflare.l="'.concat(n, '"; void 0;')
    }
    function f(t, n) {
        if (n && t && n.apply(document, [t]), /loaded|interactive|complete/.test(document.readyState))
            for (var e = 0, r = document.links.length; e < r; e++)
                if (s().test(document.links[e].href)) {
                    var c = document.links[e];
                    window.clickflare.links_replaced.has(c) || (c.href = l(c.href), window.clickflare.links_replaced.add(c))
                }
    }! function(c, a) {
        var i = document.onreadystatechange;
        window.clickflare || (window.clickflare = {
            listeners: {},
            customParams: {},
            links_replaced: new Set,
            addEventListener: function(t, n) {
                var e = this.listeners[t] || [];
                e.includes(n) || e.push(n), this.listeners[t] = e
            },
            dispatchEvent: function(t, n) {
                n && (this.customParams[t] = n), (this.listeners[t] || []).forEach((function(t) {
                    return t(n)
                }))
            },
            push: function(t, n) {
                n && (this.customParams[t] = n), (this.listeners[t] || []).forEach((function(t) {
                    return t(n)
                }))
            }
        }, document.onreadystatechange = function(t) {
            return f(t, i)
        }, f(null, i), setTimeout((function() {
            ! function(c, a) {
                var i, o = function(c, a) {
                        var i = new URL("".concat(r).concat(c)),
                            o = "{",
                            s = o + o;
                        a.startsWith(s) || i.searchParams.set(n, a);
                        return i.searchParams.append(t, document.referrer), i.searchParams.append(e, location.href), i.searchParams.append("variantId", window.LL_VARIANT_ID), i.searchParams.append("lpt", document.title), i.searchParams.append("t", (new Date).getTime().toString()), i.toString()
                    }(c, a),
                    s = document.createElement("script"),
                    l = document.scripts[0];
                s.async = 1, s.src = o, s.onerror = function() {
                    ! function() {
                        for (var t = function(t, n) {
                                var e = document.links[t];
                                u().test(e.href) && setTimeout((function() {
                                    e && e.setAttribute("href", function(t) {
                                        var n = t.match(u());
                                        if (n) {
                                            var e = (n.groups || {}).original_link;
                                            return e ? e.slice(0, -1) : t
                                        }
                                        return t
                                    }(e.href))
                                }))
                            }, n = 0, e = document.links.length; n < e; n++) t(n)
                    }()
                }, null === (i = l.parentNode) || void 0 === i || i.insertBefore(s, l)
            }(c, a)
        })))
    }("".concat("/cf/tags", "/").concat(new URL(window.location.href).searchParams.get("cftmid") || "{{__CONTAINER_ID__}}"), new URL(window.location.href).searchParams.get(n) || "REPLACE_ME_CAMPAIGN_ID")
}(); </script>

A/B-testen opzetten met Voluum

Voluum is een van de oudste trackers in affiliate marketing en heeft nog steeds een groot deel van de markt in handen. Ook hier vertrouwen we op direct tracking om de variantID in deze tracker te rapporteren, met dezelfde methode als eerder.

VariantID in Voluum

De variantID wordt onderaan in het sjabloon van de verkeersbron toegevoegd, maar in welke volgorde je hem invoegt maakt eigenlijk niet uit. Om dezelfde terminologie aan te houden, moeten dezelfde 2 variabelen worden vervangen: “REPLACE_ME_CAMPAIGN_ID” en “REPLACE_ME_CUSTOM_DOMAIN”. Kopieer de volgende code en plak die in het gedeelte voor custom code van LanderLab, zodat de setup compleet is.

<<b>style</b>>.dtpcnt{opacity: 0;}</<b>style</b>>
    <<b>script</b>>
    (function(d, c, k, l, r, t, g, u, A, e, m, v, B, a, n, p, h, q, w, D, x) {
        function y() { for (var f = c.querySelectorAll(".dtpcnt"), b = 0, a = f.length; b < a; b++) f[b][u] = f[b][u].replace(/(^|\s+)dtpcnt($|\s+)/g, "") }
        function C(a, b, d, e) { var f = new Date;
            f.setTime(f.getTime() + (e || 864E5));
            c.cookie = a + "=" + b + "; " + d + "samesite=Strict; expires=" + f.toGMTString() + "; path=/";
            k.setItem(a, b);
            k.setItem(a + "-expires", f.getTime()) }
        function z(a) {
            var b = c.cookie.match(new RegExp("(^| )" + a + "=([^;]+)"));
            return b ? b.pop() : k.getItem(a + "-expires") && +k.getItem(a +
                "-expires") > (new Date).getTime() ? k.getItem(a) : null
        }
        x = "https:" === d.location.protocol ? "secure; " : "";
        d[e] || (d[e] = function() {
            (d[e].q = d[e].q || []).push(arguments) }, p = c[r], c[r] = function() { p && p.apply(this, arguments); if (d[e] && !d[e].hasOwnProperty("params") && /loaded|interactive|complete/.test(c.readyState))
                for (; a = c[t][m++];) /\/?click\/?($|(\/[0-9]+)?$)/.test(a.pathname) && (a[g] = "javascrip" + d.postMessage.toString().slice(4, 5) + ":" + e + '.l="' + a[g] + '",void 0') }, setTimeout(function() {
            (q = /[?&]cpid(=([^&#]*)|&|#|$)/.exec(d.location.href)) &&
            q[2] && (h = q[2], w = z("vl-" + h));
            var f = z("vl-cep"),
                b = location[g];
            if ("savedCep" === B && f && (!h || "undefined" === typeof h) && 0 > b.indexOf("cep=")) { var e = -1 < b.indexOf("?") ? "&" : "?";
                b += e + f } a = c.createElement("script");
            n = c.scripts[0];
            a.defer = 1;
            a.src = v + (-1 === v.indexOf("?") ? "?" : "&") + "lpref=" + l(c.referrer) + "&lpurl=" + l(b) + "&lpt=" + l(c.title) + "&vtm=" + (new Date).getTime() + (w ? "&uw=no" : "") + "&variantId=" + window.LL_VARIANT_ID ;
            a[A] = function() { for (m = 0; a = c[t][m++];) /dtpCallback\.l/.test(a[g]) && (a[g] = decodeURIComponent(a[g]).match(/dtpCallback\.l="([^"]+)/)[1]);
                y() };
            n.parentNode.insertBefore(a, n);
            h && C("vl-" + h, "1", x)
        }, 0), setTimeout(y, 7E3))
    })(window, document, localStorage, encodeURIComponent, "onreadystatechange", "links", "href", "className", "onerror", "dtpCallback", 0, "REPLACE_ME_CUSTOM_DOMAIN/d/REPLACE_ME_CAMPAIGN_ID.js", "savedCep");
    </<b>script</b>>
    <<b>noscript</b>>
        <<b>link</b> href="REPLACE_ME_CUSTOM_DOMAIN/d/REPLACE_ME_CAMPAIGN_ID.js?noscript=true&lpurl=" rel="stylesheet" /></<b>noscript</b>>

A/B-testen opzetten met Redtrack

Als laatste zetten we dezelfde setup op voor Redtrack. Deze tracker heeft een flink deel van de markt in handen en biedt dezelfde functies als ClickFlare en Voluum.

In vergelijking met de andere 2 trackers moet de variantID hier echter aan een specifiek token worden toegewezen, omdat sommige tokens gereserveerd zijn voor systeemtokens. In dit voorbeeld is de variantID toegewezen aan sub18, en dat komt ook terug in het direct tracking-script.

VariantID in Redtrack

 

“REPLACE_ME_CAMPAIGN_ID” en “REPLACE_ME_CUSTOM_DOMAIN” moeten worden vervangen, en daarna is de code klaar voor gebruik in LanderLab.

<script>
function getCookie(name) {
    var value = "; " + document.cookie;
    var parts = value.split("; " + name + "=");
    if (parts.length === 2) {
        return parts.pop().split(";").shift();
    }
}
var trackerURL = "REPLACE_ME_CUSTOM_DOMAIN";
var campaignID = "REPLACE_ME_CAMPAIGN_ID";
var cachebuster = Math.round(new Date().getTime() / 1000);
var rtkClickID;
var rtkfbp = getCookie('_fbp') || '';
var rtkfbc = getCookie('_fbc') || '';
var LL_VARIANT_ID = window.LL_VARIANT_ID;
var locSearch = window.location.search;
var urlParams = new URLSearchParams(locSearch);
var pixelParams = "&" + locSearch.substr(1) + "&sub18=" + LL_VARIANT_ID + "&sub19=" + rtkfbp + "&sub20=" + rtkfbc
if (campaignID == "") {
    campaignID = urlParams.get('rtkcmpid')
}
var initialSrc = "https://"+ trackerURL + "/" + campaignID + "?format=json";

function stripTrailingSlash(str) {
    return str.replace(/\/$/, "");
}

var rawData;

function fixHrefWithClick(
    _rawData,
    _cachebuster,
    _rtkClickID
) {
    document.querySelectorAll('a').forEach(function(el) {
        if (el.href.indexOf(trackerURL + "/click") > -1) {
            if (el.href.indexOf('?') > -1) {
                el.href = stripTrailingSlash(el.href) + "&clickid=" + (_rtkClickID || _rawData.clickid) + "&rtkck=" + _cachebuster
            } else {
                el.href = stripTrailingSlash(el.href) + "?clickid=" + (_rtkClickID || _rawData.clickid) + "&rtkck=" + _cachebuster
            }
        }
        if (el.href.indexOf("clickid={clickid}") > -1) {
            el.href = el.href.replace(/{clickid}/, _rawData.clickid) + "&rtkck=" + _cachebuster;
        }
    });
}

setTimeout(function() {
    if (!urlParams.get('rtkcid')) {
        xhr = new XMLHttpRequest;
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                rawData = JSON.parse(xhr.responseText);
                rtkClickID = rawData.clickid
                setCookie();
                // fixHrefWithClick(rawData, cachebuster)
                document.querySelectorAll('a').forEach(function(el) {
                    if (el.href.indexOf(trackerURL + "/click") > -1) {
                        if (el.href.indexOf('?') > -1) {
                            el.href = stripTrailingSlash(el.href) + "&clickid=" + rawData.clickid + "&rtkck=" + cachebuster
                        } else {
                            el.href = stripTrailingSlash(el.href) + "?clickid=" + rawData.clickid + "&rtkck=" + cachebuster
                        }
                    }
                    if (el.href.indexOf("clickid={clickid}") > -1) {
                        el.href = el.href.replace(/{clickid}/, rawData.clickid) + "&rtkck=" + cachebuster;
                    }
                });
                xhrr = new XMLHttpRequest;
                xhrr.open("GET", "https://"+ trackerURL +"/view?clickid=" + rawData.clickid)
                xhrr.send();
            }
        }
        xhr.open("GET", initialSrc + pixelParams)
        xhr.send();
    } else {
        rtkClickID = urlParams.get('rtkcid')
        setCookie();
        xhrTrack = new XMLHttpRequest;
        xhrTrack.open("GET", "https://"+trackerURL+"/view?clickid=" + rtkClickID)
        xhrTrack.send();
        // fixHrefWithClick(rawData, cachebuster, rtkClickID)
        document.querySelectorAll('a').forEach(function(el) {
            if (el.href.indexOf(trackerURL+ "/click") > -1) {
                if (el.href.indexOf('?') > -1) {
                    el.href = stripTrailingSlash(el.href) + "&clickid=" + rtkClickID + "&rtkck=" + cachebuster
                } else {
                    el.href = stripTrailingSlash(el.href) + "?clickid=" + rtkClickID + "&rtkck=" + cachebuster
                }
            }
            if (el.href.indexOf("clickid={clickid}") > -1) {
                el.href = el.href.replace(/{clickid}/, rawData.clickid) + "&rtkck=" + cachebuster;
            }
        });
    }
}, 5e1)

function setCookie() {
    var cookieName = "rtkclickid-store",
        cookieValue = rtkClickID,
        expirationTime = 86400 * 30 * 1000,
        date = new Date(),
        dateTimeNow = date.getTime();
    date.setTime(dateTimeNow + expirationTime);
    var date = date.toUTCString();
    document.cookie = cookieName + "=" + cookieValue + "; expires=" + date + "; path=/;"
}
    </script>

Conclusie

Nu de data in je tracker wordt gerapporteerd, kun je daadwerkelijk meten hoeveel events een specifieke variant oplevert. Zodra je de winnende variant kent, beëindig je gewoon de A/B-test en stel je die in als hoofdvariant. Begin vandaag nog met splittesten met LanderLab en neem daarbij het risico weg dat je wordt gebanned.

Wil je A/B-testen optimaliseren met je tracker?
Start nu je gratis proefperiode en gebruik geavanceerd A/B-testen met LanderLab samen met ClickFlare, Voluum of Redtrack!

Lees verder

Meer in Gidsen.

Onderwerpen

Blader per onderwerp

Elk artikel valt onder een onderwerp. Begin bij het onderwerp dat het dichtst bij je lopende campagne ligt.

Lees het playbook.Bouw dan de pagina.

Begin gratis: bouw de landingspagina, publiceer hem op je eigen domein en stuur elke lead door naar je afnemer, voordat je volgende campagne live gaat.

Van één prompt naar gekwalificeerde leads

Zie hoe één prompt een live offertefunnel voor zonnepanelen wordt, elke lead naar je afnemer gaat en de lekken worden gesignaleerd voordat ze je budget opeten.

0:00
0:59