A/B testovanie bannerov so žiadosťou o súhlas s používaním súborov cookie
Výzva
Chcete otestovať rôzne dizajny alebo texty bannerov o súbore cookie s cieľom zvýšiť mieru súhlasu a zároveň zachovať súlad s nariadením GDPR.
Scenár
„Chcem otestovať náš banner o súboroch cookie pomocou A/B testovania, aby som zistil, či rôzne formulácie ovplyvňujú mieru súhlasu. Obávam sa však o súlad s nariadením GDPR, ak budem sledovať používateľov skôr, ako vyjadria súhlas.“
Prístup k A/B testovaniu v súlade s predpismi
Kľúčový princíp: Banner s informáciami o súboroch cookie môžete testovať BEZ sledovacích nástrojov, pričom použijete len striktne nevyhnutné súbory cookie.
Implementácia
// Create variant assignment (strictly necessary cookie)
function assignVariant() {
let variant = getCookie('banner_test_variant');
if (!variant) {
// Randomly assign variant
variant = Math.random() < 0.5 ? 'A' : 'B';
// Store in strictly necessary cookie (doesn't require consent)
document.cookie = banner_test_variant=${variant}; path=/; max-age=2592000; SameSite=Strict;
}
return variant;
}
// Configuration for Variant A (Control)
const configA = {
"notice_banner_type": "simple",
"website_name": "My Website",
// ... other config
};
// Configuration for Variant B (Test)
const configB = {
"notice_banner_type": "headline",
"website_name": "My Site", // Shorter name
// ... other config
};
// Initialize based on variant
document.addEventListener('DOMContentLoaded', function () {
const variant = assignVariant();
const config = variant === 'A' ? configA : configB;
// Add callback to track results (only after consent)
config.callbacks = {
"i_agree_button_clicked": () => {
// User accepted - log this (now they've consented to tracking)
logConsentEvent(variant, 'accepted');
},
"i_decline_button_clicked": () => {
// User declined - still log the action
logConsentEvent(variant, 'declined');
}
};
cookieconsent.run(config);
});
function logConsentEvent(variant, action) {
// Send to your analytics (user has now consented)
if (typeof gtag !== 'undefined') {
gtag('event', 'cookie_consent', {
'variant': variant,
'action': action
});
}
// Or send to backend
fetch('/api/log-consent', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
variant: variant,
action: action,
timestamp: new Date().toISOString()
})
});
}
function getCookie(name) {
const value = ; ${document.cookie};
const parts = value.split(; ${name}=);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Testovacie premenné
Typ banneru
// Variant A: Simple banner
"notice_banner_type": "simple"
// Variant B: Headline banner
"notice_banner_type": "headline"
Farebná schéma
// Variant A: Light
"palette": "light"
// Variant B: Dark
"palette": "dark"
Text tlačidla (prostredníctvom vlastného CSS)
// Add CSS to change button text
const style = document.createElement('style');
style.textContent = variant === 'A'
? '.cc-nb-okagree::before { content: "Accept All"; }'
: '.cc-nb-okagree::before { content: "I Agree"; }';
document.head.appendChild(style);
Meranie zobrazení súhlasu
// Backend endpoint to analyze results
// GET /api/consent-analytics
{
"variant_A": {
"impressions": 1000,
"accepted": 650,
"declined": 250,
"no_action": 100,
"acceptance_rate": 0.65
},
"variant_B": {
"impressions": 1000,
"accepted": 720,
"declined": 200,
"no_action": 80,
"acceptance_rate": 0.72
}
}
Súhlas medzi doménami
Problém
„Naša hlavná stránka je www.example.com a náš obchod je shop.example.com. Používatelia dostávajú banner s informáciami o súboroch cookie na OBIDVOCH stránkach, aj keď už na prvej stránke súhlasili. Je to otravné a strácame konverzie.“
Porozumenie výzvam medzi doménami
V predvolenom nastavení sú súbory cookie obmedzené na konkrétnu doménu, kde sú nastavené:
- Súbor cookie nastavený na
www.example.com→ Nie je prístupný nashop.example.com - Súbor cookie nastavený na
shop.example.com→ Nie je prístupný nawww.example.com
Riešenie: parameter cookie_domain
Použite parameter cookie_domain na zdieľanie súhlasu medzi subdoménami:
cookieconsent.run({
"consent_type": "express",
"website_name": "My Website",
"website_privacy_policy_url": "https://www.example.com/privacy",
"cookie_domain": ".example.com", // Note the leading dot!
"page_load_consent_levels": ["strictly-necessary"]
});
Dôležité! Úvodná bodka (.example.com) sprístupňuje súbor cookie na:
example.comwww.example.comshop.example.comblog.example.com- Akejkoľvek subdoméne
example.com
Kompletný príklad medzi doménami
Na všetkých doménach/subdoménach použite identickú konfiguráciu:
<!-- On www.example.com -->
<script type="text/javascript" src="//www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
cookieconsent.run({
"notice_banner_type": "headline",
"consent_type": "express",
"palette": "light",
"language": "en",
"website_name": "Example",
"website_privacy_policy_url": "https://www.example.com/privacy",
"open_preferences_center_selector": "#changePreferences",
"page_load_consent_levels": ["strictly-necessary"],
"cookie_domain": ".example.com", // Shared across all subdomains
"cookie_secure": true // Recommended for production
});
});
</script>
<!-- On shop.example.com - SAME configuration -->
<script type="text/javascript" src="//www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
cookieconsent.run({
// EXACT SAME CONFIG as main domain
"notice_banner_type": "headline",
"consent_type": "express",
"palette": "light",
"language": "en",
"website_name": "Example",
"website_privacy_policy_url": "https://www.example.com/privacy",
"open_preferences_center_selector": "#changePreferences",
"page_load_consent_levels": ["strictly-necessary"],
"cookie_domain": ".example.com", // Same domain!
"cookie_secure": true
});
});
</script>
Otestujte nastavenie medzi doménami
- Navštívte
www.example.com - Prijmite súbory cookie
- Otvorte DevTools → Aplikácia → Cookies
- Overte, či doména súboru cookie zobrazuje
.example.com(s bodkou na začiatku) - Prejdite na
shop.example.com - Overte, či sa banner NEZOBRAZUJE (súhlas už bol udelený)
Bežné problémy s medzi doménami
Problém 1: Banner sa stále zobrazuje na subdoménach
Problém
„Nastavil som cookie_domain na ‚.example.com‘, ale banner sa stále zobrazuje na každej subdoméne.“
Príčina
Prehliadač blokuje súbory cookie tretích strán.
Riešenie
Uistite sa, že pre stránky HTTPS je nastavenie cookie_secure na hodnotu true.
// Make sure cookie_secure is true for HTTPS sites
"cookie_secure": true,
// Also verify in DevTools that cookie is actually being set
// Check: Application → Cookies → Look for cookie_consent_level
// Domain should show: .example.com (not www.example.com)
Problém 2: Rozdielny súhlas na rôznych subdoménach
Problém:
Používateľ udelí súhlas na hlavnej doméne, ale preferencie sa líšia na subdoméne.
Príčina:
Konfigurácie nie sú identické vo všetkých doménach.
Riešenie:
Použite zdieľaný konfiguračný súbor alebo premennú.
// shared-config.js (include on all domains)
const SHARED_COOKIE_CONFIG = {
"notice_banner_type": "headline",
"consent_type": "express",
"palette": "light",
"language": "en",
"website_name": "Example",
"website_privacy_policy_url": "https://www.example.com/privacy",
"open_preferences_center_selector": "#changePreferences",
"page_load_consent_levels": ["strictly-necessary"],
"cookie_domain": ".example.com",
"cookie_secure": true
};
// Then on each domain:
cookieconsent.run(SHARED_COOKIE_CONFIG);
Viac domén (rôzne TLD)
Problém:
Máte example.com A example.co.uk, teda úplne odlišné domény.
Riešenie:
Súbory cookie NEMOŽNO zdieľať medzi rôznymi doménami najvyššej úrovne z dôvodu zabezpečenia prehliadača.
Máte dve možnosti:
Možnosť 1: Akceptovať viacero bannerov.
- Používateľ vidí banner na každej doméne najvyššej úrovne
- Udelený súhlas platí individuálne pre každú doménu, súhlas sa nezdieľa
- Toto je pravdepodobne najviac vyhovujúci prístup
Možnosť 2: Použite synchronizáciu na pozadí (pre prihlásených používateľov)
// On example.com - user accepts
"callbacks": {
"user_consent_saved": () => {
if (isUserLoggedIn()) {
// Sync to backend
fetch('https://api.example.com/sync-consent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getUserToken()
},
body: JSON.stringify({
consent: getConsentState(),
domains: ['example.com', 'example.co.uk']
})
});
}
}
}
// On example.co.uk - check backend first
async function checkBackendConsent() {
if (isUserLoggedIn()) {
const response = await fetch('https://api.example.com/get-consent', {
headers: {'Authorization': 'Bearer ' + getUserToken()}
});
const data = await response.json();
if (data.hasConsent) {
// Set cookie locally
setCookieConsent(data.consentLevel);
}
}
}
Obnovenie stránky po udelení súhlasu
Problém
„Po tom, čo používateľ prijme súbory cookie, znovu načítajú stránku pomocou window.location.reload(), aby sa uistili, že sa načítajú skripty na sledovanie. To však spôsobuje, že Google Analytics stratí pôvodný zdroj odkazujúcej stránky a všetku návštevnosť zobrazuje ako „Priama“.“
K tomu dochádza, pretože pri opätovnom načítaní stránky:
- Prehliadač vymaže informácie o referrerovi
- Načítanie novej stránky vyzerá, ako keby pochádzalo z tej istej domény
- Google Analytics ju zaradí do kategórie „Priama“ návštevnosť
- Stratíte údaje o atribúcii
Riešenie 1: Neobnovujte stránku (odporúčané)
Použite spätné volania na dynamické načítanie skriptov namiesto opätovného načítania:
cookieconsent.run({
"notice_banner_type": "headline",
"consent_type": "express",
"palette": "light",
"language": "en",
"website_name": "My Site",
"website_privacy_policy_url": "https://mysite.com/privacy",
"page_load_consent_levels": ["strictly-necessary"],
"callbacks": {
"scripts_specific_loaded": (level) => {
// Scripts are NOW loaded - no reload needed!
console.log("Scripts loaded for: " + level);
if (level === 'tracking') {
// Analytics is now active
// Send initial page view if needed
if (typeof gtag !== 'undefined') {
gtag('event', 'page_view', {
'page_location': window.location.href,
'page_referrer': document.referrer
});
}
}
}
},
"callbacks_force": true
});
Riešenie 2: Zachovajte referrer pri opätovnom načítaní stránky
Ak MUSÍTE stránku načítať znovu, zachovajte referrer:
cookieconsent.run({
// ... config ...
"callbacks": {
"i_agree_button_clicked": () => {
// Store referrer and source before reload
sessionStorage.setItem('original_referrer', document.referrer);
sessionStorage.setItem('landing_page', window.location.href);
// Get URL parameters (utm_source, etc.)
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('utm_source')) {
sessionStorage.setItem('utm_source', urlParams.get('utm_source'));
sessionStorage.setItem('utm_medium', urlParams.get('utm_medium'));
sessionStorage.setItem('utm_campaign', urlParams.get('utm_campaign'));
}
// Now reload
window.location.reload();
}
}
});
// After reload, restore attribution
document.addEventListener('DOMContentLoaded', function() {
const savedReferrer = sessionStorage.getItem('original_referrer');
const utmSource = sessionStorage.getItem('utm_source');
if (savedReferrer && typeof gtag !== 'undefined') {
// Send page view with preserved referrer
gtag('event', 'page_view', {
'page_location': window.location.href,
'page_referrer': savedReferrer
});
// Send campaign data if available
if (utmSource) {
gtag('event', 'campaign_details', {
'campaign_source': utmSource,
'campaign_medium': sessionStorage.getItem('utm_medium'),
'campaign_name': sessionStorage.getItem('utm_campaign')
});
}
// Clear storage
sessionStorage.removeItem('original_referrer');
sessionStorage.removeItem('utm_source');
// ... clear others
}
});
Riešenie 3: Použite režim súhlasu Google (osvedčená prax)
S režimom súhlasu V2 nie je potrebné stránku načítať znovu:
<!-- 1. Set default consent to denied -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied'
});
</script>
<!-- 2. Load Google Analytics (runs in consent mode) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
<!-- 3. Cookie Consent with callbacks -->
<script src="//www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
cookieconsent.run({
"consent_type": "express",
"website_name": "My Site",
"page_load_consent_levels": ["strictly-necessary"],
"callbacks": {
"scripts_specific_loaded": (level) => {
// Update consent mode - NO RELOAD!
switch (level) {
case 'tracking':
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
break;
case 'targeting':
gtag('consent', 'update', {
'ad_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted'
});
break;
}
}
},
"callbacks_force": true
});
});
</script>
Vložený obsah a iFrames
Problém
„Na našej stránke máme vložené videá z YouTube. Mali by sme blokovať rámce iFrame, kým používatelia neprijmú súbory cookie? Ako to môžeme implementovať pomocou TermsFeed?“
Riešenie
Riešením je integrácia zástupného symbolu a použitie dynamického načítania.
Krok 1: Vytvorenie HTML zástupného symbolu
<!-- Instead of directly embedding iframe -->
<div class="video-placeholder" data-video-id="dQw4w9WgXcQ" data-consent-type="targeting">
<div class="placeholder-content">
<img src="/images/video-thumbnail.jpg" alt="Video thumbnail">
<div class="placeholder-overlay">
<button class="accept-and-load" onclick="loadVideo(this)">
Accept cookies to watch this video
</button>
<p>This video is hosted by YouTube and requires marketing cookies.</p>
<a href="#" onclick="openCookiePreferences(); return false;">
Change cookie preferences
</a>
</div>
</div>
</div>
<style>
.video-placeholder {
position: relative;
width: 100%;
padding-bottom: 56.25%; // 16:9 aspect ratio
background: #000;
}
.placeholder-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.placeholder-content img {
width: 100%;
height: 100%;
object-fit: cover;
}
.placeholder-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
text-align: center;
padding: 20px;
}
.accept-and-load {
background: #ff0000;
color: white;
border: none;
padding: 15px 30px;
font-size: 16px;
border-radius: 5px;
cursor: pointer;
margin-bottom: 15px;
}
</style>
Krok 2: Načítanie iFrame po udelení súhlasu
// Check if user has already consented
function hasConsent(consentType) {
const consentCookie = getCookie('cookie_consent_level');
if (!consentCookie) return false;
// Parse consent levels
const levels = JSON.parse(decodeURIComponent(consentCookie));
return levels.includes(consentType);
}
// Load video dynamically
function loadVideo(button) {
const placeholder = button.closest('.video-placeholder');
const videoId = placeholder.dataset.videoId;
const consentType = placeholder.dataset.consentType;
// Check if user has consent
if (!hasConsent(consentType)) {
// Request consent
if (typeof cookieconsent !== 'undefined' && cookieconsent.openPreferencesCenter) {
cookieconsent.openPreferencesCenter();
} else {
alert('Please accept marketing cookies to view this content');
}
return;
}
// Create iframe
const iframe = document.createElement('iframe');
iframe.src = https://www.youtube.com/embed/${videoId};
iframe.width = '100%';
iframe.height = '100%';
iframe.frameBorder = '0';
iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
iframe.allowFullscreen = true;
// Replace placeholder with iframe
placeholder.innerHTML = '';
placeholder.appendChild(iframe);
}
// Auto-load videos if consent already given
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.video-placeholder').forEach(placeholder => {
const consentType = placeholder.dataset.consentType;
if (hasConsent(consentType)) {
// Auto-load - user already consented
const videoId = placeholder.dataset.videoId;
const iframe = document.createElement('iframe');
iframe.src = https://www.youtube.com/embed/${videoId};
iframe.width = '100%';
iframe.height = '100%';
iframe.frameBorder = '0';
iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
iframe.allowFullscreen = true;
placeholder.innerHTML = '';
placeholder.appendChild(iframe);
}
});
});
// Listen for consent updates
document.addEventListener('DOMContentLoaded', function() {
cookieconsent.run({
// ... config ...
"callbacks": {
"scripts_specific_loaded": (level) => {
// When user accepts targeting cookies, load all pending videos
if (level === 'targeting') {
document.querySelectorAll('.video-placeholder').forEach(placeholder => {
if (placeholder.dataset.consentType === 'targeting') {
loadVideo(placeholder.querySelector('.accept-and-load'));
}
});
}
}
}
});
});
function getCookie(name) {
const value = ; ${document.cookie};
const parts = value.split(; ${name}=);
if (parts.length === 2) return parts.pop().split(';').shift();
}
function openCookiePreferences() {
if (typeof cookieconsent !== 'undefined' && cookieconsent.openPreferencesCenter) {
cookieconsent.openPreferencesCenter();
}
}
Príklad pre ďalšie vloženia
Google Maps
<div class="map-placeholder" data-consent-type="functionality" data-location="New York, NY">
<div class="placeholder-overlay">
<p>️ Accept functional cookies to view map</p>
<button onclick="loadMap(this)">Load Map</button>
</div>
</div>
<script>
function loadMap(button) {
const placeholder = button.closest('.map-placeholder');
const location = placeholder.dataset.location;
if (!hasConsent('functionality')) {
cookieconsent.openPreferencesCenter();
return;
}
const iframe = document.createElement('iframe');
iframe.src = https://www.google.com/maps/embed/v1/place?key=YOUR_API_KEY&q=${encodeURIComponent(location)};
iframe.width = '100%';
iframe.height = '450';
iframe.style.border = '0';
iframe.allowFullscreen = true;
iframe.loading = 'lazy';
placeholder.innerHTML = '';
placeholder.appendChild(iframe);
}
</script>
Vloženia zo sociálnych médií (X, Instagram, Facebook)
<div class="social-placeholder" data-consent-type="targeting" data-platform="twitter" data-url="https://twitter.com/user/status/123">
<div class="placeholder-overlay">
<p> Accept marketing cookies to view this tweet</p>
<button onclick="loadSocialEmbed(this)">Load Tweet</button>
</div>
</div>
<script>
function loadSocialEmbed(button) {
const placeholder = button.closest('.social-placeholder');
const platform = placeholder.dataset.platform;
const url = placeholder.dataset.url;
if (!hasConsent('targeting')) {
cookieconsent.openPreferencesCenter();
return;
}
// Load platform SDK
if (platform === 'twitter' && !window.twttr) {
const script = document.createElement('script');
script.src = 'https://platform.twitter.com/widgets.js';
script.onload = () => {
twttr.widgets.createTweet(
url.split('/').pop(),
placeholder,
{ theme: 'light' }
);
};
document.head.appendChild(script);
}
// Add other platforms as needed
}
</script>