How to set a cookie that reminds a user accepted cookies' privacy setting

As the title suggests, I want to set a cookie that remembers that a user accepted the banner informing the website makes use of cookies (in my case Google Analytics—as you might know, in Europe you have to explicitly state this thing now).

Since I have no experience in this, what’s the best way to accomplish this?

Using Javascript or PHP? Does Kirby have particular options for this?

Thanks,
André

You can use the methods of the cookie API: https://getkirby.com/docs/toolkit/api#cookie

Great!
Are these methods to be used with <?php if ( ): ?> ?

Would you mind to make an example?

Yes, like this:

<?php if(!cookie::exists('accepted')) {
  cookie::set('accepted', 'true', 1440);
}
?>

This code checks if the cookie with the name “accepted” has already been set, if not, the cookie is set with the value “true” and a lifetime of 24 hours. For more options, see the docs.

You can check if the cookie has been set with

<?= cookie:get('accepted') ?>

Hope this helps.

It’s been helpful, thank you.

I am trying to adapt it now, and if I set it like this:

<?php if(!cookie::exists('accepted')): ?>
<div class="banner">
  <p>cookie already exists</p>
</div> 

<?php else(cookie::set('accepted', 'true', 1440*365)): ?>
<div class="banner">
  <p>cookie has been set now</p>
</div> 	
<?php endif ?>

It tells me that it expects a : instead of the ( on <?php else(.
If I change the else to else if, I get no error, but the cookie is not set.

What am I mixing up in the code?

Oh, that does not make sense, apart from the fact that the syntax is not correct, the else bit will never happen.


<?php 
// if the cookie does not exist, show a banner that the cookie does not exist
if(!cookie::exists('accepted')): ?>
<div class="banner">
  <p>cookie does not exist, but we want to know all about you, so click on OK</p>
</div> 

<?php
// then set the cookie (in reality you want to set the cookie when the user has clicked on OK though
cookie::set('accepted', 'true', 1440*365); ?>
<!-- you don't really need this second banner, do you? -->
<div class="banner">
  <p>cookie has been set now</p>
</div> 	
<?php endif ?>
```

following worked fine for me on various projects.

Since I had to apply the php function to a button and, looking it up, I would have had to use AJAX, I just preferred to go with the jQuery plugin.

Thank you @bnomei! and thanks inimitable @texnixe!

@afincato, do you use jQuery anywhere else on your website? If yes, then adding a jQuery plugin can make sense.

Otherwise, adding a few lines of AJAX to set the cookie is perfectly fine. There are also vanilla JS alternatives like http://cookie-bar.eu/

You could also do this with no Javascript whatsoever. If that’s something you’re looking for.

I am already using jQuery for a plugin that filters content (quite important for the website), so yeah, no problem.

Otherwise I would have tried to avoid it, of course!
:smiley:

All good then :wink: I’ll get around to building a Kirby plugin for this very soon.

@Thiousi I will use your plugin when it’s ready. :slight_smile:

Sorry to revive this old thread!

I’m trying to add cookies to a site for the first time and am having some troubles. Upon looking through cookie-bar linked above, it seems to have some dependencies on bower or gulp? Im not using either or even jquery.

I think the best solution would be to use the kirby cookie API but I can’t find anything solid that explains how to use ajax for the button state without jquery…

My repurposed code from above:

<?php if(!cookie::exists('cookies')): ?>
  <div class="banner">
    <p>daikon* uses cookies to track visits statistics.
      <a href="/privacy.html" id="cookies-button">Read more</a>
      <button name="cookies-reject" id="cookies-reject">Reject</button>
      <button name="cookies-accept" id="cookies-accept">Accept</button></p>
  </div>

  <?php cookie::forever('cookies', 'daikonflavouredcookie', '/', null); ?>
  
<?php endif ?>

How do I run the function to launch analytics + set cookie upon the user clicking the accept button without jquery?

If you don’t want to use jQuery, you can do it with a vanilla JS , here are some resources that might help to send an Ajax request:

This one is a lovely and small library to work with cookies in js if anyone is looking for one: https://github.com/js-cookie/js-cookie

thanks both @texnixe and @manuelmoreale!!

I’ve gotten some help from a dev at Ecosia in using the above library (vanilla js, no ajax) and here’s our working solution for anyone who needs it.

in document header

  <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>

In my body

<div id="cookies-banner" class="cookies-banner grid-container-copy">
  <p>daikon* uses cookies to track visits statistics.
    <span class="cookie-buttons">
      <button name="reject-cookies" id="reject-cookies">Reject</button>
      <button name="accept-cookies" id="accept-cookies">Accept</button>
    </span>
  </p>
</div>

in my style.css

.cookies-banner {
    display: none;
}

in my cookies.js

window.onload = function() {

  // defining cookie
  var daikonCookie = Cookies.getJSON('daikoncookie');

  // check if cookie has been accepted
  if (daikonCookie && daikonCookie.analytics) {
    addAnalytics();
    initialiseAnalytics();
    return;
  }

  // else declare variables
  var acceptBtn = document.getElementById('accept-cookies');
  var rejectBtn = document.getElementById('reject-cookies');
  var cookiesText = document.getElementById('cookies-text');
  var cookiesBanner = document.getElementById('cookies-banner');

  // display the banner (adjust to your default style e.g. block)
  cookiesBanner.style.display = 'grid';

  // listen for on click
  acceptBtn.addEventListener('click', function() {
    Cookies.set('daikoncookie', { analytics: true }, { expires: 365 });
    cookiesBanner.style.display = 'none';
    addAnalytics();
    initialiseAnalytics();
   });

   rejectBtn.addEventListener('click', function() {
     cookiesBanner.style.display = 'none';
   })

 };

// tweaked from stackoverflow to async load the analytics and initialise it
function addAnalytics() {
  var ga = document.createElement('script');

  ga.type = 'text/javascript';
  ga.async = true;
  ga.src = 'https://www.googletagmanager.com/gtag/js?id=UA-XXX-1';

  var scriptTag = document.getElementsByTagName('script')[0];
  scriptTag.parentNode.insertBefore(ga, scriptTag);
}

function initialiseAnalytics() {
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-XXX-1');
}

@jessxuan Thanks for sharing!