Comment ajouter un bandeau cookies à une application Next.js
Dans un projet Next.js avec l’App Router, rendez la balise avec next/script dans app/layout.tsx avec strategy="beforeInteractive", ce qui l’injecte dans le head avant tout code Next.js ; avec le Pages Router, le même composant va dans pages/_document.tsx. Marquez les balises Google et Meta avec type="text/plain" et data-cq-category dans le HTML rendu côté serveur, ou laissez la balise Google se charger en Consent Mode avec des signaux refusés par défaut.Étapes
Où charger la balise dans Next.js
Next.js documente la stratégie beforeInteractive de next/script pour les gestionnaires de consentement aux cookies : le script est injecté dans le HTML initial, dans le head, récupéré avant tout module Next.js et exécuté dans l’ordre où il a été placé, sans bloquer l’hydratation. Il doit vivre dans un layout racine (app/layout.tsx, ou app/[locale]/layout.tsx avec un routage internationalisé). Next.js transmet les attributs data-* à la balise script finale.
tsx// app/layout.tsximport Script from "next/script";export default function RootLayout({ children }: { children: React.ReactNode }) {return (<html lang="en"><body>{children}<Scriptsrc="https://cookiequiet.com/cq.js"strategy="beforeInteractive"data-site="YOUR_SITE_KEY"data-consent-mode="1"data-auto-block="1"/></body></html>);}
Les scripts dotés de cette stratégie sont injectés dans le head quel que soit l’endroit où vous placez le composant, et ils s’exécutent une fois par chargement de document : les navigations côté client ne les relancent pas, ce qui est le comportement voulu. Avec le Pages Router, rendez le même composant dans pages/_document.tsx. Vous pouvez lire la clé depuis process.env.NEXT_PUBLIC_COOKIEQUIET_SITE plutôt que de l’écrire dans le fichier.
Comment gérer les balises que votre application charge
Une application React diffère d’un CMS sur un point qui compte : les balises ajoutées après le chargement de la page ne figurent pas dans le HTML initial. Cookiequiet active les scripts marqués quand un choix enregistré est appliqué au chargement et à chaque fois que le visiteur fait un choix ; les balises marquées ont donc leur place dans le HTML rendu côté serveur.
Balises marquées dans le layout racine. Rendez-les comme des éléments script ordinaires dans le layout, pas via next/script :
tsx<scripttype="text/plain"data-cq-category="marketing"dangerouslySetInnerHTML={{ __html: "/* code de base du pixel Meta, inchangé, copié depuis Events Manager */" }}/>
Cookiequiet les transforme en vrais scripts une fois la catégorie accordée. Voir le guide Meta Pixel pour le code de base complet et la mise en garde sur le noscript.
Balises Google en Consent Mode. Si vous préférez que Google Analytics 4 ou Google Ads se charge avec des signaux refusés par défaut et envoie des pings sans cookies jusqu’au consentement, ajoutez le bloc de consentement par défaut de Google comme script inline beforeInteractive (un id est obligatoire pour les scripts inline), puis chargez la balise Google normalement, par exemple avec les composants GoogleAnalytics ou GoogleTagManager de @next/third-parties, qui utilisent la stratégie afterInteractive par défaut :
tsx<Script id="cq-consent-defaults" strategy="beforeInteractive">{"window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('consent', 'default', { ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied', analytics_storage: 'denied', functionality_storage: 'denied', personalization_storage: 'denied', security_storage: 'granted', wait_for_update: 500 });"}</Script>
Cookiequiet pousse les mêmes valeurs par défaut dès qu’il s’exécute et la commande consent update après chaque choix ; le bloc inline ne sert qu’à garantir l’ordre quand la balise Google est chargée par un autre mécanisme. Le guide Google Tag Manager couvre le conteneur et l’événement cq_consent.
Composants qui dépendent du consentement. Pour un lecteur YouTube, une carte ou un widget de chat rendu par React, lisez le choix depuis l’API publique dans un composant client :
tsx"use client";import { useEffect, useState } from "react";export function useConsent(category: string) {const [granted, setGranted] = useState(false);useEffect(() => {const api = (window as any).Cookiequiet;if (api === undefined) return;const current = api.get();setGranted(current ? current.c.includes(category) : false);return api.on((s: { c: string[] }) => setGranted(s.c.includes(category)));}, [category]);return granted;}
get() renvoie le choix enregistré avec ses catégories dans c, et on() renvoie une fonction de désabonnement. Ne rendez l’iframe que lorsque useConsent("marketing") vaut true ; sinon, affichez un espace réservé avec un bouton qui appelle window.Cookiequiet.showPreferences(). Pour les iframes ordinaires dans des composants serveur, data-cq-src à la place de src suffit.
Comment ajouter le lien Préférences de cookies
Rendez une ancre ordinaire dans le composant de pied de page ; un lien avec un dièse n’a pas besoin de next/link :
tsx<a href="#cq-preferences" data-cq-show-preferences>Cookie preferences</a>
Comment tester
- Lancez l’application (
next devconvient ; le bandeau récupère sa configuration depuis cookiequiet.com) et ouvrez-la dans une fenêtre de navigation privée. - Cliquez sur « Tout refuser ». Dans les outils de développement, les cookies doivent se limiter à
cq_consentet à vos propres cookies de session : pas de_ga, pas de_fbp. - Effacez les cookies, cliquez sur « Tout accepter », rechargez : les scripts marqués s’exécutent et la balise Google reçoit
analytics_storage: granted. - Naviguez entre les routes : le bandeau ne réapparaît pas et le choix reste appliqué.
- Consultez le registre des consentements dans le tableau de bord.
Ce qui est propre à Next.js
- Un layout racine, une balise. Ne rendez pas aussi le composant Script dans des layouts imbriqués ; Next.js n’autorise
beforeInteractiveque dans un layout racine, et une seconde copie serait ignorée ou dupliquée. - Content Security Policy. Avec une politique à base de nonce, passez le nonce au composant Script ; autorisez
https://cookiequiet.comdansscript-srcetconnect-src(la configuration, la géolocalisation et les enregistrements de consentement sont récupérés depuis cette origine). - Export statique et runtimes edge. Le bandeau est un script client sans dépendance serveur ;
output: "export"fonctionne. - Routage internationalisé. La langue du bandeau suit le navigateur du visiteur, pas la locale de la route ; chaque texte est modifiable par langue dans le tableau de bord.
Pour un site statique construit avec Next.js, l’article sur les bandeaux cookies pour sites statiques couvre l’hébergement sur Vercel ou Netlify.