Настройка принятие куки и счетчиков аналитики

Использование Яндекс.Метрики регулируется законом о персональных данных (например, ФЗ-152 в РФ), так как сервис собирает IP-адреса, cookie-файлы и данные о поведении людей. Для работы без нарушений нужно разместить на сайте Политику конфиденциальности, добавить баннер о сборе cookie с согласием и отключить передачу конфиденциальных данных

Мы подготовили код такого баннера, чтобы вы могли добавить его в Плагины, а также заменить в нем номера счетчиков на свои.

Визуально выглядит он так:

image.png

Чтобы установить этот код, перейдите в раздел ПлагиныСвой код и вставьте его в поле Код перед Head

image.png

<div id="cookie-banner" class="cookie-banner cookie-banner--hidden">
    <div class="cookie-banner__content">
        <p class="cookie-banner__text"> Мы используем Cookie. Во время посещения сайта вы соглашаетесь с тем, что в целях улучшения сервиса и обеспечения работоспособности сайта мы используем файлы Cookie и сервис веб-аналитики "Яндекс Метрика", обрабатываем персональные данные в соответствии с нашими
            <p> <a href="/privacy" target="_blank" class="cookie-banner__link">Пользовательское Соглашение</a> </p>
            <p> <a href="/cookie-policy" target="_blank" class="cookie-banner__link">Политика использования Cookie</a>
                <br> </p>
            <p> <a href="/obrabotka-dannykh" target="_blank" class="cookie-banner__link">Соглашение об обработке персональных данных</a>. </p>
            <div class="cookie-banner__actions">
                <button id="cookie-accept" class="cookie-btn cookie-btn--accept"> Разрешить все </button>
                <button id="cookie-reject" class="cookie-btn cookie-btn--reject"> Только необходимые </button>
                <button id="cookie-settings-btn" class="cookie-btn cookie-btn--settings"> Настроить </button>
            </div>
    </div>
</div>
<!-- Модальное окно настроек -->
<div id="cookie-modal" class="cookie-modal cookie-modal--hidden">
    <div class="cookie-modal__overlay" id="cookie-modal-overlay"></div>
    <div class="cookie-modal__window">
        <div class="cookie-modal__header">
            <h3>Настройки файлов cookie</h3>
            <button id="cookie-modal-close" class="cookie-modal__close"> &times; </button>
        </div>
        <div class="cookie-modal__body">
            <!-- Технические (нельзя отключить) -->
            <div class="cookie-option">
                <div class="cookie-option__info"> <strong>Необходимые</strong>
                    <p> Нужны для базовой работы сайта и сохранения ваших настроек приватности. </p>
                </div>
                <label class="cookie-toggle">
                    <input type="checkbox" checked disabled /> <span class="cookie-toggle__slider cookie-toggle__slider--disabled"></span> </label>
            </div>
            <!-- Аналитика -->
            <div class="cookie-option">
                <div class="cookie-option__info"> <strong>Аналитические</strong>
                    <p> Сбор анонимной статистики (Яндекс.Метрика, Google Analytics) для улучшения сайта. </p>
                </div>
                <label class="cookie-toggle">
                    <input type="checkbox" id="toggle-analytics" /> <span class="cookie-toggle__slider"></span> </label>
            </div>
            <!-- Маркетинг / Трекинг -->
            <div class="cookie-option">
                <div class="cookie-option__info"> <strong>Маркетинговые</strong>
                    <p>Трекинг (Roistat) для оценки эффективности рекламы.</p>
                </div>
                <label class="cookie-toggle">
                    <input type="checkbox" id="toggle-marketing" /> <span class="cookie-toggle__slider"></span> </label>
            </div>
        </div>
        <div class="cookie-modal__footer">
            <button id="cookie-save-preferences" class="cookie-btn cookie-btn--accept"> Сохранить выбор </button>
        </div>
    </div>
</div>

<style>
 .cookie-banner {
    position: fixed;
    bottom: 24px;
    left: 24px;
    right: 24px;
    max-width: 600px;
    background: #fff;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
    border-radius: 12px;
    padding: 20px;
    z-index: 9998;
    transition: transform 0.4s ease,
      opacity 0.4s ease;
    border: 1px solid #f0f0f0;
    font-family: sans-serif;
}

.cookie-banner--hidden {
    transform: translateY(40px);
    opacity: 0;
    pointer-events: none;
}

.cookie-banner__text {
    font-size: 14px;
    line-height: 1.5;
    color: #333;
    margin: 0 0 16px 0;
}

.cookie-banner__actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.cookie-btn {
    padding: 10px 20px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.2s;
    border: none;
}

.cookie-btn--accept {
    background: #111;
    color: #fff;
}

.cookie-btn--accept:hover {
    background: #222;
}

.cookie-btn--reject {
    background: #f5f5f7;
    color: #555;
}

.cookie-btn--reject:hover {
    background: #e8e8ed;
}

.cookie-btn--settings {
    background: transparent;
    color: #111;
    text-decoration: underline;
    padding: 10px;
}

