Consentl cu Next.js
Plasați Consentl primul în <head> al layoutului rădăcină din App Router, încărcați alte etichete prin ConsentlScript sau folosiți _document din Pages Router.
- Scriptul de încărcare primul în <head>
- Da
Pentru blocarea prealabilă și valorile implicite Google Consent Mode, Consentl trebuie să ruleze
înaintea oricărei alte etichete, sincron (fără async, defer sau type="module"). În
Next.js, aceasta înseamnă o etichetă <script> simplă, nu next/script.
<script src="https://api.consentl.com/v1/loader.js?k=SITE_KEY&l=LANG"></script>
Stocați cheia site-ului într-o variabilă de mediu, cum ar fi NEXT_PUBLIC_CONSENTL_SITE_KEY. Cheia
este publică, așa că expunerea ei în browser nu este o problemă. Consent Mode necesită planul Pro
sau unul superior, iar blocarea automată a trackerelor cunoscute planul Business.
App Router (app/layout.tsx)
Testat cu Next.js 16.4 și React 19.
Ce fac React 19 și Next cu etichetele dumneavoastră
- React tratează fiecare
<script async src>ca pe o resursă și o mută în partea de sus a<head>, deasupra unui script sincron simplu, chiar dacă l-ați scris după Consentl. Și scripturile proprii ale Next vin primele. next/scriptcustrategy="afterInteractive"(șibeforeInteractive) scrie în pagină un<link rel="preload">pentru etichetă. Browserul descarcă eticheta în timp ce citește pagina, înainte de consimțământ. Consentl împiedică rularea ei, dar nu și această solicitare.
Datele de pagină transmise în flux de Next (self.__next_f) nu sunt reținute niciodată de
Consentl, indiferent ce menționează.
Configurarea recomandată
- Consentl ca
<script src>simplu, primul în<head>. React nu îl mută, apare o singură dată în pagină, iar vizitatorii primesc întotdeauna setările actuale ale bannerului (scriptul de încărcare este păstrat în cache 5 minute). - Fiecare altă etichetă care trebuie să aștepte consimțământul (Google Analytics, Meta, TikTok…)
prin mica componentă
ConsentlScriptde mai jos. Aceasta scrie eticheta catype="text/plain"cu categoria sa Consentl: React nu o mută, browserul nu o descarcă, iar Consentl o rulează o singură dată după consimțământ, în orice plan, inclusiv după navigarea pe client. - Sau administrați aceste etichete în Google Tag Manager (consultați Google Tag Manager).
Etichetele Google în modul avansat Consent Mode (planul Pro și cele superioare) sunt concepute
să se încarce înainte de consimțământ; dacă folosiți acest mod, încărcați-le cu next/script și
afterInteractive. strategy="lazyOnload" nu scrie niciun preload (Next 16.4) și este reținut până
la consimțământ, dar doar pentru etichetele recunoscute de blocarea automată (planul Business), așa
că preferați 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>
);
}
Cu o Content Security Policy, transmiteți nonce-ul către ConsentlScript (nonce={nonce});
Consentl îl păstrează atunci când rulează eticheta.
De ce să nu afișați scriptul de încărcare inline?
O versiune anterioară a acestei pagini prelua scriptul de încărcare pe server și îl afișa inline. În
App Router, aceasta trimite scriptul de încărcare de două ori la fiecare încărcare completă a
paginii, deoarece React copiază și conținutul unui <script> dintr-o Server Component în datele
paginii, iar paginile construite static păstrează copia preluată la build până când sunt
revalidate. Pe aceeași pagină de test:
| Configurare | HTML-ul paginii | Scriptul de încărcare Consentl |
|---|---|---|
| Etichetă script simplă (recomandat) | 2,2 KB gzip | 9,5 KB gzip, o solicitare, păstrat în cache 5 minute și partajat de toate paginile |
| Script de încărcare inline | 15,2 KB gzip, la fiecare încărcare completă a paginii | de două ori în pagină |
Eticheta simplă costă o solicitare către api.consentl.com înainte de afișarea paginii. Cu toate
celelalte etichete în ConsentlScript (sau în Google Tag Manager), în pagină nu există nimic pe
care browserul să îl poată descărca înainte să ruleze Consentl.
Nerecomandat: beforeInteractive
next/script cu strategy="beforeInteractive" este emis ca un preload plus o intrare inline într-o
coadă; Next inserează <script>-ul real înainte de hidratare, după scripturile inline și
asincrone deja prezente în HTML-ul generat pe server.
Pages Router (pages/_document.tsx)
În Pages Router, beforeInteractive este afișat cu defer după linkurile CSS. Folosiți în schimb
un script simplu:
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>
);
}
Navigarea pe client
Nu este nevoie de nimic suplimentar: runtime-ul rămâne încărcat, alegerea se află în cookie-ul
propriu consentl, iar linkurile „Setări cookie-uri” funcționează pe orice rută. Pentru propriul
cod, verificați consimțământul cu window.Consentl?.allowed("analytics") și evenimentul
consentl:change și porniți lucrurile o singură dată (consultați
Orice site).
Verificați că funcționează
Folosiți View Source (nu inspectorul de elemente) pe o pagină: după scripturile proprii ale Next
/_next/static/chunks/…, Consentl trebuie să vină înaintea oricărui alt script, nu există niciun
<link rel="preload"> pentru o etichetă de urmărire, iar etichetele dumneavoastră sunt
type="text/plain". Apoi deschideți site-ul într-o fereastră privată și verificați bannerul și fila
Network așa cum este descris în Orice site: nicio solicitare
către un tracker înainte să acceptați.
Limitări
- Etichetele
asyncscrise în layout sunt mutate de React deasupra Consentl; folosiți în schimbConsentlScript. next/scriptcuafterInteractiveface ca browserul să descarce eticheta înainte de consimțământ.- Cu
beforeInteractive, scripturile deja prezente în HTML-ul generat pe server rulează înaintea Consentl. - O schimbare de limbă pe client nu reîncarcă bannerul; noua limbă se aplică la următoarea încărcare completă a paginii.
- Dacă trimiteți o Content Security Policy, permiteți
https://api.consentl.com(consultați Orice site).
Ghiduri conexe
V-ați blocat? Scrieți-ne la support@consentl.com — răspundem în limba engleză, în zilele lucrătoare.