Skrypt tworzący na stronie banner consent mode

Strona główna » Skrypty » Skrypt tworzący na stronie banner consent mode
Instrukcja użycia

→ Wklej poniższy skrypt w sekcji <head> na stronie internetowej
→ Dostosuj tagi do zgód Consent Mode w ustawieniach w GTM

Skrypt bannera

<!-- PK Cookie Consent + Google Consent Mode v2 — wklej w <head> PRZED snippetem GTM -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

(function(){
  var POLICY_VERSION = '1'; // zmień, gdy zmienia się polityka/zakres cookies — użytkownicy dostaną baner ponownie

  var raw = (document.cookie.split(';').map(function(c){return c.trim();})
    .find(function(c){return c.indexOf('consent=')===0;}) || '').substring(8);

  var s = { consent:'no', analytics:'no', advertisement:'no', personalization:'no' };
  var v = null;
  raw.split(',').forEach(function(p){
    var kv = p.split(':');
    if (kv[0] in s) s[kv[0]] = (kv[1] === 'yes' ? 'yes' : 'no');
    if (kv[0] === 'v') v = kv[1];
  });

  var hasChoice = (s.consent === 'yes' && v === POLICY_VERSION);
  if (!hasChoice) { s.analytics = 'no'; s.advertisement = 'no'; s.personalization = 'no'; }

  var g = function(x){ return x === 'yes' ? 'granted' : 'denied'; };
  var toConsent = function(st){
    return {
      'analytics_storage':       g(st.analytics),
      'ad_storage':              g(st.advertisement),
      'ad_user_data':            g(st.advertisement),
      'ad_personalization':      g(st.advertisement),
      'personalization_storage': g(st.personalization),
      'functionality_storage':   'granted',
      'security_storage':        'granted'
    };
  };

  var def = toConsent(s);
  def['wait_for_update'] = 500;
  gtag('consent', 'default', def);

  gtag('set', 'url_passthrough', true);
  gtag('set', 'ads_data_redaction', s.advertisement !== 'yes');

  if (hasChoice) {
    gtag('consent', 'update', toConsent(s));
    window.dataLayer.push({
      event: 'gtm_consent_update',
      consent_source: 'stored',
      consent_action: 'page_load',
      consent: {
        functionality: 'yes',
        analytics: s.analytics,
        advertisement: s.advertisement,
        personalization: s.personalization
      },
      consent_raw: raw
    });
  }
  window.__pkPolicyVersion = POLICY_VERSION;
})();
</script>