.cookie-modal {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 1;
    visibility: visible;
    transition: opacity 0.3s ease;
    font-family: sans-serif;
}

.cookie-modal--hidden {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.cookie-modal__overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
}

.cookie-modal__window {
    position: relative;
    background: #fff;
    width: 100%;
    max-width: 700px;
    border-radius: 12px;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
    margin: 20px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
}

.cookie-modal__header {
    padding: 20px;
    border-bottom: 1px solid #eee;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.cookie-modal__header h3 {
    margin: 0;
    font-size: 18px;
}

.cookie-modal__close {
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    color: #999;
}

.cookie-modal__body {
    padding: 20px;
    overflow-y: auto;
}

.cookie-modal__footer {
    padding: 20px;
    border-top: 1px solid #eee;
    display: flex;
    justify-content: flex-end;
}

.cookie-option {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 0;
    border-bottom: 1px solid #f5f5f5;
}

.cookie-option:last-child {
    border-bottom: none;
}

.cookie-option__info {
    padding-right: 20px;
}

.cookie-option__info strong {
    display: block;
    margin-bottom: 4px;
    font-size: 15px;
}

.cookie-option__info p {
    margin: 0;
    font-size: 13px;
    color: #666;
    line-height: 1.4;
}

.cookie-toggle {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
}

.cookie-toggle input {
    opacity: 0;
    width: 0;
    height: 0;
}

.cookie-toggle__slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background-color: #ccc;
    transition: 0.3s;
    border-radius: 24px;
}

.cookie-toggle__slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.3s;
    border-radius: 50%;
}

.cookie-toggle input:checked + .cookie-toggle__slider {
    background-color: green;
}

.cookie-toggle input:checked + .cookie-toggle__slider:before {
    transform: translateX(20px);
}

.cookie-toggle__slider--disabled {
    background-color: #e0e0e0;
    cursor: not-allowed;
}

.cookie-toggle input:checked + .cookie-toggle__slider--disabled {
    background-color: #888;
}

.cookie-banner__link {
    color: #111111;
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color 0.2s ease;
}

.cookie-banner__link:hover {
    color: #666666;
}
</style>

