Websites

Add a cookie consent banner to your website

In Quebec, a banner that simply announces that a website uses cookies is no longer enough. Cookies and scripts that can identify, locate or profile a visitor, such as audience measurement, advertising or social media pixels, must stay off until the visitor accepts them. This guide is for website owners and outlines a practical approach.

This guide provides general information and is not legal advice. For a specific situation, consult a qualified privacy professional.

On this page

What Law 25 requires

Since September 22, 2023, section 8.1 of the Act respecting the protection of personal information in the private sector governs technologies that can identify, locate or profile a person. These functions must be deactivated by default: visitors must be informed that they are used and of the means to activate them, and they are enabled only with consent.

  • Strictly necessary cookies: a session, a shopping cart, a security protection or remembering the consent choice itself does not require consent. Still describe them in your cookie or privacy policy.
  • Other cookies and scripts: audience measurement, advertising, retargeting and embedded content that sets trackers load only after acceptance.

Consent must be manifest, free, informed and given for specific purposes. In practice:

  • offer choices by category, for example “Audience measurement” and “Advertising”;
  • make refusing as easy as accepting, with a Refuse button as visible as the Accept button;
  • use no pre-checked boxes, and do not treat continued browsing or scrolling as consent;
  • let visitors change or withdraw their choice at any time, for example through a permanent link in the footer;
  • keep a record of the consents obtained: date, choices made and the version of the policy shown.

If your website receives visitors from the European Union, the GDPR and the ePrivacy Directive also require prior consent for non-essential cookies. Check the requirements of each jurisdiction whose customers you target.

  1. Inventory cookies and scripts. Open your website in a private browsing window, then use the browser’s developer tools: the storage tab shows cookies and the network tab shows the services contacted. Remember plugins, the theme, the tag manager, videos, maps and chat tools.
  2. Classify each item. For each cookie or script, note its purpose, provider and duration, then decide whether it is strictly necessary for the function the visitor requested. When in doubt, treat it as non-essential.
  3. Choose a consent tool. A consent management platform or a suitable plugin for your CMS avoids many mistakes. Check that it actually blocks scripts before consent, offers a Refuse button and categories, lets visitors reopen their choices, keeps consent records and displays in French and English if your website is bilingual. A custom implementation is possible, but it needs the same rigour.
  4. Load non-essential scripts only after consent. Remove them from the page code and let the consent tool add them once the matching category is accepted. Some analytics or advertising services offer a consent mode: follow their current documentation.
  5. Update your policy. Describe the categories, purposes, providers, retention periods and how to change a choice. Link to the policy from the banner and the footer.
  6. Test with a fresh browser. In a private window, check that no non-essential cookie is set and no tracking service is contacted before a choice is made. Refuse, then check that nothing loads. Then accept and confirm that only the chosen categories load and that the choice can be changed. Repeat the test on mobile and in each language of the website.

Minimal custom example

The following example loads an audience measurement script only after consent has been recorded. The address https://analytics.example.com/script.js and the policy link are examples to replace with your own. Place this code just before the </body> tag in your templates.

HTML
<div id="consent-banner" hidden>
  <p>
    We use audience measurement cookies only if you accept them.
    <a href="/cookie-policy/">Learn more</a>
  </p>
  <button type="button" data-consent="refuse">Refuse</button>
  <button type="button" data-consent="accept">Accept</button>
</div>
<button type="button" id="consent-settings">Cookie settings</button>

<script>
  (function () {
    var KEY = "consent-analytics";
    var banner = document.getElementById("consent-banner");
    var loaded = false;

    function loadAnalytics() {
      if (loaded) return;
      loaded = true;
      var script = document.createElement("script");
      script.src = "https://analytics.example.com/script.js";
      script.async = true;
      document.head.appendChild(script);
    }

    function readChoice() {
      try {
        return localStorage.getItem(KEY);
      } catch (error) {
        return null;
      }
    }

    function saveChoice(value) {
      try {
        localStorage.setItem(KEY, value);
      } catch (error) {}
    }

    var choice = readChoice();
    if (choice === "accept") {
      loadAnalytics();
    } else if (choice !== "refuse") {
      banner.hidden = false;
    }

    banner.addEventListener("click", function (event) {
      var button = event.target.closest("[data-consent]");
      if (!button) return;
      var value = button.getAttribute("data-consent");
      saveChoice(value);
      banner.hidden = true;
      if (value === "accept") loadAnalytics();
    });

    document
      .getElementById("consent-settings")
      .addEventListener("click", function () {
        banner.hidden = false;
      });
  })();
</script>

Until a choice is recorded, the banner is displayed and the analytics script is not loaded. The Cookie settings button reopens the banner so the choice can be changed. If a visitor withdraws consent, a script that has already loaded stays active until the page is reloaded; also delete the service’s cookies as described in its documentation.

The choice remembered in the browser is necessary storage, but it is not proof of consent: keep a record on your side or use a tool that does. This example handles a single category; add separate choices for each additional category.

References

For a question about hosting your website with Nuagerie, see our Support page. For general questions, see our Contact page.