Consentl con Next.js
Inserisca Consentl per primo nel <head> del layout radice dell'App Router, carichi gli altri tag con un componente ConsentlScript o usi il _document del Pages Router.
- Loader per primo nel <head>
- Sì
Per il blocco preventivo e i valori predefiniti di Google Consent Mode, Consentl deve essere eseguito
prima di ogni altro tag, in modo sincrono (niente async, defer o type="module"). In
Next.js ciò significa un tag <script> semplice, non next/script.
<script src="https://api.consentl.com/v1/loader.js?k=SITE_KEY&l=LANG"></script>
Memorizzi la chiave del sito in una variabile d'ambiente come NEXT_PUBLIC_CONSENTL_SITE_KEY. La
chiave è pubblica, quindi esporla al browser non è un problema. Consent Mode richiede il piano Pro o
superiore, il blocco automatico dei tracker noti il piano Business.
App Router (app/layout.tsx)
Testato con Next.js 16.4 e React 19.
Che cosa fanno React 19 e Next ai suoi tag
- React tratta ogni
<script async src>come una risorsa e lo sposta in cima al<head>, sopra uno script sincrono semplice, anche se lo ha scritto dopo Consentl. Anche gli script di Next vengono per primi. next/scriptconstrategy="afterInteractive"(ebeforeInteractive) scrive nella pagina un<link rel="preload">per il tag. Il browser scarica il tag mentre legge la pagina, prima del consenso. Consentl ne impedisce l'esecuzione, ma non quella richiesta.
I dati di pagina trasmessi in streaming da Next (self.__next_f) non vengono mai trattenuti da
Consentl, qualunque cosa contengano.
Configurazione consigliata
- Consentl come
<script src>semplice, per primo nel<head>. React non lo sposta, è presente una sola volta nella pagina e i visitatori ricevono sempre le impostazioni attuali del banner (il loader viene memorizzato nella cache per 5 minuti). - Ogni altro tag che deve attendere il consenso (Google Analytics, Meta, TikTok…) tramite il piccolo
componente
ConsentlScriptqui sotto. Scrive il tag cometype="text/plain"con la sua categoria Consentl: React non lo sposta, il browser non lo scarica e Consentl lo esegue una volta dopo il consenso, in ogni piano, anche dopo la navigazione lato client. - Oppure gestisca questi tag in Google Tag Manager (veda Google Tag Manager).
I tag Google in modalità avanzata di Consent Mode (dal piano Pro in su) sono pensati per caricarsi
prima del consenso; se usa questa modalità, li carichi con next/script e afterInteractive.
strategy="lazyOnload" non scrive alcun preload (Next 16.4) e viene trattenuto fino al consenso, ma
solo per i tag che il blocco automatico riconosce (piano Business), quindi preferisca ConsentlScript.
// app/consentl-script.tsx — works in Server and Client Components
type Category = "preferences" | "analytics" | "marketing";
/** A tag that waits for consent: inert in the page, run by Consentl once the category is accepted. */
export function ConsentlScript({ category, src, nonce, children }: { category: Category; src?: string; nonce?: string; children?: string }) {
return src ? (
// eslint-disable-next-line @next/next/no-sync-scripts -- type="text/plain": never loaded by the browser itself
<script type="text/plain" data-consentl={category} src={src} nonce={nonce} />
) : (
<script type="text/plain" data-consentl={category} nonce={nonce} dangerouslySetInnerHTML={{ __html: children ?? "" }} />
);
}
// app/layout.tsx (or app/[locale]/layout.tsx)
import { ConsentlScript } from "./consentl-script";
const SITE_KEY = process.env.NEXT_PUBLIC_CONSENTL_SITE_KEY!;
export default function RootLayout({ children }: { children: React.ReactNode }) {
const lang = "en"; // e.g. (await params).locale
const loader = `https://api.consentl.com/v1/loader.js?k=${encodeURIComponent(SITE_KEY)}&l=${encodeURIComponent(lang)}`;
return (
<html lang={lang}>
<head>
{/* eslint-disable-next-line @next/next/no-sync-scripts -- must block: consent defaults + prior blocking */}
<script src={loader} />
</head>
<body>
{children}
<ConsentlScript category="analytics" src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX" />
<ConsentlScript category="analytics">
{`window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag('js',new Date());gtag('config','G-XXXXXXX');`}
</ConsentlScript>
<footer>
<a href="#consentl" data-consentl-open="">Cookie settings</a>
</footer>
</body>
</html>
);
}
Con una Content Security Policy, passi il suo nonce a ConsentlScript (nonce={nonce}); Consentl lo
mantiene quando esegue il tag.
Perché non stampare il loader inline?
Una versione precedente di questa pagina recuperava il loader sul server e lo stampava inline.
Nell'App Router ciò invia il loader due volte a ogni caricamento completo della pagina, perché
React copia anche il contenuto dello <script> di un Server Component nei dati di pagina, e le pagine
generate staticamente mantengono la copia recuperata al momento della build finché non vengono
riconvalidate. Sulla stessa pagina di test:
| Configurazione | HTML della pagina | Loader di Consentl |
|---|---|---|
| Tag script semplice (consigliato) | 2,2 KB compressi con gzip | 9,5 KB compressi con gzip, una richiesta, in cache per 5 minuti e condiviso da tutte le pagine |
| Loader inline | 15,2 KB compressi con gzip, a ogni caricamento completo della pagina | presente due volte nella pagina |
Il tag semplice costa una richiesta a api.consentl.com prima che la pagina venga visualizzata. Con
ogni altro tag in ConsentlScript (o in Google Tag Manager), nella pagina non c'è nulla che il browser
possa scaricare prima che Consentl venga eseguito.
Sconsigliato: beforeInteractive
next/script con strategy="beforeInteractive" viene emesso come un preload più una voce di coda
inline; Next inserisce lo <script> effettivo prima dell'idratazione, dopo gli script inline e
asincroni già presenti nell'HTML generato dal server.
Pages Router (pages/_document.tsx)
Nel Pages Router, beforeInteractive viene generato con defer dopo i link CSS. Usi invece uno
script semplice:
import { Head, Html, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head>
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
<script src={`https://api.consentl.com/v1/loader.js?k=${process.env.NEXT_PUBLIC_CONSENTL_SITE_KEY}&l=en`} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
Navigazione lato client
Non serve altro: il runtime resta caricato, la scelta risiede nel cookie di prima parte consentl e i
link «Impostazioni dei cookie» funzionano su qualsiasi route. Per il suo codice, verifichi il consenso
con window.Consentl?.allowed("analytics") e l'evento consentl:change, e avvii le cose una sola
volta (veda Qualsiasi sito web).
Verificare che funzioni
Usi View Source (non l'ispettore degli elementi) su una pagina: dopo gli script di Next
/_next/static/chunks/…, Consentl deve precedere ogni altro script, non c'è alcun
<link rel="preload"> per un tag di tracciamento e i suoi tag sono type="text/plain". Poi apra il
sito in una finestra privata e controlli il banner e la scheda Network come descritto in
Qualsiasi sito web: nessuna richiesta a un tracker prima che lei
accetti.
Limitazioni
- I tag
asyncscritti nel layout vengono spostati da React sopra Consentl; usi inveceConsentlScript. next/scriptconafterInteractivefa sì che il browser scarichi il tag prima del consenso.- Con
beforeInteractive, gli script già presenti nell'HTML generato dal server vengono eseguiti prima di Consentl. - Un cambio di lingua sul client non ricarica il banner; la nuova lingua si applica al successivo caricamento completo della pagina.
- Se invia una Content Security Policy, consenta
https://api.consentl.com(veda Qualsiasi sito web).
Guide correlate
Serve aiuto? Scriva a support@consentl.com: rispondiamo in inglese nei giorni lavorativi.