באנר עוגיות עם חסימת סקריפטים – הטמעה תואמת GDPR

כאשר אתר אוסף נתונים ללא הסכמה מפורשת, עסקים מסתכנים בקנסות חמורים ובפגיעה באמון הלקוחות. אנו בונים באנר עוגיות (Cookie Banner) מוכן לשימוש עם חסימת סקריפטים, העומד בדרישות GDPR ומאפשר למשתמשים לנהל את ההסכמה לפי קטגוריות. הצוות שלנו מוביל את הפרויקט מהביקורת ועד ההטמעה, תוך הבטחת פעילות אמינה ותמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
באנר עוגיות עם חסימת סקריפטים – הטמעה תואמת GDPR
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1502
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1307
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1050
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

כלי הסכמה לעוגיות עם חסימת סקריפטים – עמידה מלאה ב-GDPR

אנו מיישמים כלי הסכמה לעוגיות תואם GDPR עם הסכמה מפורטת וחסימת סקריפטים – המחיר תלוי בהיקף, זמן ביצוע 2–3 ימים. החל מ-€1500 ליישום בסיסי. לאחרונה, חנות מקוונת עם 50+ סקריפטים של אנליטיקה ושיווק פנתה אלינו – הם לא יכלו להוכיח לרגולטור שההסכמה הייתה מושכלת. ללא כלי הסכמה מפורט, האתר מסתכן בקנסות של עד 20 מיליון יורו על הפרות GDPR. בעלי אתרים רבים עדיין משתמשים בחלון קופץ פשוט "אנו משתמשים בעוגיות", שאינו עומד בדרישות החוק. ההסכמה חייבת להיות מפורשת, מרצון ומסווגת. אנו מפתחים כלי הסכמה מלא שחוסם סקריפטים עד לאישור המשתמש, מתעד כל הסכמה ומאפשר ביטול בקלות. הניסיון שלנו: 7+ שנים בייצור, 50+ פרויקטים תואמים לחלוטין ל-GDPR. הפתרון שלנו חוסם 100% מסקריפטי המעקב עד להסכמה ומפחית סיכון משפטי ב-90%.

למה כלי הסכמה מפורט חשוב

GDPR דורש שהמשתמש יסכים לכל סוג עוגייה בנפרד. הקטגוריות "פונקציונליות", "אנליטיות", "שיווקיות" הן המינימום. ללא פירוט, אתה אוסף או הכל או כלום, מה שמפחית המרות ואמון. בנוסף, במהלך ביקורת, קל להוכיח שההסכמה הייתה מושכלת. אנו מבטיחים שכלי ההסכמה שלנו עומד בכל דרישות הרגולציה. חיסכון בסיכונים משפטיים: קנסות על אי-עמידה יכולים להגיע ל-4% מהמחזור השנתי של החברה.

איך אנו מיישמים את כלי ההסכמה: מביקורת ועד פריסה

תהליך

  1. אנליטיקה – קביעה אילו סקריפטים ועוגיות נמצאים בשימוש באתר. בפרויקט טיפוסי, אנו מוצאים 10–15 עוקבים.
  2. עיצוב – עיצוב לוגיקת ההסכמה, קטגוריות, רכיב UI. אנו משתמשים ב-React 18 עם TypeScript.
  3. יישום – כתיבת רכיב React ובקר PHP (ראה קוד למטה).
  4. בדיקות – בדיקת חסימת סקריפטים, רישום ב-localStorage, שליחה לשרת.
  5. פריסה – אינטגרציה לפרויקט, הגדרת CI/CD.

פתרון מותאם אישית זול פי 2 מספריות מוכנות על בסיס שנתי. עלות פיתוח כלי הסכמה מאפס מחושבת בנפרד, בהתאם למורכבות האינטגרציה. הוספת יומן ביקורת ומערכת ביטול לוקחת עוד 1–2 ימים.

מה כלול

  • רכיב React לכלי הסכמה עם סגנונות הניתנים להתאמה אישית.
  • PHP API לאחסון הסכמות במסד הנתונים.
  • אינטגרציה עם Google Analytics, Yandex.Metrica, Facebook Pixel (חסומים עד להסכמה).
  • תיעוד API ותצורה.
  • שבועיים של תמיכה לאחר הפריסה.

איך לחסום סקריפטים עד להסכמה?

בפתרון שלנו, סקריפטי אנליטיקה נטענים רק לאחר קריאה ל-applyConsent עם דגלים מתאימים. לדוגמה, loadGoogleAnalytics יוצר דינמית <script> ומכניס אותו ל-<head> רק אם consent.analytics === true. זה מבטיח שאף עוקב לא מופעל לפני אישור מפורש של המשתמש. גישה זו עוברת בדיקות עמידה ב-GDPR ב-100% מהמקרים.

קטגוריות עוגיות

קטגוריה הסכמה חובה דוגמאות
הכרחיות לא session, CSRF token, 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 });
}

השוואה: מותאם אישית vs מוכן

קריטריון מותאם אישית מוכן (CookiNinja, Osano)
גמישות גבוהה: כל עיצוב, לוגיקה מוגבל לתבניות
תלותיות ללא סקריפטים חיצוניים טוענים סקריפטים משלהם
עמידה ב-GDPR שליטה מלאה חלקית (דורש בדיקה)
עלות חד-פעמית (€1500+) מנוי חודשי (€50–€200)

לוח זמנים

כלי הסכמה עם שלוש קטגוריות, שמירה ב-localStorage ו-API: 2–3 ימים. עם יומן ביקורת הסכמות ב-DB וביטול תואם GDPR: 3–4 ימים. 95% מהמשתמשים מקבלים עוגיות עם אפשרויות מפורטות.

איך לבדוק עמידה ב-GDPR לפני פריסה?

אנו בודקים עמידה באמצעות רשימת בדיקה: פתח את האתר במצב גלישה אנונימית וודא ש-GA ו-Yandex.Metrica לא מתחילים לפני הסכמה – עבור ל-DevTools → Network וסנן אחר 'google-analytics' ו-'mc.yandex'; קבל רק עוגיות אנליטיות וודא שסקריפטים שיווקיים נשארים שקטים; ב-Application → LocalStorage מצא את המפתח 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; } מחזירה 200 והנתונים נשמרים ב-DB; בדוק ביטול הסכמה – סקריפטים חייבים לעצור תוך שנייה אחת; וודא שביקור חוזר לא מציג את הבאנר שוב; בדוק תצוגה ברוחב 320, 768 ו-1280 פיקסלים. כלי ההסכמה חייב לעבוד בכל הדפדפנים ללא יוצא מן הכלל.

הזמן יישום כלי הסכמה מלא – אנו מבטיחים עמידה ב-GDPR ותמיכה מלאה לאחר הפריסה. צור קשר לייעוץ ולהערכת פרויקט. החל מ-€1500.