सेल्फ़-होस्टेड कुकी कंसेंट बैनर जनरेटर

कुछ सवालों के जवाब दें और एक ऐसा कुकी consent बैनर पाएं जो आपका अपना हो: सीधा आपकी साइट में पेस्ट करने के लिए plain HTML, CSS और vanilla JavaScript। यह असल में गैर-ज़रूरी scripts को तब तक ब्लॉक करता है जब तक कोई सहमति न दे, पसंद को localStorage में सेव करता है, और "Accept all" जितना ही दिखने वाला "Reject all" बटन रखता है - वह बारीकी जिसे France की CNIL जैसी regulatory बॉडी खास तौर पर लागू करती हैं। कोई थर्ड-पार्टी consent प्लेटफ़ॉर्म नहीं, कोई अकाउंट नहीं, कोई pageview सीमा नहीं।

सब कुछ आपके ब्राउज़र में ही जनरेट होता है। जो स्निपेट आपको मिलता है वह खुद कोई नेटवर्क अनुरोध नहीं करता - न कोई CDN, न सहमति-प्रबंधन सर्वर, न ऐसा पेजव्यू काउंटर जो खत्म हो सके।

बैनर टेक्स्ट में दिखाया जाता है - विज़िटर्स को पता होना चाहिए कि कौन पूछ रहा है।

आवश्यक। इसके बिना सहमति सूचित नहीं मानी जाती।

आपके द्वारा सेट की गई कुकी श्रेणियाँ

हमेशा

Strictly necessary

सहमति से मुक्त, इसलिए यह हमेशा मौजूद रहती है और इसे बंद नहीं किया जा सकता।

CNIL लगभग 6 महीने को अच्छी प्रथा मानता है, अस्वीकृति और सहमति दोनों के लिए।

window.cookieConsent के रूप में उपलब्ध और "cookieConsent.v1" के तहत संग्रहीत।

दो चीज़ें जिन्हें आप यहाँ बंद नहीं कर सकते

"सभी अस्वीकार करें" हमेशा "सभी स्वीकार करें" के बगल में, समान आकार और महत्व के साथ, बैनर के पहले स्तर पर दिखाया जाता है - और वैकल्पिक श्रेणियाँ हमेशा अनचेक जनरेट होती हैं। ये वे दो विवरण हैं जिनके लिए नियामक वास्तव में साइटों पर जुर्माना लगाते हैं, इसलिए जानबूझकर इन्हें तोड़ने का कोई विकल्प नहीं दिया गया है।

  • ठीक करेंAdd your site or company name - the banner has to say who is asking.

पूर्वावलोकन

We use cookies

This site uses cookies that are strictly necessary to run the site. With your permission we would also like to set optional cookies. You can accept them all, refuse them all, or choose category by category.

Accept allReject all
<style>
/* Cookie consent banner - generated by usezivo.com.
   Dependency-free: no fonts, no CDN, no network requests of its own. */

.cc-cookieconsent-root { position: fixed; z-index: 2147483000; }

.cc-cookieconsent-backdrop {
  position: fixed; inset: 0; z-index: 2147482999;
  background: rgba(15, 23, 42, 0.45);
}

