Creating Custom Cookie Banner in Wix For Free

Michael Mares
8 min readFeb 17, 2024

Difficulty: Advanced to Pro

Time: 60min

Requires coding: copy-paste only

In this tutorial, you will find a recipe for such a tasty cookie bar!

Introduction

I thought all is lost when after browsing countless forums no-one seemed to have an answer to the question of creating your own cookie bar.

Don’t get me wrong, I enjoy the Wix environment and their consent mode work well. It is GDRP compliant out of the box but there is one annoying thing about it.

It does not allow you to customize it. And it sticks to the bottom of the page, making it very easy to ignore for users.

And without a consent, by default Wix will not fire analytics. I have lost about 50% of my data when I moved https://studentsurvivalguide.dk/ over to Wix, from Webflow.

So I decided to go down the rabbit hole and see if I can make a solution myself.

Luckily, there is a way to create your own, customizable cookie banner that is GDPR compliant on Wix.

This tutorial is derived from my dev notes and goes through the process chronologically. There might be a few dead-ends as it usually happens during real reserach. Functional code snippets are by the end of the article.

Research phase

I’ve tried adjusting the native cookie banner from Wix using the head code injection. This proved very difficult and prone to errors. We would have to attach mutation observers as Wix is React based and this could slow down the whole site.

But it seems like there is a wrapper around the consent policy setConsentPolicy() which allows us to set the consent policy, reset it or accept only selection.

To be able to work with code in Wix, you need to enable the Dev Mode. Read more here: https://dev.wix.com/docs/develop-websites/articles/getting-started/resources/about-velo-by-wix

import { consentPolicy } from 'wix-window-frontend';
// ...
const myPolicy = {
essential: $w('#essentialCheckbox').checked,
analytics: $w('#analyticsCheckbox').checked,
functional: $w('#functionalCheckbox').checked,
advertising: $w('#advertisingCheckbox').checked,
dataToThirdParty: $w('#dataToThirdPartyCheckbox').checked
};
consentPolicy.setConsentPolicy(myPolicy)
.then((policyDetails) => {
const newPolicy = policyDetails.policy;
return policyDetails;
})
.catch((error) => {
console.error(error);
});
// This returns the following
/* policyDetails value:
* {
* "defaultPolicy" : false,
* "policy" : {
* "essential" : true,
* "functional" : false,
* "analytics" : false,
* "advertising" : false,
* "dataToThirdParty" : false
* },
* "createdDate" : 2020-12-20T12:33:09.775Z
* }
*/

Therefore, if we can construct our own cookie banner, we could simply hide the current banner programmatically and only display the new one.

Let’s now test the following code. We will add a button to the page that, when pressed, will set the consent to our selection:

export function button7_click(event) {
const myPolicy = {
essential: true,
analytics: true,
functional: true,
advertising: true,
dataToThirdParty: true,
};
consentPolicy.setConsentPolicy(myPolicy)
.then((policyDetails) => {
const newPolicy = policyDetails.policy;
console.log("New Policy: ", newPolicy);
return policyDetails;
})
.catch((error) => {
console.error(error);
});
}
Buttons were programmatically linked to the consent policy reset. One button would wipe the consent memory and the other would accept all.

Sure enough, the Wix API wrapper fires and we have sent the request to set the user cookie policy.

Now we have two major steps in front our ourselves:

  • Design the cookie bar
  • Disable the original cookie bar

I would like to avoid turning off the cookie bar in settings. When we turn it off, we will lose the functionality of having the small ‘cookie settings’ box on the side and I am not sure how will it impact the tracking.

There are two scenarios that could happen when we turn of the cookie bar in the settings:

  1. All tracking will work immediatelly
  2. No tracking will work as we will not have a consent

It turns out that the first options is true, if we disable the original cookie banner by Wix.

Therefore, we need to keep the original and hide it when it becomes rendered in the DOM.

🍪 We can see that the default (before user accepts cookies) is as follows. Once the user accepts cookies, following is set to the cookies:

"consent-policy":{
"ess":1,"func":1,"anl":0,"adv":0,"dt3":1,"ts":28468143
}

Nothing shows in the data layer until we hit ‘accept all’ which means that our method will be feasible.

This alleviates a little bit of pressure from our side, as we do not have to worry about default states etc.

Now onto the second step:

Create custom cookie bar

Our custom cookie bar should be a Lightbox and it should be triggered when the user is not having the defaultPolicy.

Then we need to create the small widget on a side which will open the additional settings.

Go to Site Pages and Menu > Lightboxes and ‘+ Add’.

Then choose the full page lightbox. Do not worry too much about which one you chose, we will be modifying it anyways.

Let’s disable this option so that people cannot click away before accepting or denying cookies.

In the same way, you can disable the little ‘X’ button on the top right corner. Now I will paste my own design:

Now we have our cookie banner but the buttons are not yet functional.

We need to now set up three functions:

  1. Function to open the lightbox for new visitors
  2. Function to accept all the cookies/deny all the cookies
  3. Function to save selected cookies from the ‘Details’ panel

First step is to rename all the buttons and toggles into something meaningful to work with. From default, these things are named ‘#button1’ or ‘#toggle-3’ which is not very informative.

In the code bellow, you can see how I named my variables. It should be easy to follow the convention though the code is not too difficult to rewrite to your needs.

