Cookie-samtykke for Next.js, Gatsby og statiske nettsteder: En utviklerguide til integrasjon
Problemet med samtykke på statiske sider
Moderne JavaScript-rammeverk som Next.js, Gatsby og Nuxt.js har introdusert et paradigmeskifte i hvordan nettsider bygges og leveres. Sider forhåndsrendres ved bygging eller på serveren, og blir deretter hydrert i klienten. Dette skaper en unik utfordring for cookie-samtykke: samtykkebanneret må være klart før noen sporingsskript kjører, men selve siden kan allerede være rendret og mellomlagret i edge-nettverket.
Tradisjonelle CMP-er ble laget for serverrendret PHP eller enkle HTML-sider der dokumentet lastes lineært fra topp til bunn. I en rammeverden med code splitting, lazy loading og streaming server-side rendering bryter disse forutsetningene sammen. For å få samtykke riktig i disse miljøene må du forstå renderingspipen.
Hvorfor timing betyr mer enn du tror
I en standard HTML-side er det enkelt å plassere et CMP-skript i <head> før andre skript. I Next.js App Router eller Gatsby er situasjonen mer kompleks:
- Forhåndsrendret HTML kommer først: Nettleseren mottar komplett HTML fra CDN eller server. Hvis det finnes inline-skript eller tredjepartstags innebygd i den HTML-en, kan de kjøre før samtykkeloggikken din lastes.
- Hydreringsgap: React-hydrering skjer etter at HTML-en er tegnet. Hvis samtykkekomponenten din er en React-komponent, eksisterer den ikke i en funksjonell tilstand før hydreringen er fullført. I dette gapet kan Google-tags eller analyse-skript fyre uten samtykke.
- Komplikasjoner med edge-cache: Hvis du bruker ISR (Incremental Static Regeneration) eller edge-funksjoner, blir HTML-en mellomlagret. Du kan ikke dynamisk injisere samtykkeavhengig logikk i cachet HTML uten en klient-side-mekanisme.
Kjerneprinsippet er dette: samtykke må etableres på skriptnivå, ikke komponentnivå. En React-komponent som rendrer et samtykkebanner er for sen hvis den først blir interaktiv etter hydrering.
Integrasjon med Next.js App Router
Next.js 13+ med App Router introduserte en ny måte å håndtere skript på. Her er anbefalt tilnærming for samtykkeintegrasjon:
Trinn 1: Last CMP-skriptet i rot-layouten
Bruk Next.js Script-komponenten med strategien beforeInteractive i din rot-layout.tsx. Dette forteller Next.js å injisere skriptet i det første HTML-dokumentet, før hydreringen starter:
Strategien beforeInteractive er kritisk. Standardstrategien afterInteractive laster skript etter hydrering, noe som er for sent for samtykke. Med beforeInteractive blir CMP-skriptet inkludert i serverrendret HTML og kjører mens siden lastes.
Trinn 2: Sett standardsamtykke før Google-tags
Før Google Tag Manager- eller gtag.js-snippet ditt, inkluder et inline-skript som setter standardsamtykkestatus. Dette sikrer at selv om GTM lastes før CMP-banneret vises, respekterer det avviste standardverdier:
Dette inline-skriptet bør plasseres i <head> i rot-layouten din, før CMP- og GTM-skriptene. I Next.js kan du bruke en vanlig <script>-tagg inne i <head>-elementet i layouten for dette formålet.
Trinn 3: Håndter ruteendringer
Ved single-page application-navigasjon lastes CMP-skriptet én gang, men ruteendringer utløser ikke en full sideinnlasting. CMP-en din må persistere på tvers av klient-side-navigasjoner. FlexyConsent håndterer dette automatisk — når det først er lastet, forblir det aktivt på alle ruteendringer uten re-initialisering.
Integrasjon med Next.js Pages Router
For prosjekter som fortsatt bruker Pages Router, er tilnærmingen lik, men bruker _document.tsx i stedet for rot-layouten. Plasser CMP-skriptet i <Head>-komponenten i din tilpassede Document-klasse. Strategien beforeInteractive fungerer på samme måte i Pages Router.
Den viktigste forskjellen er at _document.tsx bare rendres på serveren, så all samtykkeloggikk her er garantert å være med i den første HTML-payloaden.
Gatsby-integrasjon for statiske sider
Gatsby genererer fullstendig statisk HTML ved bygging. Det er ingen server-side rendering ved forespørselstidspunktet, noe som forenkler enkelte aspekter, men kompliserer andre:
- Bruk
gatsby-ssr.tsxfor å injisere CMP-skriptet i<head>på hver side. API-etonRenderBodylar deg legge til skript i head som vil være til stede i hver statiske HTML-fil. - Unngå Gatsby-plugins som lazy-loader samtykke: Noen community-plugins wrapper samtykke i React-komponenter som først monteres etter hydrering. Dette skaper timing-gapet som ble diskutert tidligere.
- Plasser samtykkestandarder inline: Bruk
setHeadComponentsigatsby-ssr.tsxfor å legge til et inline-skript som setter standardsamtykkestatus. Dette skriptet vil være i den statiske HTML-en og kjøre umiddelbart.
Gatsbys byggtidstilnærming betyr at hver HTML-fil på CDN-et ditt vil inkludere samtykkeskriptet. Dette er faktisk ideelt — det finnes ingen serverlogikk som kan feile eller cache feil.
Vurderinger for Nuxt.js
Nuxt.js (Vue-basert) har sine egne mønstre. I Nuxt 3 bruker du useHead-composable eller nuxt.config.ts sin app head-konfigurasjon for å legge til CMP-skriptet globalt. Nuxt støtter et body: false-alternativ (som plasserer skript i head) og et async-attributt for ikke-blokkerende lasting.
For Nuxt sin server-side rendering-modus gjelder samme prinsipp: CMP-skriptet må være med i den første HTML-responsen, ikke dynamisk injisert av en Vue-komponent etter mount.
Unngå layout-skift
Samtykkebannere er beryktet for å forårsake Cumulative Layout Shift (CLS), en Core Web Vital som påvirker SEO-rangeringer. Når et banner dukker opp etter at siden er rendret, skyver det innhold ned eller legger seg uventet over det.
Strategier for å minimere CLS fra samtykkebannere:
- Bruk et banner nederst: Bannere nederst i viewporten flytter ikke sideinnhold. Dette er den mest CLS-vennlige tilnærmingen.
- Reserver plass: Hvis du må bruke et banner øverst, reserver vertikal plass i CSS-en slik at sidelayouten tar høyde for banneret før det rendres.
- Unngå modal-overlays ved innlasting: Fullskjerms samtykkevegger som vises etter at siden er rendret skaper opplevd layout-ustabilitet. Hvis du trenger en vegg, rendrer du den som en del av den første sidetilstanden.
- Last CMP-en synkront i head: Når CMP-en lastes som et render-blokkerende skript i head, kan banneret vises som en del av første paint i stedet for å dukke opp senere.
FlexyConsents rammeverksagnostiske tilnærming
FlexyConsent er laget for å fungere med alle rammeverk — eller uten rammeverk — ved å operere på skriptnivå i stedet for komponentnivå. Dette er viktig av flere grunner:
- Én asynkron skript-tagg: Én
<script>-tagg i<head>er alt som trengs. Ingen npm-pakker å installere, ingen rammeverksspesifikke wrappers, ingen byggkonfigurasjon. - Samtykkestandarder fyres umiddelbart: Skriptet setter Consent Mode V2-standarder som sin første handling, før noen callback eller DOM-manipulasjon. Dette betyr at Google-tags respekterer samtykke fra aller første millisekund.
- Ingen DOM-avhengighet: Samtykkeloggikken venter ikke på at React, Vue eller Svelte skal hydrere. Den opererer uavhengig av rammeverkslivssyklusen.
- Fungerer med SSG, SSR, ISR og CSR: Fordi det er et vanlig skript, fungerer det identisk uansett om siden er statisk generert, serverrendret, inkrementelt regenerert eller klient-side-rendret.
Utviklertips: Den enkleste testen for korrekt CMP-integrasjon er å åpne nettleserens Network-fane, filtrere på Google-domener og laste siden på nytt. Ingen Google-forespørsler skal fyres før kommandoen for samtykkestandard vises i konsollen. Hvis de gjør det, lastes CMP-en din for sent.
FlexyConsents gratisplan støtter ubegrenset antall sidevisninger og fungerer med Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix og ren HTML. Integrasjonen er den samme på tvers av alle: én skript-tagg, riktig plassert.