Представьте: вы открываете сайт, а до нажатия кнопки «Согласен» уже сработал пиксель Facebook. Это прямое нарушение статьи 7 GDPR — требуется активное согласие. Результат — штраф до 4% оборота или 20 млн евро. Мы решаем это через consent-механизм с auto-blocking, который гарантирует, что трекинг-скрипты не загрузятся без явного согласия. За 5 лет мы внедрили более 50 решений — от простых баннеров до интеграции с OneTrust и кастомных систем. Один из проектов: на сайте интернет-магазина с посещаемостью 100k в месяц нашли скрытый скрипт Hotjar, работающий без согласия — после внедрения кастомного баннера с auto-blocking юридические риски снизились на 90%. Избежать штрафов помогает правильный consent-механизм. Получите консультацию по внедрению.
Почему важно разделение cookies на категории?
По GDPR cookies делятся на категории, и пользователь должен иметь возможность выбирать по каждой, а не просто «Принять все». Решение Суда Европейского союза C-252/21 подтвердило: галочки «Принять всё» недостаточно. Пользователь должен иметь возможность согласиться только на необходимые и, например, аналитические, но отказаться от маркетинговых. Мы реализуем интерфейс с чекбоксами по каждой категории, сохраняя выбор в localStorage и на сервере. Отказ должен быть так же прост, как согласие — кнопка «Только необходимые» на первом экране баннера.
| Категория | Примеры | Требует согласия |
|---|---|---|
| Strictly Necessary | Сессия, CSRF-токен, корзина | Нет |
| Functional | Язык, тема, сохранённые фильтры | Обычно нет |
| Analytics | Google Analytics, Яндекс.Метрика | Да |
| Marketing | Facebook Pixel, ремаркетинг, Adwords | Да |
Как работает auto-blocking mode?
Auto-blocking mode — механизм, который блокирует выполнение скриптов трекинга до получения согласия. Без него скрипты могут загрузиться до того, как пользователь дал согласие, что нарушает GDPR. Реализация может быть через готовые решения (Cookiebot, OneTrust) или кастомный загрузчик. Мы предпочитаем второй для полного контроля, так как он даёт гибкость в 10 раз выше по сравнению с типовыми баннерами. Например, кастомный загрузчик позволяет тонко настраивать блокировку скриптов в зависимости от категории и динамически подгружать ресурсы. Свяжитесь с нами для детального обсуждения архитектуры.
Пример загрузки Google Analytics только после согласия:
export function useAnalytics() {
const { consent } = useContext(CookieConsentContext);
useEffect(() => {
if (consent.analytics && !window.gtag) {
const script = document.createElement('script');
script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_ID}`;
document.head.appendChild(script);
window.dataLayer = window.dataLayer || [];
window.gtag = function() { window.dataLayer.push(arguments); };
window.gtag('js', new Date());
window.gtag('config', GA_ID, { anonymize_ip: true });
}
}, [consent.analytics]);
}
Как проверить, что баннер соответствует требованиям GDPR?
Основные критерии: пользователь должен дать активное согласие до загрузки скриптов, отказ должен быть так же прост, как согласие, а все записи о согласии должны храниться. Используйте инструменты вроде Cookie Scanner или расширение для браузера. Если скрипты загружаются до взаимодействия — баннер не соответствует стандартам. Наши инженеры проводят бесплатный аудит вашего сайта: закажите проверку.
Техническая реализация: от контекста до компонента
Приводим полноценный пример с контекстом и компонентом баннера. Код можно адаптировать под Next.js, Vue или чистый JavaScript.
// CookieConsentContext.tsx
interface ConsentState {
analytics: boolean;
marketing: boolean;
functional: boolean;
}
const CookieConsentContext = createContext<{
consent: ConsentState;
updateConsent: (updates: Partial<ConsentState>) => void;
hasResponded: boolean;
}>({} as any);
export function CookieConsentProvider({ children }: { children: ReactNode }) {
const [consent, setConsent] = useState<ConsentState>({
analytics: false,
marketing: false,
functional: false,
});
const [hasResponded, setHasResponded] = useState(false);
useEffect(() => {
const stored = localStorage.getItem('cookie_consent');
if (stored) {
const data = JSON.parse(stored);
setConsent(data.preferences);
setHasResponded(true);
}
}, []);
const updateConsent = (updates: Partial<ConsentState>) => {
const newConsent = { ...consent, ...updates };
const record = {
preferences: newConsent,
timestamp: new Date().toISOString(),
version: '1.0',
};
localStorage.setItem('cookie_consent', JSON.stringify(record));
setConsent(newConsent);
setHasResponded(true);
// Отправить запись на сервер
fetch('/api/consent', {
method: 'POST',
body: JSON.stringify(record),
});
};
return (
<CookieConsentContext.Provider value={{ consent, updateConsent, hasResponded }}>
{children}
</CookieConsentContext.Provider>
);
}
// CookieBanner.tsx
export function CookieBanner() {
const { hasResponded, updateConsent } = useContext(CookieConsentContext);
const [showDetails, setShowDetails] = useState(false);
const [selections, setSelections] = useState({
analytics: false, marketing: false, functional: true,
});
if (hasResponded) return null;
return (
<div className="cookie-banner" role="dialog" aria-label="Cookie consent">
<p>Мы используем cookies для улучшения работы сайта.</p>
{showDetails && (
<div className="cookie-categories">
<label>
<input type="checkbox" checked disabled />
Необходимые (всегда активны)
</label>
<label>
<input type="checkbox"
checked={selections.analytics}
onChange={e => setSelections(s => ({...s, analytics: e.target.checked}))}
/>
Аналитика
</label>
<label>
<input type="checkbox"
checked={selections.marketing}
onChange={e => setSelections(s => ({...s, marketing: e.target.checked}))}
/>
Маркетинг
</label>
</div>
)}
<div className="cookie-actions">
<button onClick={() => updateConsent({ analytics: false, marketing: false })}>
Только необходимые
</button>
<button onClick={() => setShowDetails(!showDetails)}>
Настроить
</button>
<button className="primary"
onClick={() => updateConsent({ analytics: true, marketing: true, functional: true })}>
Принять все
</button>
{showDetails && (
<button onClick={() => updateConsent(selections)}>
Сохранить выбор
</button>
)}
</div>
</div>
);
}
Хранение записей о согласии для compliance
Для compliance необходимо вести лог. Мы используем отдельную таблицу с идентификацией пользователя (IP + fingerprint) и полной историей. Каждая запись содержит timestamp, версию политики и список предпочтений. Это доказывает compliance при проверке.
// migrations/create_consent_records_table.php
Schema::create('consent_records', function (Blueprint $table) {
$table->id();
$table->string('user_identifier'); // IP + fingerprint или user_id
$table->json('preferences');
$table->string('version');
$table->ipAddress('ip_address');
$table->timestamp('consented_at');
$table->timestamp('withdrawn_at')->nullable();
});
Что входит в работу: этапы и deliverables
- Аудит текущих скриптов и cookies на сайте.
- Проектирование архитектуры consent-механизма (сервер + клиент).
- Разработка кастомного или настройка готового баннера.
- Реализация auto-blocking для трекинг-скриптов.
- Интеграция с аналитикой и CRM.
- Документация и обучение команды.
- Пост-релизная поддержка в течение месяца.
Deliverables:
- Документация по архитектуре и настройке
- Исходный код компонента и интеграции
- Инструкция по обновлению политики cookies
- Обучение команды (1 час вебинара)
- Пост-релизная поддержка 1 месяц
Сравнение кастомного и готового решения
| Параметр | Кастомная разработка | Готовое решение (Cookiebot, OneTrust) |
|---|---|---|
| Время внедрения | 3-5 дней | 1 день |
| Контроль над дизайном | Полный | Ограниченный |
| Производительность | <100ms прироста LCP | +200ms LCP из-за внешних скриптов |
| Стоимость | Индивидуально | От €12/мес |
| Auto-blocking | Да | Да |
| Хранение записей | Собственная база | Встроенное (ограничено по объёму) |
Кастомная реализация даёт полный контроль над дизайном, логикой и производительностью. Для проекта с уникальными требованиями мы рекомендуем кастом: прирост LCP может составлять до 200 мс.
Оценка текущей ситуации
Проведите аудит cookies с помощью расширения «Cookie Scanner» или через консоль браузера. Если вы нашли скрипты, которые загружаются без согласия, — время менять подход. Получите консультацию по интеграции — наши инженеры проанализируют ваш сайт бесплатно.







