1. Klistra in snutten
Släpp in den genererade koden precis före den avslutande body-taggen på varje sida. Den har inga beroenden och lägger inte till några nätverksanrop.
Gratisverktyg
Välj dina cookie-kategorier, skriv texten, välj utseende — och kopiera ut en beroendefri samtyckesbanner som du kan klistra in på vilken sajt som helst. Den sparar besökarens val, håller taggade skript blockerade tills deras kategori godkänns och kan öppnas igen från en länk i sidfoten.
Din samtyckesbanner
Klistra in detta precis före den avslutande body-taggen, på varje sida.
<!-- Cookie consent banner - paste this just before </body> -->
<script>
(function () {
var CFG = {
"storageKey": "cookie_consent",
"position": "bar",
"theme": "light",
"accent": "#a6144d",
"title": "Vi använder cookies",
"message": "Vi använder cookies för att driva den här webbplatsen, förstå hur den används och förbättra den. Du kan acceptera allt, avvisa det som är valfritt, eller välja per kategori.",
"policyUrl": "https://example.com/privacy",
"policyLabel": "Läs vår integritetspolicy",
"accept": "Acceptera alla",
"reject": "Avvisa valfria",
"prefs": "Preferenser",
"save": "Spara val",
"categories": [
{
"id": "necessary",
"label": "Strikt nödvändiga",
"desc": "Krävs för att webbplatsen ska fungera. Alltid aktiva och frågar aldrig om samtycke.",
"required": true
},
{
"id": "analytics",
"label": "Analys",
"desc": "Mäter hur webbplatsen används så att den kan förbättras.",
"required": false
},
{
"id": "marketing",
"label": "Marknadsföring",
"desc": "Används för att anpassa annonser och mäta kampanjer.",
"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> Så använder du den
Släpp in den genererade koden precis före den avslutande body-taggen på varje sida. Den har inga beroenden och lägger inte till några nätverksanrop.
Ändra en spårningstaggs typ till text/plain och lägg till data-consent="analytics". Bannern kör den så fort den kategorin beviljas — och aldrig innan.
Lägg till en länk i sidfoten som anropar window.showConsentPreferences() så att besökare kan öppna panelen igen. Varje beslut utlöser också en consentchange-händelse du kan lyssna på.
Vanliga frågor
Den ger dig mekaniken som tillsynsmyndigheterna förväntar sig: inga valfria cookies före samtycke, lika lätt att neka som att godkänna, val per kategori och ett sätt att ändra sig senare. Efterlevnad beror också på vad du faktiskt kör, vad din policy säger och var dina besökare finns — se därför den genererade koden som en stabil utgångspunkt snarare än som juridisk rådgivning.
Ge script-taggen type="text/plain" och ett data-consent-attribut som anger dess kategori. Webbläsaren kör den inte, och bannern skriver om den till en riktig script-tagg så snart den kategorin godkänns — vid det här besöket eller vid nästa, utifrån det sparade valet.
I localStorage, under den nyckel du väljer, som ett litet JSON-objekt med en flagga per kategori plus datumet. Ingen cookie sätts för själva bannern och inget skickas till en server, så det fungerar på en helt statisk sajt.
Ja. Position, tema och accentfärg är alternativ här, och varje element i den genererade CSS-koden har prefixet cc- så att du kan skriva över reglerna från din egen stilmall utan att röra kodsnutten.
För en enda sajt med en handfull kategorier räcker den här kodsnutten oftast. Så snart du behöver samtyckesloggar, flera domäner eller analys som automatiskt respekterar valet tar PulsePandas inbyggda samtyckeshanterare över hela jobbet.
Relaterat
PulsePanda levereras med en inbyggd samtyckeshanterare — cookiefri som standard, och den slutar samla in data så fort någon väljer bort det. Ingen extra leverantör, ingen limkod.
Kom igång gratis