L'essentiel
Un site Next.js qui charge Google Analytics, le Meta Pixel ou tout autre traceur doit recueillir le consentement des visiteurs avant que ces scripts s'exécutent, comme l'exigent le RGPD et l'article 82 de la loi Informatique et Libertés. Afficher une bannière ne suffit pas : les scripts non essentiels doivent rester bloqués jusqu'à l'accord explicite, les signaux Google Consent Mode v2 doivent partir à l'état denied, le choix doit être respecté à chaque navigation côté client et vous devez conserver une preuve de chaque consentement. Ce guide couvre les exigences du RGPD, les spécificités de Next.js (App Router, Server Components, navigation SPA, SSR) et une mise en œuvre pas à pas.
Pourquoi la conformité cookies est critique pour une app Next.js
Next.js est un framework React très utilisé pour les sites marketing, les boutiques e-commerce, les SaaS et les sites éditoriaux, souvent déployés sur Vercel ou Netlify. Sa souplesse est aussi son principal risque de conformité : les développeurs y ajoutent couramment Google Analytics 4, Google Tag Manager, le Meta Pixel, Hotjar, Intercom et d'autres outils, qui déposent tous des cookies ou des traceurs équivalents soumis au consentement préalable.
L'erreur la plus fréquente consiste à charger ces scripts dans _app.tsx, app/layout.tsx ou un composant Layout partagé, sans aucune vérification du consentement. Ce schéma est extrêmement répandu et constitue une violation nette du RGPD : les traceurs se déclenchent dès la première page, avant que le visiteur ait pu choisir quoi que ce soit.
Les conséquences sont réelles. La CNIL a infligé des amendes de plusieurs dizaines de millions d'euros à de grands sites pour des manquements liés aux cookies, les plaintes d'associations comme noyb se multiplient, et une bannière qui ne fait pas ce qu'elle annonce abîme la confiance des utilisateurs.
Ce que le RGPD exige pour les cookies dans Next.js
Le RGPD, combiné à la directive ePrivacy, impose trois obligations pour les cookies non essentiels : informer clairement l'utilisateur, recueillir son consentement avant d'activer les traceurs, et lui permettre de retirer ce consentement aussi facilement qu'il l'a donné.
Quels cookies nécessitent un consentement ?
La plupart des outils tiers intégrés dans une app Next.js sont concernés :
- Mesure d'audience : Google Analytics 4, ainsi que Matomo ou Plausible lorsqu'ils ne sont pas configurés pour bénéficier de l'exemption CNIL
- Publicité et marketing : Meta Pixel, LinkedIn Insight Tag, Google Ads, TikTok Pixel
- Expérience utilisateur : Hotjar, FullStory, LogRocket, Microsoft Clarity
- Support et chat : Intercom, Drift, HubSpot Chat
Les cookies strictement nécessaires au fonctionnement de l'application (session, authentification, panier) en sont exemptés. Attention : localStorage et sessionStorage relèvent du même régime que les cookies. Un traceur qui écrit dans le stockage local exige lui aussi un consentement.
Les trois obligations fondamentales
- Informer : indiquer quels cookies sont utilisés, pourquoi et par qui, avant tout dépôt.
- Recueillir un consentement valable : libre, spécifique, éclairé et univoque. Pas de case pré-cochée, pas de consentement implicite par défilement, et un bouton Refuser aussi simple à utiliser que le bouton Accepter.
- Respecter le choix : ne pas charger les scripts refusés, permettre le retrait à tout moment et redemander après un délai raisonnable. La CNIL recommande de conserver le choix (acceptation comme refus) pendant 6 mois, et la durée de vie des traceurs ne doit pas dépasser 13 mois (voir notre article sur la règle des 13 mois).
Les spécificités de Next.js
Server Components et Client Components
Avec l'App Router (Next.js 13 et suivants), la frontière entre Server et Client Components compte pour le consentement :
- Server Components : exécutés sur le serveur, ils n'ont accès ni à
document.cookieni àlocalStorage. Ils ne connaissent le consentement qu'à travers le cookie HTTP envoyé avec la requête. - Client Components (marqués
'use client') : exécutés dans le navigateur, ils peuvent réagir aux événements de consentement. - Middleware et Route Handlers : ils peuvent lire le cookie de consentement pour adapter le rendu ou les traitements côté serveur.
La navigation côté client
Une app Next.js navigue avec history.pushState, sans recharger la page. Sur un site classique, chaque chargement relance la bannière et rebloque les scripts de suivi. Dans une application monopage, les scripts injectés après la première page ne sont pas revérifiés si votre outil de consentement ne s'accroche pas à la navigation côté client.
Le problème du chargement des scripts
Le composant next/script propose plusieurs stratégies de chargement. Avec strategy="afterInteractive", le script se charge dès que la page devient interactive, avant tout clic sur la bannière. Sans mécanisme de consentement en amont, GA4 ou GTM se déclenche avant même l'affichage de la bannière. C'est la violation la plus courante dans les applications Next.js.
Deux façons de gérer le consentement
Option 1 : utiliser une CMP (recommandé)
Une plateforme de gestion du consentement comme FlowConsent prend en charge l'affichage de la bannière, la collecte du consentement, le blocage préalable des scripts tiers, les signaux Google Consent Mode v2 et la preuve du consentement. Les traductions et les évolutions réglementaires sont maintenues pour vous.
Option 2 : tout développer vous-même
Une bannière maison est faisable avec un composant React et un Context ou un store global, mais la liste des points à réussir est longue :
- bloquer chaque script non essentiel, y compris ceux injectés par GTM ou par des intégrations tierces
- envoyer les valeurs par défaut du Consent Mode v2 avant tout tag Google
- revérifier le consentement à chaque navigation côté client
- conserver la preuve du consentement (horodatage, version de la bannière, choix par catégorie) côté serveur
- renouveler le consentement et gérer son retrait
- suivre vous-même chaque évolution réglementaire (CNIL, CEPD)
Installer FlowConsent dans Next.js, étape par étape
La bannière FlowConsent est un script autonome : aucun paquet npm à installer côté navigateur. Le snippet exact de votre projet, avec votre URL de déploiement et votre code de licence, est généré dans Builder → Deployment → Integration, qui propose un onglet Next.js. La procédure complète figure dans le guide d'intégration Next.js et React SPA. Pour une app React sans Next.js (Vite, Create React App, React Router), suivez plutôt le guide d'installation React.
Étape 1 : ajouter le script
- App Router : dans
app/layout.tsx, ajoutez le script FlowConsent avec<Script strategy="beforeInteractive">. Cette stratégie le fait charger par Next.js avant l'hydratation, si bien que le blocage préalable est actif avant le moindre traceur. - Pages Router : dans
pages/_document.tsx, placez le<script>FlowConsent en premier dans<Head>.
Le snippet d'intégration contient aussi un stub Google Consent Mode en ligne qui enregistre les valeurs denied par défaut : gardez-le avant le loader. Ne chargez jamais FlowConsent depuis un composant React ou un useEffect : quand ce code s'exécute, les autres scripts ont déjà eu le temps de partir.
Étape 2 : activer le mode SPA
Dans le Builder, ouvrez l'onglet Settings, activez SPA Mode puis redéployez la bannière. FlowConsent intercepte alors history.pushState et history.replaceState, écoute popstate et rebloque les scripts de suivi non couverts à chaque navigation. Il émet aussi un événement flowconsent:navigation que vous pouvez écouter.
Étape 3 : confier les scripts de suivi à FlowConsent
Ne chargez pas Google Analytics, le Meta Pixel ou des outils équivalents avec next/script. Déclarez-les plutôt dans Builder → Services : la bannière ne les injecte qu'une fois la catégorie correspondante acceptée (analytics, marketing, préférences). Pour les contenus intégrés comme les iframes YouTube, un attribut data-service permet à la bannière de les conditionner.
Il en va de même pour @next/third-parties (Next.js 14 et suivants) : son composant GoogleAnalytics charge GA4 via next/script, hors du contrôle de votre outil de consentement. Si vous voulez que FlowConsent gère GA4, configurez le service dans le Builder plutôt que via ce paquet.
Google Consent Mode v2 dans Next.js
Google Consent Mode v2 est exigé depuis mars 2024 pour les annonceurs qui veulent continuer à utiliser les fonctions d'audience et de mesure de Google Ads auprès des utilisateurs de l'Espace économique européen. Il transmet quatre signaux à Google : analytics_storage, ad_storage, ad_user_data et ad_personalization.
FlowConsent l'implémente nativement, comme le détaille le guide Google Consent Mode :
- un stub en ligne enregistre des valeurs
deniedpar défaut pour les quatre signaux avant le chargement de tout tag Google wait_for_update: 500laisse à la bannière le temps d'appliquer le choix mémorisé d'un visiteur qui revient- dès que le visiteur choisit, la bannière envoie
gtag('consent', 'update', …) - après un refus, les tags Google n'envoient plus que des pings sans cookie (
gcs=G100), conformes au refus
Que vous passiez par GTM ou par gtag.js directement, la règle reste la même : les valeurs de consentement par défaut doivent être en place avant l'initialisation de tout tag Google. Pour la méthode complète, consultez notre guide d'implémentation de Google Consent Mode v2.
Lire le consentement côté serveur
Une partie des traitements démarre côté serveur : événements GA4 Measurement Protocol, synchronisation CRM, logique d'attribution dans un Route Handler, rendu personnalisé dans un Server Component. La bannière ne peut pas les bloquer : c'est à votre code de vérifier le consentement.
Le paquet @flowconsent/server-sdk lit le cookie first-party déposé par la bannière et renvoie une décision typée. Sans dépendance, il fonctionne en edge (Vercel, Cloudflare Workers) comme sur Node 18 et suivants, donc dans le Middleware, les Route Handlers et les Server Components. La décision est refusée par défaut lorsque le cookie est absent, illisible ou périmé, et decision.can('analytics') ou decision.can('google-analytics') indique si une catégorie ou un service est autorisé.
Réagir au consentement dans votre code React
Pour la logique placée dans des Client Components, FlowConsent émet un événement flowconsent:consent dont l'objet detail.preferences contient le choix du visiteur par catégorie. Un petit hook abonné à cet événement vous permet de :
- n'initialiser votre propre outil d'analytics que si
preferences.analyticsvaut true - charger via
next/dynamicles composants qui dépendent d'un traceur, uniquement après consentement - mettre à jour l'interface quand un visiteur change d'avis
Internationalisation
Next.js gère nativement le routage i18n, et votre bannière doit parler la même langue que la page. Dans FlowConsent, les textes se traduisent dans l'onglet Translations et la méthode de détection se règle dans Information. Le nombre de langues par bannière dépend de l'offre : 2 en Free, 5 en Pro, sur mesure en Enterprise.
Performance et Core Web Vitals
La gestion du consentement ne doit pas dégrader vos Core Web Vitals :
- réservez
strategy="beforeInteractive"au seul script de consentement, jamais aux traceurs bloqués - les scripts tiers bloqués ne consomment aucune bande passante avant consentement, ce qui allège le premier chargement
- comparez le score Lighthouse avant et après l'installation de la bannière
Les erreurs fréquentes
Charger GA4 ou GTM sans vérification du consentement. Un next/script en afterInteractive s'exécute avant tout clic sur la bannière. Laissez la CMP injecter les traceurs.
Charger la CMP trop tard. Injecter la bannière depuis un composant ou un useEffect signifie que les traceurs déjà présents dans la page sont partis avant son démarrage.
Oublier la navigation côté client. Sans mode SPA, les scripts ajoutés après la première page ne sont pas rebloqués sur les routes suivantes.
Ne pas bloquer le Meta Pixel. Il dépose des cookies publicitaires et doit dépendre de la catégorie marketing. Notre guide Meta Pixel et RGPD détaille ce point.
Cases pré-cochées ou consentement passif. Une bannière avec la catégorie Analytics pré-cochée invalide le consentement. Chaque catégorie non essentielle doit partir décochée.
Confondre état mémorisé et preuve. Une valeur en cookie ou en localStorage retient le choix dans un navigateur, mais ce n'est pas une preuve. La preuve est un enregistrement côté serveur avec horodatage, version de la bannière et choix par catégorie (voir que stocker comme preuve de consentement).
Ne jamais redemander. Le choix doit être renouvelé périodiquement, et la durée de vie des traceurs ne doit pas dépasser 13 mois.
Aucun moyen de retirer son consentement. Le visiteur doit pouvoir rouvrir ses préférences à tout moment, via un lien en pied de page ou un bouton flottant.
Tester votre implémentation
- Ouvrez le site en ligne dans une fenêtre de navigation privée : la bannière s'affiche dès la première page.
- Dans les onglets Network et Application des DevTools, vérifiez qu'aucune requête de suivi ne part et qu'aucun cookie non essentiel n'est déposé avant Accepter, y compris après plusieurs changements de route.
- Avec Google Tag Assistant, confirmez que le Consent Mode démarre en
deniedet ne passe engrantedqu'après acceptation. - Lancez l'assistant d'installation : il vérifie sur votre page en ligne que le stub et le loader sont présents, dans le bon ordre.
- Terminez par un scan avec refus depuis l'onglet Compliance : il charge vos pages dans un vrai navigateur, refuse le consentement et liste tout ce qui se déclenche encore (vérification de conformité).
Checklist de conformité cookies pour Next.js
- Auditer tous les scripts tiers (
next/script, GTM, imports directs,@next/third-parties). Notre méthode d'audit des cookies détaille la démarche. - Classer chaque cookie : strictement nécessaire, préférences, mesure d'audience, marketing.
- Ajouter le script de consentement dans
app/layout.tsxavecbeforeInteractive, ou en premier dans<Head>depages/_document.tsx. - Activer le mode SPA et redéployer la bannière.
- Déclarer les traceurs dans la CMP plutôt que de les charger avec
next/script. - Vérifier que les valeurs par défaut du Consent Mode v2 sont à
deniedavant tout tag Google. - Conditionner les traitements côté serveur à une décision de consentement lue dans la requête.
- Proposer un bouton Refuser aussi visible que le bouton Accepter, sans case pré-cochée.
- Conserver la preuve du consentement et le renouveler périodiquement.
- Prévoir un lien vers les préférences sur toutes les pages.
- Vérifier en navigation privée, puis par un scan avec refus.
Conclusion
La conformité RGPD d'une application Next.js tient en un principe : aucun script non essentiel ne s'exécute avant le consentement du visiteur, sur la première page comme à chaque navigation côté client. Next.js rend l'ajout de traceurs très simple, cette règle demande donc un mécanisme fiable : un script de consentement chargé avant l'hydratation, le mode SPA, des traceurs gérés par la CMP et un consentement vérifié aussi côté serveur.
Commencez par scanner votre site Next.js avec FlowConsent pour voir quels traceurs se chargent aujourd'hui sans consentement.