Code for the lightbox:

import { consentPolicy, lightbox } from 'wix-window-frontend';
const acceptAllPolicy = {
essential: true,
dataToThirdParty: true,
functional: true,
analytics: true,
advertising: true,
};
const essentialsPolicy = {
essential: true,
functional: true,
dataToThirdParty: true,
analytics: false,
advertising: false,
};
const rejectPolicy = {
functional: false,
essential: false,
dataToThirdParty: false,
analytics: false,
advertising: false,
};
$w.onReady(function () {
// Accept all cookies when 'Accept All' is clicked
$w('#buttonAcceptAll').onClick(() => {
acceptAndClose(acceptAllPolicy);
})
// Accept all cookies when 'Accept All' is clicked
$w('#buttonAcceptAll2').onClick(() => {
acceptAndClose(acceptAllPolicy);
})
// Accept essentials when 'Only Essential' is clicked
$w('#buttonOnlyEssentials').onClick(() => {
acceptAndClose(essentialsPolicy);
})

// Accept only selected cookies
$w('#buttonAcceptSelection').onClick(() => {
const customPolicy = {
essential: $w('#toggleNecessary').checked,
analytics: $w('#toggleAnalytics').checked,
functional: $w('#toggleFunctional').checked,
advertising: $w('#toggleAdvertising').checked,
dataToThirdParty: $w('#toggleThirdParty').checked
};
acceptAndClose(customPolicy);
})
// Reject all cookies
$w('#buttonRejectCookies').onClick(() => {
acceptAndClose(rejectPolicy);
})
// Change tab on button click - details
$w('#buttonShowMore').onClick(() => {
// Open the tab titled 'Details' in the lightbox
$w('#tabs1').changeTab('singleTab1');
})
// Change tab on button click - main
$w('#buttonBackCookies').onClick(() => {
// Open the tab titled 'Details' in the lightbox
$w('#tabs1').changeTab('singleTab3');
})
})
const acceptAndClose = function (policy) {
consentPolicy.setConsentPolicy(policy)
.then((policyDetails) => {
const newPolicy = policyDetails.policy;
console.log("New Policy: ", newPolicy);
lightbox.close(); // Close the lightbox after setting the consent policy
return policyDetails;
})
.catch((error) => {
console.error(error);
});
}

Now that the lightbox is constructed, it is time to add some code to the masterPage.js in order to open the lightbox automatically if the user has not been to the site before. We can see this by inspecting the const policyDetails = consentPolicy.getCurrentConsentPolicy(); .

If the current policy is policyDetails.default === true then we can open the lightbox.

Here is the code we should place in masterPage.js:

import wixWindowFrontend from 'wix-window-frontend';
import { consentPolicy } from 'wix-window-frontend';

$w.onReady(function () {
const policyDetails = consentPolicy.getCurrentConsentPolicy();
console.log("Current policy on start: ", policyDetails)
if (policyDetails.defaultPolicy === true) {
console.log("Current policy is default")
wixWindowFrontend.openLightbox("Cookie Banner");
}

consentPolicy.onConsentPolicyChanged((policy) => {
console.log("New policy set ", policy)
if (policy.defaultPolicy === true) {
wixWindowFrontend.openLightbox("Cookie Banner");
}
});
});

Disable native cookie bar

It seems like the consent policy gets set to “all accepted” if we do not have the cookie bar activated. The previous testing probably did not update the consent bar settings fast enough

Therefore, we will need to add a mutation observer and hide this cookie banner programatically.

As we need to add this to every page on the site, it might slow down the performance of the site eventually. I am not a web developer so I cannot say how much of an impact would this have. This could be easily solved by Wix allowing you to set the default consent state in the settings.

We can do this by adding it at the end of the body in the Settings > Custom Code section.

<script>
function hideConsentBanner(mutations, observer) {
// Query for the consent banner element
const consentBanner = document.querySelector('.consent-banner-root');// If the banner is found, hide it
if (consentBanner) {
consentBanner.style.display = 'none';
console.log('Consent banner hidden successfully.');
// Once the banner is handled, disconnect the observer
observer.disconnect();
console.log('MutationObserver disconnected.');
}
}
// Create a new MutationObserver instance and pass the callback function
const observer = new MutationObserver(hideConsentBanner);
// Start observing the document for added nodes or subtree modifications
observer.observe(document.body, { childList: true, subtree: true });
// Set a timeout to disconnect the observer after 5 seconds if the banner hasn't appeared
setTimeout(() => {
if (observer) {
observer.disconnect();
console.log('MutationObserver disconnected after timeout.');
}
}, 5000);

</script>

We can now also add a little icon that will open up the lightbox, once a selection is made.

Our final product will look something like this:

Conclusion

Process of creating a custom cookie bar on Wix can be challanging but the good news is that it is not impossible. In this tutorial we saw that we can use the Velo API to work with user’s consent programatically. This allows us to create our own solution for setting consent and cookies without relying on the built-in solutions.

Note

I would love to share with you the “code” for the cookie banner but Wix does not allow any sort of export (as far as I know). I know that Webflow allowed for a preview mode where you could clone the site but I am not aware of such feature for Wix. If you know about a way, let me know and I will include it in the article.

--

--

Michael Mares

I like to explore and challenge my worldview about technology, money and mental health.