1. הדביקו את הקטע
הניחו את הקוד שנוצר ממש לפני תג הסגירה body בכל עמוד. אין לו תלויות והוא לא מוסיף בקשות רשת.
כלי חינמי
בחרו את קטגוריות העוגיות, כתבו את הטקסט, בחרו מראה — והעתיקו באנר הסכמה ללא תלויות שאפשר להדביק בכל אתר. הוא שומר את בחירת המבקר, משאיר סקריפטים מתויגים חסומים עד שהקטגוריה שלהם מאושרת, וניתן לפתוח אותו מחדש מקישור בכותרת התחתונה.
באנר ההסכמה שלכם
הדביקו זאת ממש לפני תג הסגירה body, בכל עמוד.
<!-- Cookie consent banner - paste this just before </body> -->
<script>
(function () {
var CFG = {
"storageKey": "cookie_consent",
"position": "bar",
"theme": "light",
"accent": "#a6144d",
"title": "אנחנו משתמשים בעוגיות",
"message": "אנחנו משתמשים בעוגיות כדי להפעיל את האתר, להבין כיצד משתמשים בו ולשפר אותו. אפשר לאשר הכול, לדחות את מה שאופציונלי, או לבחור לפי קטגוריה.",
"policyUrl": "https://example.com/privacy",
"policyLabel": "קראו את מדיניות הפרטיות שלנו",
"accept": "אישור הכול",
"reject": "דחיית האופציונלי",
"prefs": "העדפות",
"save": "שמירת הבחירות",
"categories": [
{
"id": "necessary",
"label": "הכרחיות",
"desc": "נדרשות לתפקוד האתר. תמיד פעילות ולעולם לא מבקשות הסכמה.",
"required": true
},
{
"id": "analytics",
"label": "אנליטיקה",
"desc": "מודדת כיצד משתמשים באתר כדי לשפר אותו.",
"required": false
},
{
"id": "marketing",
"label": "שיווק",
"desc": "משמשת להתאמת פרסומות ולמדידת קמפיינים.",
"required": false
}
]
};
var KEY = CFG.storageKey;
var doc = document;
var box = null;
function read() {
try { return JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) { return null; }
}
function save(consent) {
consent.necessary = true;
consent.date = new Date().toISOString();
try { localStorage.setItem(KEY, JSON.stringify(consent)); } catch (e) {}
unblock(consent);
window.dispatchEvent(new CustomEvent('consentchange', { detail: consent }));
if (typeof window.onConsentChange === 'function') window.onConsentChange(consent);
}
// Scripts the site parked behind a category run only once it is granted. Park
// one by giving its tag type="text/plain" and data-consent="analytics".
// (Deliberately described, not shown: a literal script tag written out here
// would close this one early and truncate everything below it.)
function unblock(consent) {
var parked = doc.querySelectorAll('script[type="text/plain"][data-consent]');
for (var i = 0; i < parked.length; i++) {
var old = parked[i];
if (!consent[old.getAttribute('data-consent')]) continue;
var next = doc.createElement('script');
for (var a = 0; a < old.attributes.length; a++) {
var at = old.attributes[a];
if (at.name !== 'type' && at.name !== 'data-consent') next.setAttribute(at.name, at.value);
}
next.text = old.text;
old.parentNode.replaceChild(next, old);
}
}
function styles() {
var dark = CFG.theme === 'dark';
var bg = dark ? '#161622' : '#ffffff';
var fg = dark ? '#f4f4f8' : '#141a47';
var muted = dark ? 'rgba(244,244,248,.72)' : 'rgba(20,26,71,.7)';
var line = dark ? 'rgba(255,255,255,.14)' : 'rgba(20,26,71,.12)';
var el = doc.createElement('style');
el.textContent = [
'.cc-root{position:fixed;z-index:2147483000;font:400 14px/1.55 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:' + fg + ';box-sizing:border-box}',
'.cc-root *,.cc-root *::before,.cc-root *::after{box-sizing:inherit}',
'.cc-card{background:' + bg + ';border:1px solid ' + line + ';box-shadow:0 18px 48px rgba(0,0,0,.18);border-radius:14px;padding:20px}',
'.cc-bar{left:0;right:0;bottom:0;padding:16px}',
'.cc-bar .cc-card{display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;max-width:1120px;margin:0 auto}',
'.cc-box{left:16px;bottom:16px;max-width:400px}',
'.cc-modal{inset:0;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(10,10,20,.5)}',
'.cc-modal .cc-card{max-width:520px;width:100%}',
'.cc-title{margin:0 0 6px;font-size:16px;font-weight:700}',
'.cc-text{margin:0;color:' + muted + '}',
'.cc-text a{color:' + CFG.accent + ';font-weight:600}',
'.cc-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}',
'.cc-bar .cc-actions{margin-top:0}',
'.cc-btn{appearance:none;cursor:pointer;border:1px solid ' + line + ';border-radius:999px;padding:9px 18px;font:600 14px inherit;background:transparent;color:' + fg + '}',
'.cc-btn-main{background:' + CFG.accent + ';border-color:' + CFG.accent + ';color:#fff}',
'.cc-btn:focus-visible{outline:2px solid ' + CFG.accent + ';outline-offset:2px}',
'.cc-cats{display:none;margin:14px 0 0;padding:14px 0 0;border-top:1px solid ' + line + '}',
'.cc-cats.cc-open{display:block}',
'.cc-cat{display:flex;gap:10px;align-items:flex-start;margin-bottom:12px}',
'.cc-cat input{margin:3px 0 0;accent-color:' + CFG.accent + '}',
'.cc-cat strong{display:block;font-size:14px}',
'.cc-cat span{display:block;color:' + muted + ';font-size:13px}',
'@media(max-width:640px){.cc-bar .cc-card{display:block}.cc-bar .cc-actions{margin-top:14px}.cc-btn{flex:1 1 auto}}'
].join('');
doc.head.appendChild(el);
}
function build() {
var stored = read() || {};
var root = doc.createElement('div');
root.className = 'cc-root cc-' + CFG.position;
root.setAttribute('role', CFG.position === 'modal' ? 'dialog' : 'region');
root.setAttribute('aria-label', CFG.title);
if (CFG.position === 'modal') root.setAttribute('aria-modal', 'true');
var card = doc.createElement('div');
card.className = 'cc-card';
var copy = doc.createElement('div');
var h = doc.createElement('p');
h.className = 'cc-title';
h.textContent = CFG.title;
var p = doc.createElement('p');
p.className = 'cc-text';
p.textContent = CFG.message + ' ';
if (CFG.policyUrl) {
var link = doc.createElement('a');
link.href = CFG.policyUrl;
link.textContent = CFG.policyLabel;
p.appendChild(link);
}
copy.appendChild(h);
copy.appendChild(p);
var cats = doc.createElement('div');
cats.className = 'cc-cats';
var inputs = {};
for (var i = 0; i < CFG.categories.length; i++) {
var c = CFG.categories[i];
var row = doc.createElement('label');
row.className = 'cc-cat';
var cb = doc.createElement('input');
cb.type = 'checkbox';
cb.checked = c.required || stored[c.id] === true;
cb.disabled = !!c.required;
var txt = doc.createElement('div');
var name = doc.createElement('strong');
name.textContent = c.label;
var desc = doc.createElement('span');
desc.textContent = c.desc;
txt.appendChild(name);
txt.appendChild(desc);
row.appendChild(cb);
row.appendChild(txt);
cats.appendChild(row);
inputs[c.id] = cb;
}
copy.appendChild(cats);
var actions = doc.createElement('div');
actions.className = 'cc-actions';
function button(label, main, onClick) {
var b = doc.createElement('button');
b.type = 'button';
b.className = 'cc-btn' + (main ? ' cc-btn-main' : '');
b.textContent = label;
b.addEventListener('click', onClick);
actions.appendChild(b);
return b;
}
function decide(granted) {
var consent = {};
for (var i = 0; i < CFG.categories.length; i++) {
var c = CFG.categories[i];
consent[c.id] = c.required ? true : granted === null ? !!inputs[c.id].checked : granted;
}
save(consent);
close();
}
var prefsBtn = button(CFG.prefs, false, function () {
var open = cats.classList.toggle('cc-open');
prefsBtn.setAttribute('aria-expanded', open ? 'true' : 'false');
saveBtn.style.display = open ? '' : 'none';
});
prefsBtn.setAttribute('aria-expanded', 'false');
button(CFG.reject, false, function () { decide(false); });
button(CFG.accept, true, function () { decide(true); });
var saveBtn = button(CFG.save, false, function () { decide(null); });
saveBtn.style.display = 'none';
card.appendChild(copy);
card.appendChild(actions);
root.appendChild(card);
doc.body.appendChild(root);
box = root;
}
function close() {
if (box && box.parentNode) box.parentNode.removeChild(box);
box = null;
}
function open() {
if (!box) build();
}
function start() {
styles();
var stored = read();
if (stored) unblock(stored);
else build();
window.showConsentPreferences = open;
}
if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', start);
else start();
})();
</script> איך משתמשים
הניחו את הקוד שנוצר ממש לפני תג הסגירה body בכל עמוד. אין לו תלויות והוא לא מוסיף בקשות רשת.
שנו את סוג תג המעקב ל-text/plain והוסיפו data-consent="analytics". הבאנר מריץ אותו ברגע שהקטגוריה מאושרת — ולעולם לא לפני כן.
הוסיפו קישור בכותרת התחתונה שקורא ל-window.showConsentPreferences() כדי שמבקרים יוכלו לפתוח מחדש את הפאנל. כל החלטה גם מפעילה אירוע consentchange שאפשר להאזין לו.
שאלות נפוצות
הוא נותן לכם את המנגנון שהרגולטורים מצפים לו: אין עוגיות אופציונליות לפני הסכמה, דחייה קלה כמו אישור, בחירה לפי קטגוריה ודרך לשנות את דעתכם אחר כך. העמידה בדרישות תלויה גם במה שאתם באמת מריצים, במה שכתוב במדיניות שלכם והיכן נמצאים המבקרים שלכם, לכן התייחסו לקוד שנוצר כנקודת פתיחה טובה ולא כייעוץ משפטי.
תנו לתג הסקריפט type="text/plain" ותכונת data-consent עם שם הקטגוריה. הדפדפן לא יריץ אותו, והבאנר כותב אותו מחדש כתג סקריפט אמיתי ברגע שהקטגוריה מאושרת — בביקור הזה או בביקור הבא, לפי ההחלטה השמורה.
ב-localStorage, תחת המפתח שתבחרו, כאובייקט JSON קטן עם דגל לכל קטגוריה ותאריך. הבאנר עצמו לא מציב שום עוגייה ולא שולח דבר לשרת, ולכן הוא עובד גם באתר סטטי לחלוטין.
כן. המיקום, ערכת הנושא וצבע ההדגשה הם אפשרויות כאן, ולכל אלמנט ב-CSS שנוצר יש הקידומת cc-, כך שאפשר לדרוס את הכללים מגיליון הסגנונות שלכם בלי לגעת בקטע הקוד.
לאתר אחד עם כמה קטגוריות, הקטע הזה בדרך כלל מספיק. ברגע שתצטרכו יומני הסכמה, כמה דומיינים, או אנליטיקה שמכבדת את הבחירה אוטומטית — מנהל ההסכמה המובנה של PulsePanda לוקח על עצמו את כל העבודה.
קשור
PulsePanda מגיע עם מנהל הסכמה מובנה — ללא עוגיות כברירת מחדל, והוא מפסיק לאסוף ברגע שמישהו מסרב. בלי ספק נוסף ובלי קוד דבק.
התחילו בחינם