Реализация Cookie-бара на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Cookie-бара на сайте
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация cookie-баннера

Cookie-баннер информирует посетителей об использовании куков и получает согласие до их установки. GDPR требует: согласие добровольное, явное, гранулярное (по категориям), легко отзываемое.

Категории куков

Категория Обязательное согласие Примеры
Необходимые Нет session, CSRF-токен, cookie-consent
Функциональные Да язык, тема, помнить меня
Аналитические Да Google Analytics, Yandex.Metrica
Маркетинговые Да Google Ads, Facebook Pixel

React компонент

import { useState, useEffect } from 'react';

interface CookieConsent {
  functional: boolean;
  analytics: boolean;
  marketing: boolean;
}

const CONSENT_KEY = 'cookie_consent_v2';

function useCookieConsent() {
  const [consent, setConsent] = useState<CookieConsent | null>(null);
  const [showBanner, setShowBanner] = useState(false);

  useEffect(() => {
    const saved = localStorage.getItem(CONSENT_KEY);
    if (saved) {
      const parsed = JSON.parse(saved);
      setConsent(parsed);
      applyConsent(parsed);
    } else {
      setShowBanner(true);
    }
  }, []);

  const acceptAll = () => {
    const all = { functional: true, analytics: true, marketing: true };
    save(all);
  };

  const rejectAll = () => {
    const none = { functional: false, analytics: false, marketing: false };
    save(none);
  };

  const save = (c: CookieConsent) => {
    localStorage.setItem(CONSENT_KEY, JSON.stringify({
      ...c,
      updatedAt: new Date().toISOString(),
    }));
    setConsent(c);
    setShowBanner(false);
    applyConsent(c);
    reportConsent(c);
  };

  return { consent, showBanner, acceptAll, rejectAll, save, openSettings: () => setShowBanner(true) };
}

function applyConsent(consent: CookieConsent) {
  // Включить/выключить скрипты аналитики
  if (consent.analytics) {
    loadGoogleAnalytics();
    loadYandexMetrica();
  }
  if (consent.marketing) {
    loadFacebookPixel();
  }
}

async function reportConsent(consent: CookieConsent) {
  await fetch('/api/cookie-consent', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ consent, ip: undefined }),  // IP определяет сервер
  });
}

export function CookieBanner() {
  const { showBanner, acceptAll, rejectAll, save } = useCookieConsent();
  const [showDetails, setShowDetails] = useState(false);
  const [selections, setSelections] = useState({ functional: false, analytics: false, marketing: false });

  if (!showBanner) return null;

  return (
    <div className="cookie-banner" role="dialog" aria-label="Настройки cookies">
      <div className="cookie-banner__content">
        <h2>Мы используем cookies</h2>
        <p>
          Мы используем необходимые куки для работы сайта. С вашего согласия — аналитические и маркетинговые.{' '}
          <a href="/cookie-policy">Подробнее</a>
        </p>

        {showDetails && (
          <div className="cookie-categories">
            <label className="cookie-category cookie-category--required">
              <input type="checkbox" checked disabled />
              <span>Необходимые</span>
              <small>Всегда включены. Обеспечивают базовую работу сайта.</small>
            </label>

            {(['functional', 'analytics', 'marketing'] as const).map(cat => (
              <label key={cat} className="cookie-category">
                <input
                  type="checkbox"
                  checked={selections[cat]}
                  onChange={e => setSelections(s => ({ ...s, [cat]: e.target.checked }))}
                />
                <span>{{ functional: 'Функциональные', analytics: 'Аналитические', marketing: 'Маркетинговые' }[cat]}</span>
              </label>
            ))}
          </div>
        )}

        <div className="cookie-banner__actions">
          <button onClick={rejectAll} className="btn btn--outline">Отклонить всё</button>
          <button onClick={() => setShowDetails(!showDetails)} className="btn btn--outline">Настроить</button>
          {showDetails
            ? <button onClick={() => save(selections)} className="btn btn--primary">Сохранить</button>
            : <button onClick={acceptAll} className="btn btn--primary">Принять всё</button>
          }
        </div>
      </div>
    </div>
  );
}
.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: white;
  border-top: 1px solid #e5e7eb;
  box-shadow: 0 -4px 24px rgba(0,0,0,0.08);
  z-index: 9999;
  padding: 1.5rem;
}
.cookie-banner__actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}

Сервер: фиксация согласия

class CookieConsentController extends Controller
{
    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'consent.functional' => 'required|boolean',
            'consent.analytics'  => 'required|boolean',
            'consent.marketing'  => 'required|boolean',
        ]);

        CookieConsent::create([
            'user_id'       => auth()->id(),
            'session_id'    => $request->session()->getId(),
            'ip'            => $request->ip(),
            'user_agent'    => $request->userAgent(),
            'consent'       => $request->consent,
            'version'       => config('cookies.policy_version', '2.0'),
            'consented_at'  => now(),
        ]);

        return response()->json(['status' => 'saved']);
    }
}

Подключение Google Analytics только с согласием

function loadGoogleAnalytics() {
  if (document.getElementById('ga-script')) return;  // уже загружен

  const script = document.createElement('script');
  script.id = 'ga-script';
  script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_ID}`;
  script.async = true;
  document.head.appendChild(script);

  window.dataLayer = window.dataLayer || [];
  function gtag(...args: unknown[]) { window.dataLayer.push(args); }
  gtag('js', new Date());
  gtag('config', GA_ID, { anonymize_ip: true });
}

Срок реализации

Cookie-баннер с тремя категориями, сохранением согласия в localStorage и API: 2–3 дня. С аудит-логом согласий в БД и GDPR-совместимым отзывом: 3–4 дня.