Zgoda na pliki cookie w Next.js, Gatsby i statycznych stronach: przewodnik integracji dla deweloperów

Problem zgody na statycznych stronach

Nowoczesne frameworki JavaScript, takie jak Next.js, Gatsby i Nuxt.js, wprowadziły zmianę paradygmatu w sposobie budowania i dostarczania stron internetowych. Strony są wstępnie renderowane w czasie budowania lub na serwerze, a następnie hydratowane po stronie klienta. Tworzy to unikalne wyzwanie dla zgody na pliki cookie: baner zgody musi być gotowy, zanim jakiekolwiek skrypty śledzące zostaną uruchomione, ale sama strona może być już wyrenderowana i zcache’owana na brzegu (edge).

Tradycyjne CMP były projektowane z myślą o stronach renderowanych po stronie serwera w PHP lub prostych stronach HTML, gdzie dokument ładuje się liniowo od góry do dołu. W świecie frameworków z dzieleniem kodu, leniwym ładowaniem i strumieniowym renderowaniem po stronie serwera te założenia przestają działać. Poprawne wdrożenie zgody w takich środowiskach wymaga zrozumienia całego potoku renderowania.

Dlaczego timing ma większe znaczenie, niż się wydaje

W standardowej stronie HTML umieszczenie skryptu CMP w <head> przed innymi skryptami jest proste. W Next.js App Router lub Gatsby sytuacja jest bardziej złożona:

Kluczowa zasada jest taka: zgoda musi być ustalana na poziomie skryptu, a nie komponentu. Komponent React renderujący baner zgody pojawia się zbyt późno, jeśli staje się interaktywny dopiero po hydratacji.

Integracja z Next.js App Router

Next.js 13+ z App Router wprowadził nowy sposób obsługi skryptów. Oto zalecane podejście do integracji zgody:

Krok 1: Załaduj skrypt CMP w głównym layoucie

Użyj komponentu Script Next.js ze strategią beforeInteractive w głównym pliku layout.tsx. Informuje to Next.js, aby wstrzyknąć skrypt do początkowego dokumentu HTML, zanim rozpocznie się hydratacja:

Strategia beforeInteractive jest krytyczna. Domyślna strategia afterInteractive ładuje skrypty po hydratacji, co jest zbyt późno dla zgody. Dzięki beforeInteractive skrypt CMP jest dołączony do HTML renderowanego po stronie serwera i wykonuje się podczas ładowania strony.

Krok 2: Ustaw domyślne stany zgody przed tagami Google

Przed snippetem Google Tag Manager lub gtag.js umieść skrypt inline, który ustawia domyślne stany zgody. Zapewnia to, że nawet jeśli GTM załaduje się, zanim pojawi się baner CMP, będzie respektował domyślne ustawienia odmowy:

Ten skrypt inline powinien być umieszczony w <head> głównego layoutu, przed skryptami CMP i GTM. W Next.js możesz w tym celu użyć zwykłego tagu <script> wewnątrz elementu <head> w layoucie.

Krok 3: Obsłuż zmiany tras

W nawigacji typu single-page application skrypt CMP ładuje się raz, ale zmiany tras nie wywołują pełnego przeładowania strony. Twoje CMP musi utrzymywać się pomiędzy nawigacjami po stronie klienta. FlexyConsent obsługuje to automatycznie — po załadowaniu pozostaje aktywny przy wszystkich zmianach tras bez ponownej inicjalizacji.

Integracja z Next.js Pages Router

Dla projektów wciąż używających Pages Router podejście jest podobne, ale wykorzystuje _document.tsx zamiast głównego layoutu. Umieść skrypt CMP w komponencie <Head> własnej klasy Document. Strategia beforeInteractive działa w Pages Router w ten sam sposób.

Kluczowa różnica polega na tym, że _document.tsx renderuje się wyłącznie po stronie serwera, więc każda logika zgody umieszczona tutaj jest gwarantowanie obecna w początkowym payloadzie HTML.

Integracja statycznych stron w Gatsby

Gatsby generuje w pełni statyczny HTML w czasie budowania. Nie ma renderowania po stronie serwera w momencie żądania, co upraszcza niektóre aspekty, ale komplikuje inne:

Podejście build-time w Gatsby oznacza, że każdy plik HTML na Twoim CDN będzie zawierał skrypt zgody. To w rzeczywistości idealne rozwiązanie — nie ma logiki serwerowej, która mogłaby zawieść lub zostać niepoprawnie zcache’owana.

Uwagi dotyczące Nuxt.js

Nuxt.js (oparty na Vue) ma własne wzorce. W Nuxt 3 użyj kompozycji useHead lub konfiguracji nagłówka aplikacji w nuxt.config.ts, aby dodać skrypt CMP globalnie. Nuxt obsługuje opcję body: false (umieszczającą skrypty w head) oraz atrybut async dla nieblokującego ładowania.

Dla trybu renderowania po stronie serwera w Nuxt obowiązuje ta sama zasada: skrypt CMP musi znajdować się w początkowej odpowiedzi HTML, a nie być dynamicznie wstrzykiwany przez komponent Vue po zamontowaniu.

Unikanie przesunięć layoutu

Banery zgody są notoryczne pod względem powodowania Cumulative Layout Shift (CLS), wskaźnika Core Web Vitals wpływającego na pozycje w SEO. Gdy baner pojawia się po wyrenderowaniu strony, spycha treść w dół lub niespodziewanie ją przykrywa.

Strategie minimalizowania CLS powodowanego przez banery zgody:

Framework-agnostyczne podejście FlexyConsent

FlexyConsent został zaprojektowany tak, aby działał z dowolnym frameworkiem — lub bez żadnego frameworka — poprzez operowanie na poziomie skryptu, a nie komponentu. Oto dlaczego ma to znaczenie:

Porada dla deweloperów: Najprostszy test poprawnej integracji CMP to otwarcie zakładki Network w przeglądarce, przefiltrowanie po domenach Google i przeładowanie strony. Żadne żądania do Google nie powinny zostać wysłane przed pojawieniem się w konsoli komendy ustawiającej domyślne wartości zgody. Jeśli się pojawiają, Twoje CMP ładuje się zbyt późno.

Darmowy plan FlexyConsent obsługuje nielimitowaną liczbę odsłon i działa z Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix i zwykłym HTML. Integracja jest taka sama we wszystkich przypadkach: jeden tag skryptu, poprawnie umieszczony.

← Blog Czytaj wszystko →