.cc-cookieconsent-banner {
  position: fixed;
  left: 0; right: 0; bottom: 0; max-width: none; border-radius: 0; border-left: 0; border-right: 0; border-bottom: 0;
  box-sizing: border-box;
  padding: 18px 20px;
  background: #ffffff;
  color: #0f172a;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  box-shadow: 0 10px 40px rgba(15, 23, 42, 0.18);
  font: 400 14px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.cc-cookieconsent-title { margin: 0 0 6px; font-size: 15px; font-weight: 700; }
.cc-cookieconsent-text { margin: 0 0 14px; color: #475569; }
.cc-cookieconsent-text a { color: #2563eb; text-decoration: underline; }

/* Accept and Reject are deliberately the SAME component: same size, same
   weight, same visual prominence, side by side at the first level. */
.cc-cookieconsent-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cc-cookieconsent-btn {
  appearance: none;
  flex: 0 0 auto;
  min-width: 148px;
  padding: 11px 18px;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  border-radius: 10px;
  border: 1px solid #2563eb;
  background: #2563eb;
  color: #ffffff;
  cursor: pointer;
}
.cc-cookieconsent-btn:hover { filter: brightness(0.94); }
.cc-cookieconsent-btn:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
.cc-cookieconsent-btn--secondary { background: transparent; color: #2563eb; }
.cc-cookieconsent-link {
  appearance: none; background: none; border: 0; padding: 8px 4px;
  font: inherit; color: #475569; text-decoration: underline; cursor: pointer;
}
.cc-cookieconsent-link:hover { color: #0f172a; }

.cc-cookieconsent-panel {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  box-sizing: border-box;
  width: min(620px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 32px));
  overflow-y: auto;
  padding: 22px;
  background: #ffffff; color: #0f172a;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(15, 23, 42, 0.3);
  font: 400 14px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.cc-cookieconsent-panel h2 { margin: 0 0 6px; font-size: 17px; }
.cc-cookieconsent-panel-intro { margin: 0 0 16px; color: #475569; }

.cc-cookieconsent-cat {
  padding: 14px 0;
  border-top: 1px solid #e2e8f0;
}
.cc-cookieconsent-cat-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cc-cookieconsent-cat-name { font-weight: 600; }
.cc-cookieconsent-cat-desc { margin: 6px 0 0; color: #64748b; font-size: 13px; }
.cc-cookieconsent-always { font-size: 12px; font-weight: 600; color: #16a34a; }

/* Switch */
.cc-cookieconsent-switch { position: relative; display: inline-block; width: 44px; height: 24px; flex: 0 0 auto; }
.cc-cookieconsent-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.cc-cookieconsent-slider {
  position: absolute; inset: 0; border-radius: 999px;
  background: #cbd5e1; transition: background 0.15s ease; pointer-events: none;
}
.cc-cookieconsent-slider::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  transition: transform 0.15s ease;
}
.cc-cookieconsent-switch input:checked + .cc-cookieconsent-slider { background: #2563eb; }
.cc-cookieconsent-switch input:checked + .cc-cookieconsent-slider::after { transform: translateX(20px); }
.cc-cookieconsent-switch input:focus-visible + .cc-cookieconsent-slider { outline: 3px solid #2563eb; outline-offset: 2px; }

.cc-cookieconsent-panel-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; padding-top: 16px; border-top: 1px solid #e2e8f0; }

@media (max-width: 520px) {
  .cc-cookieconsent-banner { left: 8px; right: 8px; bottom: 8px; max-width: none; border-radius: 14px; border: 1px solid #e2e8f0; transform: none; top: auto; }
  .cc-cookieconsent-btn { flex: 1 1 100%; min-width: 0; }
}

@media (prefers-color-scheme: dark) {
  .cc-cookieconsent-banner, .cc-cookieconsent-panel { background: #0f172a; color: #e2e8f0; border-color: #334155; }
  .cc-cookieconsent-text, .cc-cookieconsent-panel-intro, .cc-cookieconsent-cat-desc { color: #94a3b8; }
  .cc-cookieconsent-cat, .cc-cookieconsent-panel-actions { border-color: #334155; }
  .cc-cookieconsent-link { color: #94a3b8; }
  .cc-cookieconsent-link:hover { color: #e2e8f0; }
  .cc-cookieconsent-slider { background: #475569; }
  @media (max-width: 520px) { .cc-cookieconsent-banner { border-color: #334155; } }
}
</style>

<!-- Cookie consent banner - generated by usezivo.com. Paste before </body>. -->
<div id="cc-cookieconsent-banner" class="cc-cookieconsent-banner" role="dialog" aria-modal="false" aria-labelledby="cc-cookieconsent-title" hidden>
  <p class="cc-cookieconsent-title" id="cc-cookieconsent-title">We use cookies</p>
  <p class="cc-cookieconsent-text">This site uses cookies that are strictly necessary to run the site. With your permission we would also like to set optional cookies. You can accept them all, refuse them all, or choose category by category. <a href="/privacy">Privacy policy</a></p>
  <div class="cc-cookieconsent-actions">
    <button type="button" class="cc-cookieconsent-btn" data-cc-cookieconsent-action="accept">Accept all</button>
    <button type="button" class="cc-cookieconsent-btn" data-cc-cookieconsent-action="reject">Reject all</button>
    <button type="button" class="cc-cookieconsent-link" data-cc-cookieconsent-action="open">Customise</button>
  </div>
</div>

<div id="cc-cookieconsent-panel" class="cc-cookieconsent-panel" role="dialog" aria-modal="true" aria-labelledby="cc-cookieconsent-panel-title" hidden>
  <h2 id="cc-cookieconsent-panel-title">Cookie preferences</h2>
  <p class="cc-cookieconsent-panel-intro">Strictly necessary cookies cannot be switched off. Every other category is off until you turn it on.</p>
      <div class="cc-cookieconsent-cat">
        <div class="cc-cookieconsent-cat-head">
          <span class="cc-cookieconsent-cat-name">Strictly necessary</span>
          <span class="cc-cookieconsent-always">Always active</span>
        </div>
        <p class="cc-cookieconsent-cat-desc">Needed for the site to work: security, load balancing, remembering what is in your basket and storing this cookie choice. These are exempt from consent.</p>
      </div>
      <div class="cc-cookieconsent-cat">
        <div class="cc-cookieconsent-cat-head">
          <span class="cc-cookieconsent-cat-name">Analytics</span>
          <label class="cc-cookieconsent-switch">
              <input type="checkbox" data-cc-cookieconsent-cat="analytics" aria-label="Analytics">
              <span class="cc-cookieconsent-slider"></span>
            </label>
        </div>
        <p class="cc-cookieconsent-cat-desc">Help us understand which pages are visited and where people get stuck, so we can improve the site. Measurement only, never used to target advertising.</p>
      </div>
  <div class="cc-cookieconsent-panel-actions">
    <button type="button" class="cc-cookieconsent-btn" data-cc-cookieconsent-action="save">Save my choices</button>
    <button type="button" class="cc-cookieconsent-btn cc-cookieconsent-btn--secondary" data-cc-cookieconsent-action="accept">Accept all</button>
    <button type="button" class="cc-cookieconsent-btn cc-cookieconsent-btn--secondary" data-cc-cookieconsent-action="reject">Reject all</button>
  </div>
</div>

<script>
/* Cookie consent - generated by usezivo.com. Vanilla JS, no dependencies,
   no network requests. Paste after the markup, or load as an external file. */
(function () {
  "use strict";

  var KEY = "cookieConsent.v1";
  var MAX_AGE_MS = 183 * 24 * 60 * 60 * 1000;
  var OPTIONAL = ["analytics"];
  var PREFIX = "cc-cookieconsent";

  var banner = document.getElementById(PREFIX + "-banner");
  var panel = document.getElementById(PREFIX + "-panel");
  var backdrop = null;
  var lastFocus = null;

  // --- storage ------------------------------------------------------------
  // localStorage can throw outright in some privacy modes, so every access is
  // guarded. If it is unavailable the banner simply reappears next visit,
  // which is the safe direction to fail in: nothing gets unblocked.
  function read() {
    try {
      var raw = localStorage.getItem(KEY);
      if (!raw) return null;
      var saved = JSON.parse(raw);
      if (!saved || typeof saved !== "object") return null;
      if (typeof saved.at !== "number" || Date.now() - saved.at > MAX_AGE_MS) return null;
      var out = { necessary: true };
      for (var i = 0; i < OPTIONAL.length; i++) {
        out[OPTIONAL[i]] = saved.categories && saved.categories[OPTIONAL[i]] === true;
      }
      return out;
    } catch (e) {
      return null;
    }
  }

  function write(categories) {
    try {
      localStorage.setItem(KEY, JSON.stringify({ v: 1, at: Date.now(), categories: categories }));
    } catch (e) {
      /* storage blocked - the choice applies to this page load only */
    }
  }

  var state = read();

  // --- script gating ------------------------------------------------------
  // Third-party tags are written as:
  //   <script type="text/plain" data-cookie-category="analytics" src="..."></script>
  // The browser will not execute type="text/plain", so nothing runs until the
  // matching category is granted, at which point the tag is swapped for a real
  // one. Inline tags work the same way.
  function unblock(granted) {
    var pending = document.querySelectorAll('script[type="text/plain"][data-cookie-category]');
    for (var i = 0; i < pending.length; i++) {
      var node = pending[i];
      var category = node.getAttribute("data-cookie-category");
      if (!granted[category]) continue;
      var real = document.createElement("script");
      for (var a = 0; a < node.attributes.length; a++) {
        var attr = node.attributes[a];
        if (attr.name === "type" || attr.name === "data-cookie-category") continue;
        real.setAttribute(attr.name, attr.value);
      }
      real.type = "text/javascript";
      if (!node.src) real.text = node.text;
      node.parentNode.replaceChild(real, node);
    }
  }

  var listeners = [];
  function emit(granted) {
    unblock(granted);
    for (var i = 0; i < listeners.length; i++) {
      try {
        listeners[i](granted);
      } catch (e) {
        /* one bad listener must not break the rest */
      }
    }
    try {
      document.dispatchEvent(new CustomEvent("cookieConsent:change", { detail: granted }));
    } catch (e) {
      /* CustomEvent unsupported - the callback API still works */
    }
  }

  // --- UI -----------------------------------------------------------------
  function showBanner() {
    if (!banner) return;
    banner.hidden = false;
    /* no backdrop configured */
  }

  function hideBanner() {
    if (banner) banner.hidden = true;
    if (backdrop && backdrop.parentNode) {
      backdrop.parentNode.removeChild(backdrop);
      backdrop = null;
    }
  }

  function boxes() {
    return panel ? panel.querySelectorAll("[data-" + PREFIX + "-cat]") : [];
  }

  function openPanel() {
    if (!panel) return;
    lastFocus = document.activeElement;
    // Reflect the stored choice, or leave every optional box OFF when there is
    // no stored choice yet. Nothing is ever pre-ticked.
    var current = read();
    var list = boxes();
    for (var i = 0; i < list.length; i++) {
      var id = list[i].getAttribute("data-" + PREFIX + "-cat");
      list[i].checked = !!(current && current[id]);
    }
    panel.hidden = false;
    var first = panel.querySelector("button, input");
    if (first) first.focus();
    document.addEventListener("keydown", onKeydown);
  }

  function closePanel() {
    if (!panel) return;
    panel.hidden = true;
    document.removeEventListener("keydown", onKeydown);
    if (lastFocus && lastFocus.focus) lastFocus.focus();
  }

  function onKeydown(e) {
    // Escape closes the PREFERENCES panel only. It never dismisses the banner:
    // dismissing without choosing must not be treated as consent.
    if (e.key === "Escape") closePanel();
  }

  function decide(categories) {
    var granted = { necessary: true };
    for (var i = 0; i < OPTIONAL.length; i++) {
      granted[OPTIONAL[i]] = categories[OPTIONAL[i]] === true;
    }
    state = granted;
    write(granted);
    closePanel();
    hideBanner();
    emit(granted);
  }

  function all(value) {
    var out = {};
    for (var i = 0; i < OPTIONAL.length; i++) out[OPTIONAL[i]] = value;
    return out;
  }

  function fromPanel() {
    var out = {};
    var list = boxes();
    for (var i = 0; i < list.length; i++) {
      out[list[i].getAttribute("data-" + PREFIX + "-cat")] = list[i].checked === true;
    }
    return out;
  }

  document.addEventListener("click", function (e) {
    var target = e.target.closest ? e.target.closest("[data-" + PREFIX + "-action]") : null;
    if (!target) return;
    var action = target.getAttribute("data-" + PREFIX + "-action");
    if (action === "accept") decide(all(true));
    else if (action === "reject") decide(all(false));
    else if (action === "save") decide(fromPanel());
    else if (action === "open") openPanel();
    else if (action === "close") closePanel();
  });

  // --- public API ---------------------------------------------------------
  window["cookieConsent"] = {
    /** true if that category has been granted. Always true for "necessary". */
    has: function (category) {
      if (category === "necessary") return true;
      return !!(state && state[category]);
    },
    /** The full granted map, or null if no choice has been made yet. */
    get: function () {
      return state ? JSON.parse(JSON.stringify(state)) : null;
    },
    /** Run cb now (if a choice exists) and on every later change. Returns an unsubscribe fn. */
    onChange: function (cb) {
      listeners.push(cb);
      if (state) {
        try {
          cb(state);
        } catch (e) {
          /* ignore */
        }
      }
      return function () {
        var i = listeners.indexOf(cb);
        if (i > -1) listeners.splice(i, 1);
      };
    },
    /** Wire this to a permanent "Cookie preferences" link in your footer. */
    openPreferences: openPanel,
    /** Forget the stored choice and ask again. Withdrawal must be as easy as consent. */
    reset: function () {
      try {
        localStorage.removeItem(KEY);
      } catch (e) {
        /* ignore */
      }
      state = null;
      showBanner();
    },
  };

  // --- boot ---------------------------------------------------------------
  if (state) {
    // A stored choice: apply it silently, do not nag.
    emit(state);
  } else {
    // No choice yet -> nothing is unblocked, and the banner asks.
    showBanner();
  }
})();
</script>

स्निपेट लाइव अपडेट होता है, लेकिन इसे लाइव करने से पहले ऊपर दी गई समस्याओं को ठीक करें।

ऊपर दिए गए नियम कहाँ से आते हैं

यह जनरेटर बैनर UI और सहमति-भंडारण तंत्र तैयार करता है। यह कानूनी सलाह नहीं है और अकेले किसी साइट को अनुपालक नहीं बना सकता - जो वास्तव में मायने रखता है वह यह है कि आप कौन-से ट्रैकर चलाते हैं, क्या आपने उन्हें वास्तव में इस गेट के माध्यम से जोड़ा है, और आपकी गोपनीयता नीति क्या कहती है। नियम देशों के बीच भी भिन्न होते हैं और समय के साथ बदलते हैं। यदि जोखिम अधिक है, तो किसी वकील से इसकी समीक्षा करवाएँ।

Axeptio या Cookiebot के बजाय सेल्फ़-होस्टेड क्यों

होस्टेड कंसेंट प्लेटफ़ॉर्म शानदार प्रोडक्ट हैं, लेकिन उनके फ़्री टियर पर सीमा होती है: मंथली पेजव्यू की एक सीमा पार करते ही बैनर काम करना बंद कर देता है या बिलिंग शुरू हो जाती है। वे हर पेज व्यू पर अपने ही डोमेन से अपना जावास्क्रिप्ट भी लोड करते हैं, जो प्राइवेसी के नाम पर आपकी साइट में एक थर्ड-पार्टी रिक्वेस्ट जोड़ देता है, और एक ऐसी निर्भरता बन जाती है जो आपके नियंत्रण के बिना बदल सकती है।

यह टूल जो स्निपेट लिखता है वह लगभग 6 KB का है, उसकी कोई डिपेंडेंसी नहीं है, वह खुद कोई नेटवर्क रिक्वेस्ट नहीं भेजता, और आपके अपने रिपॉज़िटरी में रहता है जहाँ आप उसकी हर लाइन पढ़ सकते हैं। कोई वेंडर नहीं है जिसका कोटा ख़त्म हो सके, और कुछ भी चुपके से किसी बाहरी सर्वर से संपर्क नहीं करता।

बैनर क्या करता हैकैसे
सहमति से पहले टैग ब्लॉक करता हैथर्ड-पार्टी टैग type="text/plain" के साथ और एक data-cookie-category एट्रिब्यूट के साथ लिखे जाते हैं, जिन्हें ब्राउज़र चलाने से मना कर देते हैं। सहमति मिलने पर टैग को एक असली script एलिमेंट से बदल दिया जाता है, और तभी वह चलता है।
मना करना भी स्वीकार करने जितना आसान“सभी स्वीकार करें” और “सभी अस्वीकार करें” एक ही बटन कॉम्पोनेंट हैं - समान चौड़ाई, पैडिंग, वज़न और रंग के साथ - पहले स्तर पर साथ-साथ।
कुछ भी पहले से टिक नहींजेनरेट किए गए प्रिफ़रेंस स्विच में कभी checked एट्रिब्यूट नहीं होता। कभी नहीं।
चुप रहना सहमति नहीं हैबैनर को बंद करना या नज़रअंदाज़ करना कुछ भी सेव नहीं करता और कुछ भी अनब्लॉक नहीं करता। सिर्फ़ एक स्पष्ट क्लिक ही कोई चुनाव दर्ज करता है।
जब चाहें सहमति वापस लें<ns/>.openPreferences() पैनल को फिर से खोलता है, और .reset() चुनाव को भूल जाता है - इनमें से किसी को भी फ़ुटर लिंक से जोड़ें।
जवाब याद रखता हैlocalStorage, एक टाइमस्टैम्प और आपके चुने हुए एक्सपायरी समय (डिफ़ॉल्ट रूप से 6 महीने) के साथ, ताकि विज़िटर से हर पेज पर दोबारा न पूछा जाए।

अक्सर पूछे जाने वाले प्रश्न

बिना किसी पेड प्लेटफ़ॉर्म के मुफ़्त, नियम-अनुरूप कुकी बैनर कैसे बनाएं?

अपनी साइट का नाम, privacy policy लिंक, और आप जो कुकी categories असल में इस्तेमाल करते हैं वे भरें, फिर जनरेट हुए ब्लॉक को अपने पेज में क्लोज़िंग body टैग से पहले कॉपी करें। आपको Axeptio, Cookiebot, Tarteaucitron या किसी भी consent प्लेटफ़ॉर्म पर निर्भरता के बिना vanilla HTML, CSS और JavaScript मिलता है - तो कोई free-tier pageview लिमिट नहीं टकरानी, न ही हर पेज पर थर्ड-पार्टी स्क्रिप्ट लोड होती है।

क्या यह सहमति से पहले वाकई Google Analytics को ब्लॉक करता है, या सिर्फ़ बैनर छुपाता है?

यह वाकई ब्लॉक करता है, पर आपको एक काम करना होगा: अपने टैग को type="text/javascript" से बदलकर type="text/plain" करें और data-cookie-category="analytics" जोड़ें। ब्राउज़र text/plain स्क्रिप्ट को execute नहीं करता, तो टैग पेज में निष्क्रिय पड़ा रहता है। जैसे ही visitor उस category को अनुमति देता है, स्क्रिप्ट को असली script element में क्लोन करके चला दिया जाता है।

Reject all बटन छुपाने का विकल्प क्यों नहीं है?

क्योंकि यह गैर-अनुरूप बैनरों की सबसे ज़्यादा बताई जाने वाली समस्या है। CNIL का रुख है कि ट्रैकर्स को अस्वीकार करना उतना ही आसान होना चाहिए जितना स्वीकार करना, और पहले स्तर पर "Accept all" जैसी ही दिखावट वाला "Reject all" बटन इसका स्पष्ट तरीका मानती है। यह जनरेटर हमेशा दोनों बटन एक ही CSS क्लास से बनाता है, तो वे साइज़ और वज़न में एक जैसे होते हैं।

क्या इससे मेरी साइट कानूनी रूप से GDPR-अनुरूप हो जाती है?

नहीं, और किसी भी टूल से सावधान रहें जो इसका उल्टा दावा करे। यह सिर्फ़ बैनर UI और consent-स्टोरेज तंत्र जनरेट करता है। अनुपालन इस पर भी निर्भर करता है कि आप असल में कौन-से ट्रैकर्स चलाते हैं, क्या हर एक वाकई gate से होकर गुज़रता है, आपकी privacy और cookie policies में क्या लिखा है, और ऐसे नियम जो देश के हिसाब से अलग होते हैं और समय के साथ बदलते हैं।

संबंधित टूल