<script>
(function() {
    const COOKIE_PREFS_KEY = 'site_cookie_preferences_v3';
    const COUNTERS_CONFIG = {
        yandexMetrika: 104245192,
        googleAnalytics: null,
        roistat: null
    };
    const defaultPrefs = {
        resolved: false,
        analytics: false,
        marketing: false
    };
    let prefs = defaultPrefs;
    const cookieString = document.cookie.split('; ').find(row => row.startsWith(COOKIE_PREFS_KEY + '='));
    if(cookieString) {
        try {
            prefs = JSON.parse(decodeURIComponent(cookieString.split('=')[1]));
        } catch(e) {}
    }
    const TRACKERS = {
        analytics: ['mc.yandex.ru', 'google-analytics.com', 'googletagmanager.com'],
        marketing: ['cloud.roistat.com', 'roistat.com', 'mod.calltouch.ru']
    };

    function isTrackerBlocked(src) {
        if(!src || typeof src !== 'string') return false;
        if(!prefs.analytics && TRACKERS.analytics.some(d => src.includes(d))) return true;
        if(!prefs.marketing && TRACKERS.marketing.some(d => src.includes(d))) return true;
        return false;
    }
    const originalCreateElement = document.createElement;
    document.createElement = function(tagName) {
        const el = originalCreateElement.apply(this, arguments);
        if(tagName.toLowerCase() === 'script') {
            let srcValue = '';
            Object.defineProperty(el, 'src', {
                get: function() {
                    return srcValue;
                },
                set: function(val) {
                    srcValue = val;
                    if(isTrackerBlocked(val)) el.type = 'javascript/blocked';
                    el.setAttribute('src', val);
                }
            });
        }
        return el;
    };
    const originalAppendChild = Node.prototype.appendChild;
    Node.prototype.appendChild = function(node) {
        if(node.tagName === 'SCRIPT' && isTrackerBlocked(node.src)) node.type = 'javascript/blocked';
        return originalAppendChild.apply(this, arguments);
    };
    const originalInsertBefore = Node.prototype.insertBefore;
    Node.prototype.insertBefore = function(newNode, referenceNode) {
        if(newNode.tagName === 'SCRIPT' && isTrackerBlocked(newNode.src)) newNode.type = 'javascript/blocked';
        return originalInsertBefore.apply(this, arguments);
    };
    const originalSetItem = Storage.prototype.setItem;
    Storage.prototype.setItem = function(key, value) {
        if(typeof key === 'string') {
            let shouldBlock = false;
            if(!prefs.analytics && (key.startsWith('_ym') || key.startsWith('_ga') || key === 'user_visit')) shouldBlock = true;
            if(!prefs.marketing && (key.startsWith('roistat') || key.startsWith('_fbp'))) shouldBlock = true;
            if(shouldBlock) return;
        }
        return originalSetItem.apply(this, arguments);
    };

    function sweepData() {
        const domain = window.location.hostname.replace('www.', '');
        document.cookie.split(";").forEach(c => {
            const name = c.split("=")[0].trim();
            let shouldDel = false;
            if(!prefs.analytics && (name.startsWith('_ym') || name === '_yasc' || name.startsWith('_ga') || name.startsWith('_gid'))) shouldDel = true;
            if(!prefs.marketing && (name.startsWith('roistat') || name.startsWith('_fbp'))) shouldDel = true;
            if(shouldDel) {
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${domain}`;
                document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;`;
            }
        });
        try {
            ['localStorage', 'sessionStorage'].forEach(st => {
                const storage = window[st];
                if(!storage) return;
                const keysToDel = [];
                for(let i = 0; i < storage.length; i++) {
                    const k = storage.key(i);
                    if(!k) continue;
                    if(!prefs.analytics && (k.startsWith('_ym') || k.startsWith('_ga') || k === 'user_visit')) keysToDel.push(k);
                    if(!prefs.marketing && (k.startsWith('roistat') || k.startsWith('_fbp'))) keysToDel.push(k);
                }
                keysToDel.forEach(k => storage.removeItem(k));
            });
        } catch(e) {}
    }
    if(!prefs.resolved || !prefs.analytics || !prefs.marketing) {
        sweepData();
        const sweepInterval = setInterval(sweepData, 200);
        setTimeout(() => clearInterval(sweepInterval), 4000);
    }
    document.addEventListener('DOMContentLoaded', () => {
        const banner = document.getElementById('cookie-banner');
        const modal = document.getElementById('cookie-modal');
        const acceptBtn = document.getElementById('cookie-accept');
        const rejectBtn = document.getElementById('cookie-reject');
        const settingsBtn = document.getElementById('cookie-settings-btn');
        const closeModalBtn = document.getElementById('cookie-modal-close');
        const overlay = document.getElementById('cookie-modal-overlay');
        const savePrefsBtn = document.getElementById('cookie-save-preferences');
        const toggleAnalytics = document.getElementById('toggle-analytics');
        const toggleMarketing = document.getElementById('toggle-marketing');
        if(!prefs.resolved) {
            setTimeout(() => banner.classList.remove('cookie-banner--hidden'), 1000);
        } else {
            applyCustomCounters(prefs);
        }

        function saveAndReload(newPrefs) {
            newPrefs.resolved = true;
            const d = new Date();
            d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000));
            document.cookie = `${COOKIE_PREFS_KEY}=${encodeURIComponent(JSON.stringify(newPrefs))}; expires=${d.toUTCString()}; path=/; SameSite=Lax; Secure`;
            window.location.reload();
        }
        acceptBtn.addEventListener('click', () => saveAndReload({
            analytics: true,
            marketing: true
        }));
        rejectBtn.addEventListener('click', () => saveAndReload({
            analytics: false,
            marketing: false
        }));
        settingsBtn.addEventListener('click', () => {
            toggleAnalytics.checked = prefs.analytics;
            toggleMarketing.checked = prefs.marketing;
            modal.classList.remove('cookie-modal--hidden');
        });
        const closeModal = () => modal.classList.add('cookie-modal--hidden');
        closeModalBtn.addEventListener('click', closeModal);
        overlay.addEventListener('click', closeModal);
        savePrefsBtn.addEventListener('click', () => {
            saveAndReload({
                analytics: toggleAnalytics.checked,
                marketing: toggleMarketing.checked
            });
        });

        function applyCustomCounters(currentPrefs) {
            if(currentPrefs.analytics && COUNTERS_CONFIG.yandexMetrika) {
                if(window[`ymab_${COUNTERS_CONFIG.yandexMetrika}`] || typeof ym === 'function') return;
                (function(m, e, t, r, i, k, a) {
                    m[i] = m[i] || function() {
                        (m[i].a = m[i].a || []).push(arguments)
                    };
                    m[i].l = 1 * new Date();
                    for(var j = 0; j < e.length; j++) {
                        if(e[j].src === r) {
                            return;
                        }
                    }
                    k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a)
                })
                (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
                ym(COUNTERS_CONFIG.yandexMetrika, "init", {
                    clickmap: true,
                    trackLinks: true,
                    accurateTrackBounce: true,
                    webvisor: true
                });
            }
        }
    });
})();
</script>

В коде найдите строки, которые отвечают за номера счетчиков (вместо null пишем свои номера счетчиков), они должны быть сразу после открывающего тега script

telegram-cloud-photo-size-2-5427283459241090584-x.jpg
Обратите внимание, что данный плагин является экспериментальным и данных по нему мало, поэтому если вы заметите какие-либо расхождения, пожалуйста, сообщите об этом в поддержку.

ТЕХНИЧЕСКАЯ ПОДДЕРЖКА

Не можете найти то, что ищете?

Напишите нам. Мы на связи с 7:00 до 22:00 без выходных. Среднее время ожидания ответа: 10-15 минут. Также вы можете вступить в наш Телеграм-чат, где собралось много специалистов и пользователей.

Поддержка Creatium

Агенты ответят через 10 минут

Агенты ответят

Блог, курсы и полезные материалы 

Платформа сайтов любой сложности