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é

1 Like

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.

1 Like

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.

1 Like

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.

3 Likes

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

1 Like

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');
}
1 Like

@jessxuan Thanks for sharing!

1 Like