Sovereignty

Why I do not put a GDPR banner on my clients' websites

A cookie banner is not a legal duty, it is the result of a tracking choice. A five-question self-audit, HTTP hardening headers, self-hosted Matomo with Docker Compose, a comparison of Plausible, Umami and GoatCounter, recent fines from the CNIL (the French data protection authority) and the GDPR obligations that remain.

Why I do not put a GDPR banner on my clients' websites
Contents (21 sections)
  1. 1. The banner is the penalty for a technical choice
  2. 2. A five-question self-audit
  3. 3. Four technical choices that remove the need for a banner
  4. Replacing Google Fonts with local fonts
  5. Hardening HTTP headers to block parasitic tracking
  6. 4. The “one-click” banner is not compliant
  7. 5. “But how do I know how many visitors I have?”
  8. 6. Self-hosted Matomo, the only set-up I recommend
  9. Docker Compose for Matomo + MariaDB
  10. 7. The GDPR setting that removes the banner, step by step
  11. Anonymisation and retention settings in config.ini.php
  12. Site-side tracker (with a noscript fallback)
  13. 8. Matomo / Plausible / Umami / GoatCounter compared
  14. Matomo (the most complete)
  15. Plausible (the simplest)
  16. Umami (the balance)
  17. GoatCounter (the no-frills option)
  18. 9. What the GDPR still asks of you
  19. 10. What not tracking really costs
  20. Conclusion
  21. Sources and references

When you visit a French website in 2026, you are greeted by a pop-up. Three columns, pre-ticked boxes, an “Accept all” button given pride of place and a “Customise” link tucked away at the bottom in light grey. It has become so commonplace that people accept it mechanically, which is exactly the point. But this friction is not a legal obligation, it is the direct result of a technical choice: setting trackers.

On the websites I build for my clients, I do not use one. Not out of regulatory laziness, not out of carelessness: quite the opposite, out of maximum compliance. Here is the legal reasoning, the five-question self-audit to check your own site, and the complete stack that lets you stay strictly GDPR compliant without ever bothering visitors with a consent request.

1. The banner is the penalty for a technical choice #

Article 82 of the French Data Protection Act (loi Informatique et Libertés), which transposes the ePrivacy Directive 2002/58/EC, says two simple things: (1) any storage or reading of information on the user's device (cookie, localStorage, fingerprint) requires prior, free and informed consent; (2) unless there is an explicit exception: cookies strictly necessary for the service to work, and audience measurement exempted by the CNIL, the French data protection authority.

The mechanical conclusion: if you set no cookie that requires consent, you have nothing to ask for. No banner, no debate over the wording of “reject all”, no Cookiebot billed at €9 a month. Compliance is achieved upstream, in the code, not as a layer added on top in a widget.

Side-by-side comparison: on the left, a website with an intrusive cookie pop-up and many trackers visible in the network requests; on the right, a clean website with no banner and no trackers
On the left, the visible result of all the hidden trackers. On the right, the same site without GA, without Meta Pixel, without external Google Fonts, and therefore with no banner required.

2. A five-question self-audit #