<style id="cb-styles">
  :root{ --cb-ico-scale:1.30; }

  #cb-overlay{
    position:fixed; inset:0; background:rgba(0,0,0,.45);
    z-index:2147483647;
    display:flex; align-items:center; justify-content:center;
  }
  #cb-modal{
    background:#ffffff; color:#0f172a; width:min(720px,92vw);
    border-radius:16px; border:1px solid #e5e7eb; box-shadow:0 24px 80px rgba(0,0,0,.25);
    overflow:hidden; z-index:2147483647;
  }
  .cb-top{ padding:0 24px; border-bottom:1px solid #e5e7eb; display:flex; gap:28px; }
  .cb-tab{ padding:16px 0 14px; border-bottom:3px solid transparent; cursor:pointer; font-weight:800; color:#0f172a; }
  .cb-tab.active{ border-color:#1960BF; }

  .cb-body{ padding:22px; max-height:60vh; overflow:auto; }
  .cb-title{ margin:0 0 10px; font-size:28px; font-weight:800; }
  .cb-desc{ margin:0 0 16px; color:#475569; font-size:16px; }
  .cb-info{ font-size:16px; color:#0f172a; }
  .cb-info p{ margin:0 0 12px; }
  .cb-info a, .cb-desc a{ color:#1960BF; font-weight:800; border-bottom:0; padding-bottom:0; box-shadow:none; }

  .cb-list{ margin-top:8px; border-top:1px solid #e5e7eb; }
  .cb-li{
    display:flex; align-items:flex-start; justify-content:space-between;
    padding:16px 0; border-bottom:1px solid #e5e7eb; gap:16px;
  }
  .cb-li strong{ font-weight:800; }
  .cb-left{ min-width:0; }
  .cb-sub{ margin:.35rem 0 0; color:#64748b; font-size:14px; line-height:1.4; }
  .cb-right{ display:flex; align-items:center; gap:12px; flex:0 0 auto; }

  .cb-switch{ position:relative; width:56px; height:32px; }
  .cb-switch input{ position:absolute; opacity:0; width:0; height:0; }
  .cb-slider{ position:absolute; inset:0; background:#e7e7e7; border-radius:999px; transition:.2s; }
  .cb-slider:before{
    content:""; position:absolute; left:3px; top:3px; width:26px; height:26px;
    background:#fff; border-radius:50%; transition:.2s; box-shadow:0 1px 2px rgba(0,0,0,.25);
  }
  .cb-switch input:checked + .cb-slider{ background:#1960BF; }
  .cb-switch input:focus-visible + .cb-slider{ outline:3px solid #1960BF; outline-offset:2px; }
  .cb-switch input:checked + .cb-slider:before{ transform:translateX(24px); }
  .cb-switch.disabled input:checked + .cb-slider{ background:#4A80D6; }
  .cb-switch.disabled{ opacity:.9; }

  .cb-actions{
    display:flex; gap:12px; flex-wrap:wrap; padding:16px 22px;
    border-top:1px solid #e5e7eb; background:#fafafa;
    margin-bottom:15px;
  }
  .cb-actions.center{ justify-content:center; }
  .cb-actions.end{ justify-content:flex-end; }

  .cb-btn{
    border:0; border-radius:12px; padding:12px 18px; cursor:pointer;
    font-weight:900; min-width:210px; text-align:center;
  }
  .cb-btn.primary{ background:#1960BF; color:#fff; }
  .cb-btn.secondary{ background:#1960BF; color:#fff; }
  .cb-btn.ghost{ background:#fff; border:1px solid #e5e7eb; color:#1960BF; }

  @media(max-width:640px){ .cb-btn{ flex:1 1 100%; min-width:100%; } }

  #custom-button{
    position:fixed; bottom:20px; left:20px; width:60px; height:60px; border:none; border-radius:50%;
    background-color:#1960BF; cursor:pointer; z-index:2147483647;
    display:flex; align-items:center; justify-content:center; transition:background-color .3s ease, transform .3s ease;
    overflow:hidden;
  }
  #custom-button .cb-ico-wrap{ width:100%; height:100%; display:flex; align-items:center; justify-content:center; }
  #custom-button .cb-ico{ width:36px; height:36px; display:block; transform:scale(var(--cb-ico-scale)); transform-origin:center; }
  #custom-button:hover{ background-color:#144a94; transform:scale(1.06); }
</style>

<script id="cb-script">
(function(){
  const COOKIE_NAME = "consent";
  const TTL_DAYS = 180;
  const POLICY_VERSION = window.__pkPolicyVersion || "1";

  // Cookies stron trzecich do usunięcia po odrzuceniu/wycofaniu danej kategorii.
  const CATEGORY_COOKIES = {
    analytics:       [/^_ga($|_)/, /^_gid$/, /^_gat/, /^_clck$/, /^_clsk$/, /^CLID$/, /^ANONCHK$/, /^MUID$/, /^SM$/],
    advertisement:   [/^_gcl_/, /^_fbp$/, /^_fbc$/, /^_gac_/, /^IDE$/, /^test_cookie$/],
    personalization: []
  };

  const UI = {
    text: {
      tabs:["Zgody","Szczegóły","Informacje"],
      title:"Ta strona używa plików cookie",
      desc:'Niezbędne pliki cookie zapewniają działanie i bezpieczeństwo strony. Za Twoją zgodą używam też cookies analitycznych i reklamowych (m.in. Google, Microsoft Clarity, Meta). Możesz zaakceptować wszystkie, odrzucić wszystkie lub wybrać kategorie. Zgodę możesz w każdej chwili zmienić lub wycofać, klikając ikonę ciasteczka w rogu strony. Szczegóły w <a href="/polityka-prywatnosci/" target="_blank" rel="noopener">polityce prywatności</a>.',
      detailsIntro:"Wybierz kategorie, na które wyrażasz zgodę (domyślnie wyłączone):",
      acceptAll:"Akceptuj wszystkie",
      rejectAll:"Odrzuć wszystkie",
      customize:"Dostosuj",
      save:"Zapisz wybrane",
      infoHTML:
        '<p>Administratorem danych jest właściciel serwisu. Dane z cookies analitycznych i reklamowych trafiają do dostawców narzędzi (Google Ireland Ltd., Microsoft Ireland Operations Ltd., Meta Platforms Ireland Ltd.).</p>' +
        '<p>Zgoda jest przechowywana przez 180 dni w pliku cookie <code>consent</code> (wraz z datą decyzji). Masz prawo dostępu do danych, ich sprostowania, usunięcia oraz wniesienia skargi do UODO.</p>' +
        '<p>Więcej w <a href="/polityka-prywatnosci/" target="_blank" rel="noopener">polityce prywatności</a>.</p>'
    },
    detailsRows:[
      ["Niezbędne (zawsze włączone)","functionality",true,"Konieczne do działania i bezpieczeństwa strony (np. sesja, koszyk, zapamiętanie Twojej decyzji o cookies). Nie wymagają zgody."],
      ["Analityczne","analytics",false,"Google Analytics 4, Microsoft Clarity — statystyki odwiedzin, źródła ruchu, nagrania sesji (anonimizowane)."],
      ["Reklamowe","advertisement",false,"Google Ads, Meta Pixel — pomiar skuteczności kampanii i dopasowanie reklam."],
      ["Personalizacyjne","personalization",false,"Dopasowanie treści i interfejsu (np. zapamiętane preferencje, rekomendacje)."]
    ]
  };

  const KEYS = ["consent","functionality","analytics","advertisement","personalization"];
  const DEFAULTS = { consent:"no", functionality:"yes", analytics:"no", advertisement:"no", personalization:"no" };

  function serializeState(state){
    return KEYS.map(k => `${k}:${state[k]}`).join(",");
  }
  function serializeCookie(state, meta){
    return serializeState(state) + `,v:${meta.v},ts:${meta.ts}`;
  }

  function setCookieState(state, days=TTL_DAYS){
    const d = new Date(); d.setTime(d.getTime()+days*864e5);
    const secure = location.protocol==="https:"?"; Secure":"";
    const meta = { v: POLICY_VERSION, ts: Date.now() };
    document.cookie = `${COOKIE_NAME}=${serializeCookie(state, meta)}; Expires=${d.toUTCString()}; Path=/; SameSite=Lax${secure}`;
  }
  function getCookieRaw(){
    const m = document.cookie.split(";").map(c=>c.trim()).find(c=>c.startsWith(COOKIE_NAME+"="));
    return m ? m.split("=",2)[1] : null;
  }
  function parseCookie(str){
    const s = {...DEFAULTS, v:null, ts:null};
    if(!str) return s;
    str.split(",").forEach(p=>{
      const [k,v]=p.split(":");
      if(!k||!v) return;
      if(KEYS.includes(k)) s[k]=(v==="yes"?"yes":"no");
      else if(k==="v") s.v=v;
      else if(k==="ts") s.ts=Number(v)||null;
    });
    s.functionality="yes";
    return s;
  }
  const readState = () => parseCookie(getCookieRaw());
  const hasChoice = () => { const s=readState(); return s.consent==="yes" && s.v===POLICY_VERSION; };
  const stateOnly = s => ({consent:s.consent,functionality:"yes",analytics:s.analytics,advertisement:s.advertisement,personalization:s.personalization});

  function deleteCookie(name){
    const host = location.hostname;
    const parts = host.split(".");
    const domains = [null, host];
    for(let i=1;i<parts.length-1;i++) domains.push("."+parts.slice(i).join("."));
    domains.push("."+host);
    domains.forEach(dom=>{
      document.cookie = `${name}=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/` + (dom?`; Domain=${dom}`:"");
    });
  }
  function purgeRejectedCookies(state){
    const names = document.cookie.split(";").map(c=>c.trim().split("=")[0]).filter(Boolean);
    Object.keys(CATEGORY_COOKIES).forEach(cat=>{
      if(state[cat]==="yes") return;
      names.forEach(n=>{ if(CATEGORY_COOKIES[cat].some(rx=>rx.test(n))) deleteCookie(n); });
    });
  }

  function toConsent(state){
    const g = v => v==="yes" ? "granted" : "denied";
    return {
      "analytics_storage":       g(state.analytics),
      "ad_storage":              g(state.advertisement),
      "ad_user_data":            g(state.advertisement),
      "ad_personalization":      g(state.advertisement),
      "personalization_storage": g(state.personalization),
      "functionality_storage":   "granted",
      "security_storage":        "granted"
    };
  }

  function updateConsentMode(action, state){
    window.dataLayer = window.dataLayer || [];
    if (typeof gtag !== "function") {
      window.gtag = function(){ dataLayer.push(arguments); };
    }
    gtag("consent","update", toConsent(state));
    gtag("set","ads_data_redaction", state.advertisement !== "yes");

    window.dataLayer.push({
      event: "gtm_consent_update",
      consent_source: "banner",
      consent_action: action,          // accept_all | reject_all | accept_selected
      consent: {...state},
      consent_raw: getCookieRaw()
    });
  }

  function applyDecision(action, state, overlay){
    setCookieState(state);
    purgeRejectedCookies(state);
    updateConsentMode(action, state);
    closeModal(overlay);
  }

  let lastFocus = null;
  function closeModal(ov){
    ov.remove();
    document.body.style.overflow = "";
    if(lastFocus && lastFocus.focus) lastFocus.focus();
  }

  function build(initial){
    if(document.getElementById("cb-overlay")) return;
    lastFocus = document.activeElement;
    const ov=document.createElement("div");
    ov.id="cb-overlay";
    ov.innerHTML=`
      <div id="cb-modal" role="dialog" aria-modal="true" aria-labelledby="cb-title">
        <div class="cb-top" role="tablist">
          <div class="cb-tab active" data-tab="consents" role="tab" tabindex="0" aria-selected="true">${UI.text.tabs[0]}</div>
          <div class="cb-tab" data-tab="details" role="tab" tabindex="0" aria-selected="false">${UI.text.tabs[1]}</div>
          <div class="cb-tab" data-tab="info" role="tab" tabindex="0" aria-selected="false">${UI.text.tabs[2]}</div>
        </div>
        <div class="cb-body">
          <div id="pane-consents">
            <h3 class="cb-title" id="cb-title">${UI.text.title}</h3>
            <p class="cb-desc">${UI.text.desc}</p>
          </div>
          <div id="pane-details" style="display:none">
            <p class="cb-desc">${UI.text.detailsIntro}</p>
            <div class="cb-list">
              ${UI.detailsRows.map(([label,key,lock,desc])=>`
                <div class="cb-li">
                  <div class="cb-left">
                    <strong id="cb_lbl_${key}">${label}</strong>
                    ${desc?`<p class="cb-sub">${desc}</p>`:""}
                  </div>
                  <div class="cb-right">
                    <label class="cb-switch ${lock?"disabled":""}">
                      <input type="checkbox" id="cb_${key}" aria-labelledby="cb_lbl_${key}" ${initial[key]==="yes"?"checked":""} ${lock?"disabled":""}>
                      <span class="cb-slider"></span>
                    </label>
                  </div>
                </div>`).join("")}
            </div>
          </div>
          <div id="pane-info" class="cb-info" style="display:none">${UI.text.infoHTML}</div>
        </div>
        <div class="cb-actions center" id="actions-consents">
          <button class="cb-btn ghost" id="btn-reject">${UI.text.rejectAll}</button>
          <button class="cb-btn ghost" id="btn-customize">${UI.text.customize}</button>
          <button class="cb-btn primary" id="btn-accept">${UI.text.acceptAll}</button>
        </div>
        <div class="cb-actions end" id="actions-details" style="display:none">
          <button class="cb-btn ghost" id="btn-reject-2">${UI.text.rejectAll}</button>
          <button class="cb-btn primary" id="btn-save">${UI.text.save}</button>
        </div>
      </div>`;
    document.body.appendChild(ov);
    document.body.style.overflow = "hidden";

    const tabs=ov.querySelectorAll(".cb-tab");
    const panes={consents:ov.querySelector("#pane-consents"),details:ov.querySelector("#pane-details"),info:ov.querySelector("#pane-info")};
    const acts={consents:ov.querySelector("#actions-consents"),details:ov.querySelector("#actions-details")};

    function showTab(which){
      tabs.forEach(x=>{ x.classList.remove("active"); x.setAttribute("aria-selected","false"); });
      const t=[...tabs].find(t=>t.dataset.tab===which); t.classList.add("active"); t.setAttribute("aria-selected","true");
      Object.keys(panes).forEach(k=>panes[k].style.display = k===which ? "block" : "none");
      acts.consents.style.display = which==="consents" ? "flex":"none";
      acts.details.style.display  = which==="details"  ? "flex":"none";
    }
    tabs.forEach(t=>{
      t.addEventListener("click",()=>showTab(t.dataset.tab));
      t.addEventListener("keydown",e=>{ if(e.key==="Enter"||e.key===" "){ e.preventDefault(); showTab(t.dataset.tab); } });
    });

    const reject = ()=>applyDecision("reject_all",
      {consent:"yes",functionality:"yes",analytics:"no",advertisement:"no",personalization:"no"}, ov);

    ov.querySelector("#btn-accept").addEventListener("click",()=>{
      applyDecision("accept_all",
        {consent:"yes",functionality:"yes",analytics:"yes",advertisement:"yes",personalization:"yes"}, ov);
    });
    ov.querySelector("#btn-reject").addEventListener("click",reject);
    ov.querySelector("#btn-reject-2").addEventListener("click",reject);
    ov.querySelector("#btn-customize").addEventListener("click",()=>showTab("details"));
    ov.querySelector("#btn-save").addEventListener("click",()=>{
      const val=k=>(ov.querySelector("#cb_"+k)?.checked?"yes":"no");
      applyDecision("accept_selected",{
        consent:"yes",
        functionality:"yes",
        analytics:val("analytics"),
        advertisement:val("advertisement"),
        personalization:val("personalization")
      }, ov);
    });

    ov.addEventListener("keydown",e=>{ if(e.key==="Escape" && hasChoice()) closeModal(ov); });

    const focusables = ()=>[...ov.querySelectorAll('button, [tabindex="0"], input:not([disabled]), a[href]')].filter(el=>el.offsetParent!==null);
    ov.addEventListener("keydown",e=>{
      if(e.key!=="Tab") return;
      const f=focusables(); if(!f.length) return;
      const first=f[0], last=f[f.length-1];
      if(e.shiftKey && document.activeElement===first){ e.preventDefault(); last.focus(); }
      else if(!e.shiftKey && document.activeElement===last){ e.preventDefault(); first.focus(); }
    });
    ov.querySelector("#btn-reject").focus({preventScroll:true});
  }

  function addLauncher(){
    if(document.getElementById("custom-button")) return;
    const btn=document.createElement("button");
    btn.id="custom-button"; btn.setAttribute("aria-label","Zmień lub wycofaj zgody na pliki cookie");
    btn.innerHTML=`<span class="cb-ico-wrap">
      <svg class="cb-ico" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-hidden="true" focusable="false">
        <path fill="#ffffff" d="M257.5 27.6c-.8-5.4-4.9-9.8-10.3-10.6c-22.1-3.1-44.6.9-64.4 11.4l-74 39.5C89.1 78.4 73.2 94.9 63.4 115L26.7 190.6c-9.8 20.1-13 42.9-9.1 64.9l14.5 82.8c3.9 22.1 14.6 42.3 30.7 57.9l60.3 58.4c16.1 15.6 36.6 25.6 58.7 28.7l83 11.7c22.1 3.1 44.6-.9 64.4-11.4l74-39.5c19.7-10.5 35.6-27 45.4-47.2l36.7-75.5c9.8-20.1 13-42.9 9.1-64.9c-.9-5.3-5.3-9.3-10.6-10.1c-51.5-8.2-92.8-47.1-104.5-97.4c-1.8-7.6-8-13.4-15.7-14.6c-54.6-8.7-97.7-52-106.2-106.8zM208 144a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM144 336a32 32 0 1 1 64 0 32 32 0 1 1 0-64zm224-64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/>
      </svg>
    </span>`;
    btn.addEventListener("click",()=>window.cookieBanner.open());
    document.body.appendChild(btn);
  }

  window.cookieBanner={
    open:()=>build(stateOnly(hasChoice()?readState():DEFAULTS)),
    reset:()=>{ setCookieState({...DEFAULTS}); build(stateOnly(DEFAULTS)); },
    get:()=>{ const s=readState(); return hasChoice()? s : {...stateOnly(DEFAULTS), v:s.v, ts:s.ts}; },
    getRaw:()=>getCookieRaw()
  };

  function init(){
    addLauncher();
    if(!hasChoice()) build(stateOnly(DEFAULTS));
  }
  if(document.readyState==="complete") init();
  else window.addEventListener("load",init);
})();
</script>

Kod zmiennej dla reklam (advertisement)

function () {
  function getConsentCookie() {
    var name = 'consent='; // Nazwa ciasteczka ze zrzutu ekranu
    var decodedCookie = decodeURIComponent(document.cookie); // Dekodowanie znaków specjalnych
    var parts = decodedCookie.split(';');
    
    for (var i = 0; i < parts.length; i++) {
      var c = parts[i];
      // Usuwanie spacji wiodących (alternatywa dla pętli while)
      c = c.trim(); 
      if (c.indexOf(name) === 0) {
        return c.substring(name.length, c.length);
      }
    }
    return '';
  }

  var v = getConsentCookie();

  // Sprawdzamy zgodę
  if (v.indexOf('advertisement:yes') > -1) {
    return 'granted';
  }
  
  // Sprawdzamy odmowę
  if (v.indexOf('advertisement:no') > -1) {
    return 'denied';
  }

  // Domyślna wartość
  return 'denied';
}

Kod zmiennej dla analityki (analytics)

function () {
  function getConsentCookie() {
    var name = 'consent='; // Nazwa ciasteczka ze zrzutu ekranu
    var decodedCookie = decodeURIComponent(document.cookie); // Dekodowanie znaków specjalnych
    var parts = decodedCookie.split(';');
    
    for (var i = 0; i < parts.length; i++) {
      var c = parts[i];
      // Usuwanie spacji wiodących (alternatywa dla pętli while)
      c = c.trim(); 
      if (c.indexOf(name) === 0) {
        return c.substring(name.length, c.length);
      }
    }
    return '';
  }

  var v = getConsentCookie();

  // Sprawdzamy zgodę
  if (v.indexOf('analytics:yes') > -1) {
    return 'granted';
  }
  
  // Sprawdzamy odmowę
  if (v.indexOf('analytics:no') > -1) {
    return 'denied';
  }

  // Domyślna wartość
  return 'denied';
}

Kod zmiennej dla funkcjnych (functionality)

function () {
  function getConsentCookie() {
    var nameA = 'consent=';
    var nameB = 'cookieyes-consent=';
    var decodedCookie = decodeURIComponent(document.cookie); // Dekodowanie znaków
    var parts = decodedCookie.split(';');
    
    for (var i = 0; i < parts.length; i++) {
      var c = parts[i].trim();
      if (c.indexOf(nameA) === 0) return c.substring(nameA.length, c.length);
      if (c.indexOf(nameB) === 0) return c.substring(nameB.length, c.length);
    }
    return '';
  }

  var v = getConsentCookie();

  // Sprawdzamy zgodę
  if (v.indexOf('functionality:yes') > -1) {
    return 'granted';
  }
  
  // Sprawdzamy odmowę
  if (v.indexOf('functionality:no') > -1) {
    return 'denied';
  }

  // Domyślna wartość
  return 'denied';
}

Kod zmiennej dla personaliacji (personalization)

function () {
  function getConsentCookie() {
    var nameA = 'consent=';
    var nameB = 'cookieyes-consent=';
    var decodedCookie = decodeURIComponent(document.cookie); // Dekodowanie znaków
    var parts = decodedCookie.split(';');
    
    for (var i = 0; i < parts.length; i++) {
      var c = parts[i].trim();
      if (c.indexOf(nameA) === 0) return c.substring(nameA.length, c.length);
      if (c.indexOf(nameB) === 0) return c.substring(nameB.length, c.length);
    }
    return '';
  }

  var v = getConsentCookie();

  // Sprawdzamy zgodę
  if (v.indexOf('personalization:yes') > -1) {
    return 'granted';
  }
  
  // Sprawdzamy odmowę
  if (v.indexOf('personalization:no') > -1) {
    return 'denied';
  }

  // Domyślna wartość
  return 'denied';
}

Dodaj komentarz

Paweł Piekarski

Paweł Piekarski

Doktorat z nauk technicznych, ponad 10 lat analizy danych na uczelni i ponad 3 lata w analityce marketingowej.

Z nauki wyniosłem jedną zasadę: wnioski są tyle warte, co dane, na których się opierają. Dlatego najpierw porządkuję dane, a potem pomagam przełożyć je na decyzje, które przynoszą zyski.

Pracuję jako freelancer. Specjalizuję się w GTM, GA4 i BigQuery. Przeprowadzam audyty, wdrożenia od zera (albo po kimś) i opiekę analityczną.

Prowadzę kanał YouTube z ponad 50 filmami o analityce internetowej i biznesowej. Dzielę się darmowymi treściami, żeby ogarnąć analitykę samodzielnie.

Napisz do mnie

Paweł Piekarski
Paweł Piekarski Digital Analyst Marketing oparty na danych

Dane kontaktowe

+48 725 473 745

poczta@pawelpiekarski.pl

linkedin.com/in/pawelpiekarskipl

    Wysyłając wiadomość, zgadzasz się na kontakt i przetwarzanie danych zgodnie z polityką prywatności.