Before rewriting anything, here is the one-minute audit grid that tells you exactly what justifies your current banner, and what can be removed without breaking anything.

  1. Open the browser DevTools on your home page → Application tab → Cookies. How many are there before any click on the banner? If the answer is “more than 0”, Article 82 applies.
  2. Network tab: how many requests go out to third-party domains (google-analytics.com, googletagmanager.com, fonts.googleapis.com, facebook.net, doubleclick.net, hotjar.com)? Each one is a tracker supplier to remove or justify.
  3. On your contact page: do you use Google reCAPTCHA? Cloudflare Turnstile in managed mode without cookies? hCaptcha? Cloudflare and hCaptcha without cookies are exempt. reCAPTCHA is not.
  4. Fonts: are they served from fonts.googleapis.com (Google receives every visitor's IP address, CJEU penalty in 2022) or self-hosted from your own domain?
  5. Embedded maps and videos: standard Google Maps and classic YouTube set cookies as soon as the page loads (even before a click). In the nocookie embed version with lazy-loading on click, they are exempt.

On 90% of small business and SME websites audited in 2026, the three real culprits are Google Analytics, Google Fonts served externally, and a third-party chat widget (Tawk.to, Crisp in its default configuration). Remove or replace them and no banner is required.

3. Four technical choices that remove the need for a banner #

On a brochure website or a light e-commerce site for a small business or SME, you can reach zero cookies requiring consent with four key decisions:

  1. No Google Analytics, no GTM, no Meta Pixel, no TikTok Pixel, no LinkedIn Insight, no Hotjar. All these tools set profiling cookies that require consent, full stop.
  2. No Google Fonts served by fonts.googleapis.com (which leaks the visitor's IP address to Google, a practice condemned by a German court in 2022): the fonts are downloaded at build time and served from the site's own domain. Next.js does this natively with next/font.
  3. No Google Maps in an iframe or in a script loaded on the home page: replace it with OpenRouteService or MapLibre plus MapTiler or IGN tiles if a map is really needed.
  4. No standard YouTube embeds (which set cookies as soon as the visitor lands on the page): use youtube-nocookie.com with lazy-loading on click, or switch to a self-hosted video with the next/video component.

Replacing Google Fonts with local fonts #

The next/font API downloads Google fonts at build time, optimises them, serves them from your own domain and generates the @font-face CSS automatically. No request to fonts.googleapis.com at runtime.

TSX
// app/layout.tsx - self-hosted fonts via next/font
import { Inter } from "next/font/google";

// Next.js downloads the fonts at build time and serves them from your domain
const inter = Inter({
  subsets: ["latin"],
  display: "swap",
  variable: "--font-inter",
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="fr" className={inter.variable}>
      <body>{children}</body>
    </html>
  );
}

Hardening HTTP headers to block parasitic tracking #

Even without deliberately adding a tracker, some browser extensions or third-party libraries may try to activate modern advertising APIs (Chrome's Topics API, attribution-reporting). An explicit Permissions-Policy disables them, and a strict Content-Security-Policy forbids loading external scripts that are not listed.

TypeScript
// next.config.ts - HTTP hardening headers against tracking
async headers() {
  return [
    {
      source: "/(.*)",
      headers: [
        // Blocks Topics API, FLoC, attribution-reporting, advertising FedCM
        {
          key: "Permissions-Policy",
          value: "browsing-topics=(), interest-cohort=(), join-ad-interest-group=(), attribution-reporting=()",
        },
        // Strict CSP: only scripts from the domain are allowed
        {
          key: "Content-Security-Policy",
          value: "default-src 'self'; script-src 'self'; img-src 'self' data:; connect-src 'self' https://stats.client.fr; font-src 'self'",
        },
      ],
    },
  ];
}

At this point, there may still be one strictly necessary technical cookie: the Cloudflare Turnstile cookie for the duration of an anti-spam challenge, or a session cookie if you really need e-commerce baskets. These cookies are exempt from consent according to the CNIL (decision 2020-091). No banner required.

4. The “one-click” banner is not compliant #

A very widespread variant: the pop-up with a single “OK” or “Accept” box, with no visible “Reject” button at the same level. This has been legally non-compliant since CNIL decision no. 2020-091, as confirmed by the high-profile fines of 2022-2025.

  • Google LLC + Google Ireland: €150m CNIL fine (December 2021), upheld in 2022. Grounds: refusing was less accessible than accepting on google.fr and youtube.com.
  • Meta Platforms Ireland: €60m CNIL fine (January 2022). Same grounds on facebook.com.
  • Microsoft Ireland: €60m CNIL fine (December 2022). Grounds: no “reject” button on bing.com.
  • Criteo SA: €40m CNIL fine (June 2023). Grounds: invalid consent for retargeting.

The CNIL rule has become crystal clear: if you ask for consent, the “Reject all” button must be presented with the same level of accessibility, in the same typeface and with the same colour weight as “Accept all”. Any dark pattern that makes refusing harder exposes you to a penalty. One more reason not to need the banner at all: being compliant costs less than becoming compliant.

5. “But how do I know how many visitors I have?” #

That is the real question. For 70% of the small businesses I come across, the honest answer is: “you do not need to know it to the nearest visitor”. You already know how many leads come through the contact form (e-mail). You can see your Search Console positions. You have your sales figures. The vanity metric “1,247 unique visitors this week” changes nothing for your business, especially if half of them are bots.

For the remaining 30% (e-commerce sites, sites with a conversion funnel to optimise, editorial sites that track their best-performing articles), we install self-hosted Matomo. And we configure it so that it stays exempt from the banner.

6. Self-hosted Matomo, the only set-up I recommend #

Matomo is the open source alternative to Google Analytics, under the GPLv3 licence. Two versions exist side by side: Matomo Cloud (SaaS, hosted by Matomo) and self-hosted Matomo (you install it on your own server). Only the second allows maximum compliance and full sovereignty over the data: that is what I install for my clients.

Architecture diagram of self-hosted Matomo: site visitor, Matomo Docker container on stats.client.fr, isolated MariaDB database, local processing with no transfer to third parties
Typical architecture of a self-hosted Matomo: a Docker container behind a dedicated subdomain, an isolated MariaDB database, no data sent to any third party.

Docker Compose for Matomo + MariaDB #

The typical deployment fits in a single docker-compose.yml file on the same VPS as the website, behind a stats.client.fr subdomain with a Let's Encrypt TLS certificate.

YAML
# docker-compose.yml - minimal self-hosted Matomo
services:
  matomo-db:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MARIADB_DATABASE: matomo
      MARIADB_USER: matomo
      MARIADB_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./data/db:/var/lib/mysql
    networks: [matomo]

  matomo:
    image: matomo:5-apache
    restart: unless-stopped
    environment:
      MATOMO_DATABASE_HOST: matomo-db
      MATOMO_DATABASE_USERNAME: matomo
      MATOMO_DATABASE_PASSWORD: ${DB_PASSWORD}
      MATOMO_DATABASE_DBNAME: matomo
    volumes:
      - ./data/matomo:/var/www/html
    ports:
      - "127.0.0.1:8080:80"
    depends_on: [matomo-db]
    networks: [matomo]

networks:
  matomo:

Automatic encrypted backups via PBS or borgbackup to a second site, monthly updates via docker compose pull && docker compose up -d. Marginal hosting cost: a few euros a month on a VPS that already hosts other things.

7. The GDPR setting that removes the banner, step by step #

To stay within the CNIL exemption for “strictly necessary audience measurement” (decision 2020-091), Matomo must be configured according to five strict rules. Most of them can be enabled in config/config.ini.php.

  • IP anonymisation: truncate the last 2 bytes (IPv4) or the last 80 bits (IPv6) before any processing.
  • Cookieless mode: disable the creation of tracking cookies. Matomo rebuilds the session through a server-side fingerprint based on the anonymised IP + User-Agent.
  • Limit the retention of detailed data to 13 months maximum, with aggregation beyond that.
  • Disable User ID, cross-site tracking and enrichment by third parties (geo, social media).
  • No export to BigQuery, Google Ads or Meta Ads. If you want advertising retargeting, it requires consent and therefore a banner: you have left the exemption.

Anonymisation and retention settings in config.ini.php #

INI
; /var/www/html/config/config.ini.php

[General]
; Truncate the last 2 IP bytes before any processing
anonymize_ip_mask_length = 2
anonymize_ip_mask_length_ipv6 = 80

[Tracker]
; Cookieless mode: no tracking cookies
ignore_visits_cookie = 1
enable_fingerprinting_across_websites = 0

[Deletelogs]
; 13-month retention (395 days), automatic purge afterwards
delete_logs_enable = 1
delete_logs_schedule_lowest_interval = 7
delete_logs_older_than = 395

Site-side tracker (with a noscript fallback) #

The snippet to insert in the <head> or the main layout. The disableCookies directive is essential: it is what prevents the _pk_id cookie from being set on the visitor's device.

HTML
<!-- Matomo tracker, cookieless mode with noscript fallback -->
<script>
  var _paq = window._paq = window._paq || [];
  _paq.push(['disableCookies']);            // No cookie set
  _paq.push(['setDoNotTrack', true]);       // Respect the DNT header
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u = "https://stats.client.fr/";
    _paq.push(['setTrackerUrl', u + 'matomo.php']);
    _paq.push(['setSiteId', '1']);
    var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
    g.async = true; g.src = u + 'matomo.js';
    s.parentNode.insertBefore(g, s);
  })();
</script>
<noscript>
  <img referrerpolicy="no-referrer-when-downgrade"
       src="https://stats.client.fr/matomo.php?idsite=1&amp;rec=1"
       style="border:0" alt="">
</noscript>

Once configured this way, Matomo falls fully within the CNIL exemption. You measure page views, sessions, traffic sources, user journeys and conversions, all with no banner, no tracking cookie and no transfer to a third party.

8. Matomo / Plausible / Umami / GoatCounter compared #

Four tools dominate the market for “compliant cookieless” analytics. The choice depends on the trade-off between functional richness, front-end performance and hosting complexity.

Matomo (the most complete) #

  • Model: self-hosted (free, GPLv3) or paid Cloud SaaS.
  • Stack: PHP + MariaDB / PostgreSQL. Official Docker container.
  • Tracker weight: ~28 KB gzipped. Heavier than the alternatives.
  • Features: heatmaps, A/B testing, funnels, e-commerce, media, customer journey, A/B tests, a full Google Analytics level.
  • CNIL exemption: yes, after configuration (anonymisation + cookieless + 13-month retention).
  • Ideal for: e-commerce sites, editorial sites that need funnels and cohorts.

Plausible (the simplest) #

  • Model: paid Cloud SaaS (~€9/month) hosted in Germany (Hetzner Helsinki), or free self-hosted (CE).
  • Stack: Elixir + PostgreSQL + ClickHouse. Official Docker image.
  • Tracker weight: < 1 KB gzipped. Unbeatable for Lighthouse.
  • Features: pages, sources, devices, countries, goals, but no advanced funnels and no heatmaps.
  • CNIL exemption: yes, natively (cookieless by design).
  • Ideal for: brochure websites, blogs, SaaS, when you just want to know what works.

Umami (the balance) #

  • Model: free self-hosted (MIT) or paid Cloud.
  • Stack: Next.js + PostgreSQL / MySQL. Very well integrated with the Vercel ecosystem.
  • Tracker weight: ~2 KB gzipped.
  • Features: equivalent to Plausible with a more modern UI, native multi-site support.
  • CNIL exemption: yes, natively (cookieless).
  • Ideal for: JS developers who want a light, self-hosted set-up without managing PHP.

GoatCounter (the no-frills option) #

  • Model: free SaaS for small sites (< 100k page views/month) hosted by the author, or free self-hosted.
  • Stack: monolithic Go with a SQLite or PostgreSQL database.
  • Tracker weight: ~3 KB gzipped.
  • Features: basic statistics only. No funnel, no e-commerce.
  • CNIL exemption: yes, natively (cookieless, no fingerprinting).
  • Ideal for: personal blogs, association websites, open source projects that want an honest counter.

Selection criterion in two questions: do you need funnels, heatmaps or advanced e-commerce? → Matomo. Otherwise → Plausible or Umami. Self-hosted whenever possible, European SaaS otherwise. Never Google Analytics.

9. What the GDPR still asks of you #

Removing the banner does not exempt you from the remaining GDPR obligations. Whatever happens, you must keep three things visible on your website.

  • A privacy policy accessible from every page (GDPR Art. 13): it details the data collected, however minimal (server logs, contact form, exempted audience measurement).
  • A compliant legal notice (LCEN, the French e-commerce law, Art. 6): identity of the publisher, the host and the publication director.
  • Respect for the right to object (GDPR Art. 21): even if you measure your audience without consent, a visitor can ask to be excluded. Matomo and Plausible offer a one-line opt-out.

For the contact form, the GDPR requires a notice on what happens to the data (retention period, purpose, legal basis: legitimate interest or explicit consent). One sentence is enough, but it has to be there.

10. What not tracking really costs #

On a site with no banner and no tracker, you save: the Cookiebot or Axeptio licence (€200 to €600 a year), the time spent debugging consent variations between Chrome, Safari and Firefox, and the conversions lost to visitors who click “reject” and never come back. You gain: a Lighthouse score of 95+ without effort, a privacy policy that fits on one page, and visitors who do not take you for an advertising agency.

The cost of adding self-hosted Matomo: ~30 minutes of provisioning on existing infrastructure (the docker-compose.yml above deployed on a VPS), plus monthly maintenance (security updates). On the sites I manage, it is included in the managed hosting service. For a client who hosts elsewhere, I bill it separately.

Conclusion #

A cookie banner is not an obligation: it is the result of a tracking choice. If you remove the trackers, you remove the banner. And if you really need to measure, a well-configured self-hosted Matomo (IP anonymisation, cookieless, 13-month retention) covers 95% of cases, while staying strictly compliant with CNIL doctrine and the GDPR, without ever disturbing a visitor or risking a fine.

If you want to audit your current site to find out what justifies your banner and see what can be removed without harming SEO or conversions, that is usually the first step of a compliance service: allow two to four hours for the full pass, with actionable recommendations at the end.

Sources and references #

The legal and technical references in this article are based on CNIL doctrine, the official texts on Légifrance and EUR-Lex, and the documentation of the tools mentioned, up to date as of May 2026.

  1. CNIL, Decision no. 2020-091 of 17 September 2020 (guidelines on cookies and trackers, in French): https://www.cnil.fr/fr/cookies-et-autres-traceurs-la-cnil-publie-des-lignes-directrices-modificatives-et-sa-recommandation
  2. CNIL, Decision no. 2020-092 of 17 September 2020 (recommendations on banners, in French): https://www.cnil.fr/fr/cookies-et-autres-traceurs-la-cnil-publie-des-lignes-directrices-modificatives-et-sa-recommandation
  3. Légifrance, Article 82 of Law no. 78-17 (French Data Protection Act, in French): https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000037813978
  4. EUR-Lex, ePrivacy Directive 2002/58/EC: https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX:32002L0058
  5. EUR-Lex, Regulation (EU) 2016/679, GDPR (Article 13, information): https://eur-lex.europa.eu/eli/reg/2016/679/oj
  6. CNIL, Cookies and trackers: what does the law say? (in French): https://www.cnil.fr/fr/cookies-et-traceurs-que-dit-la-loi
  7. CNIL, Audience measurement exempt from consent (in French): https://www.cnil.fr/fr/la-mesure-daudience-exemptee-de-consentement
  8. CNIL, €150m fine for Google LLC + €90m for Google Ireland (in French): https://www.cnil.fr/fr/cookies-sanction-de-150-millions-deuros-lencontre-de-google-llc-et-90-millions-deuros-lencontre-de
  9. CNIL, €60m fine for Meta Platforms Ireland (Facebook) (in French): https://www.cnil.fr/fr/cookies-sanction-de-60-millions-deuros-lencontre-de-facebook-ireland-limited
  10. CNIL, €60m fine for Microsoft Ireland (Bing) (in French): https://www.cnil.fr/fr/cookies-sanction-de-60-millions-deuros-lencontre-de-microsoft-ireland-operations-limited
  11. CNIL, €40m fine for Criteo (in French): https://www.cnil.fr/fr/sanction-de-40-millions-deuros-lencontre-de-la-societe-criteo
  12. CJEU, Google Fonts decision (LG München, January 2022): https://noyb.eu/en/google-fonts-german-court-confirms-100-fine
  13. Matomo, official documentation (anonymisation, GDPR): https://matomo.org/faq/general/faq_146/
  14. Matomo, Privacy Compliance Tools: https://matomo.org/privacy/
  15. Plausible Analytics, official documentation: https://plausible.io/docs
  16. Umami, official documentation: https://umami.is/docs
  17. GoatCounter, official website: https://www.goatcounter.com/
  18. Next.js, next/font (self-hosting Google fonts): https://nextjs.org/docs/app/api-reference/components/font
  19. MDN, Permissions-Policy HTTP header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy
  20. MDN, Content-Security-Policy HTTP header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
About
01/Read nextThree articles

Related articles

Sovereignty

NIS2: what the directive says, where France stands, and why we do all this without being required to

Bastion, SIEM, immutable backups, deliberate patching, ANSSI self-audit: for six months this blog has documented an infrastructure that a company of our size has no legal obligation to build. The reason fits in four characters. What NIS2 really requires, the state of French transposition in autumn 2026, and how our building blocks line up against the 20 objectives of the ANSSI framework.

nis2anssi
Sovereignty

One consultant, one AI, 25 million SIM cards

A national interception platform written by a lone consultant, the court warrant requirement removed at the client's request, and an account ban that stopped nothing because the software now runs locally. The surveillance chapter of the Anthropic report is the most disturbing, and it says something very concrete about the data you hold.

surveillanceai
Sovereignty

ReCyF explained for SMEs: the ANSSI cyber framework, who must apply it, and where to start

On 17 March 2026, ANSSI published the Référentiel Cyber France (French cyber framework): 20 security objectives, four pillars, an operational translation of NIS2 before the law even exists. Many companies wonder whether they are concerned, and what they risk. A clear answer in three questions, a jargon-free reading of the 20 objectives, and the five to start with even when nothing obliges you to.

recyfanssi

What next

Keep your data in France, out of reach of the Cloud Act?

Dedicated servers in France, known sub-processors, backups kept out of reach. First conversation free.

Discuss your project

Reply within 24 working hours, from one of the two founders. Or by phone: +33 7 59 96 14 99.