Сагласност за колачиће за Next.js, Gatsby и статичке сајтове: водич за интеграцију за програмере
Проблем сагласности на статичким сајтовима
Модерни JavaScript оквири као што су Next.js, Gatsby и Nuxt.js увели су промену парадигме у начину на који се веб странице граде и испоручују. Странице се претходно рендерују у време билдовања или на серверу, а затим се на клијенту хидрирају. Ово ствара јединствен изазов за сагласност за колачиће: банер за сагласност мора бити спреман пре него што се изврши било који скрипт за праћење, али сама страница може већ бити рендерована и кеширана на ивици (edge).
Традиционални CMP-ови су дизајнирани за серверски рендерован PHP или једноставне HTML странице где се документ учитава линеарно од врха ка дну. У свету оквира са подељеним кодом (code splitting), лењим учитавањем (lazy loading) и стриминг серверским рендеровањем, те претпоставке се руше. Да би се сагласност исправно имплементирала у овим окружењима, потребно је разумети рендеринг „pipeline“.
Зашто је тајминг важнији него што мислите
На стандардној HTML страници, постављање CMP скрипта у <head> пре осталих скриптова је једноставно. У Next.js App Router-у или Gatsby-ју, ситуација је сложенија:
- Прво стиже претходно рендерован HTML: Прегледач добија комплетан HTML са CDN-а или сервера. Ако су у тај HTML уграђени било који inline скриптови или тагови трећих страна, они могу да се изврше пре него што се учита ваша логика за сагласност.
- Празнина током хидрације: React хидрација се дешава након што је HTML већ исцртан. Ако је ваш компонент за сагласност React компонента, она не постоји у функционалном стању док се хидрација не заврши. Током те празнине, Google тагови или аналитички скриптови могу да се активирају без сагласности.
- Компликације са кеширањем на ивици: Ако користите ISR (Incremental Static Regeneration) или edge функције, HTML се кешира. Не можете динамички убризгавати логику која зависи од сагласности у кеширани HTML без механизма на клијенту.
Кључни принцип је следећи: сагласност мора бити успостављена на нивоу скрипта, а не на нивоу компоненте. React компонента која р��ндерује банер за сагласност стиже прекасно ако постане интерактивна тек након хидрације.
Интеграција са Next.js App Router-ом
Next.js 13+ са App Router-ом је увео нови начин руковања скриптовима. Ово је препоручени приступ за интеграцију сагласности:
Корак 1: Учитајте CMP скрипт у root layout-у
Користите Next.js Script компоненту са стратегијом beforeInteractive у вашем root layout.tsx. Ово говори Next.js-у да убризга скрипт у иницијални HTML документ, пре почетка хидрације:
Стратегија beforeInteractive је критична. Подразумевана стратегија afterInteractive учитава скриптове након хидрације, што је прекасно за сагласност. Са beforeInteractive, CMP скрипт је укључен у серверски рендерован HTML и извршава се док се страница учитава.
Корак 2: Подесите подраз��мевану сагласност пре Google тагова
Пре вашег Google Tag Manager или gtag.js исечка, укључите inline скрипт који поставља подразумевана стања сагласности. Ово осигурава да чак и ако се GTM учита пре него што се појави CMP банер, он поштује подразумевана одбијања:
Овај inline скрипт треба да буде постављен у <head> вашег root layout-а, пре CMP и GTM скриптова. У Next.js-у можете користити обичан <script> таг унутар <head> елемента вашег layout-а за ову сврху.
Корак 3: Руковање променама рута
Код навигације у single-page апликацији, CMP скрипт се учитава једном, али промене рута не покрећу пуно поновно учитавање странице. Ваш CMP мора да опстане током навигације на клијенту. FlexyConsent ово обрађује аутоматски — једном када се учита, остаје активан преко свих промена рута без поновне иницијализације.
Интеграција са Next.js Pages Router-ом
За пројекте који и даље користе Pages Router, приступ је сличан, али користи _document.tsx уместо root layout-а. Поставите CMP скрипт у <Head> компоненту ваше прилагођене Document класе. Стратегија beforeInteractive функционише на исти начин у Pages Router-у.
Кључна разлика је у томе што се _document.tsx рендерује само на серверу, тако да је сва логика сагласности овде загарантовано у иницијалном HTML payload-у.
Интеграција статичког сајта у Gatsby-ју
Gatsby генерише потпуно статички HTML у време билдовања. Нема серверског рендеровања у тренутку захтева, што неке аспекте поједностављује, а друге компликује:
- Користите
gatsby-ssr.tsxда убризгате CMP скрипт у<head>сваке странице.onRenderBodyAPI вам омогућава да додате скриптове у head који ће бити присутни у свакој статичкој HTML датотеци. - Избегавајте Gatsby додатке који лењо учитавају сагласност: Неки додатци из заједнице обавијају сагласност у React компоненте које се монтирају тек након хидрације. Ово ствара временски јаз описан раније.
- Поставите подразумевану сагласност inline: Користите
setHeadComponentsуgatsby-ssr.tsxда додате inline скрипт који поставља подразумевана стања сагласности. Овај скрипт ће бити у статичком HTML-у и извршиће се одмах.
Gatsby-јев приступ у време билдовања значи да ће свака HTML датотека на вашем CDN-у садржати скрипт за сагласност. Ово је заправо идеално — нема серверске логике која може да откаже ил�� да буде погрешно кеширана.
Разматрања за Nuxt.js
Nuxt.js (заснован на Vue) има своје обрасце. У Nuxt 3, користите useHead composable или nuxt.config.ts конфигурацију заглавља апликације да глобално додате CMP скрипт. Nuxt подржава опцију body: false (која поставља скриптове у head) и async атрибут за неблокирајуће учитавање.
За Nuxt-ов режим серверског рендеровања, важи исти принцип: CMP скрипт мора бити у иницијалном HTML одговору, а не динамички убризган од стране Vue компоненте након mount-а.
Избегавање померања layout-а
Банери за сагласност су озлоглашени по изазивању Cumulative Layout Shift (CLS), Core Web Vital метрике која утиче на SEO рангирање. Када се банер појави након што се страница већ рендеровала, он потискује садржај надоле или га неочекивано преклапа.
Стратегије за минимизовање CLS-а од банера за сагласност:
- Користите банер позици��ниран на дну: Банери на дну видљивог дела екрана не померају садржај странице. Ово је најпријатељскији приступ за CLS.
- Резервишите простор: Ако морате да користите банер на врху, резервишите вертикални простор у вашем CSS-у тако да layout странице рачуна на банер пре него што се он рендерује.
- Избегавајте модалне overlay-е при учитавању: Full-screen зидови за сагласност који се појављују након што се страница рендеровала изазивају перципирану нестабилност layout-а. Ако вам је зид неопходан, рендерујте га као део иницијалног стања странице.
- Учитајте CMP синхроно у head-у: Када се CMP учита као скрипт који блокира рендеровање у head-у, банер може да се појави као део иницијалног исцртавања, уместо да „искочи“ касније.
FlexyConsent-ов приступ независан од оквира
FlexyConsent је дизајниран да ради са било којим оквиром — или без икаквог оквира — тако што функционише на нивоу скрипта, а не на нивоу компоненте. Ево зашто је то важно:
- Један async script таг: Један
<script>таг у<head>је све што је потребно. Нема npm пакета за инсталацију, нема wrapper-а специфичних за оквир, нема конфигурације билда. - Подразумеване сагласности се активирају одмах: Скрипт поставља Consent Mode V2 подразумевана подешавања као своју прву акцију, пре било ког callback-а или манипулације DOM-ом. То значи да Google тагови поштују сагласност од прве милисекунде.
- Без зависности од DOM-а: Логика сагласности не чека да се React, Vue или Svelte хидрирају. Она ради независно о�� животног циклуса оквира.
- Ради са SSG, SSR, ISR и CSR: Пошто је у питању обичан скрипт, функционише идентично без обзира да ли је страница статички генерисана, серверски рендерована, инкрементално регенерисана или рендерована на клијенту.
Савет за програмере: Најједноставнији тест за исправну CMP интеграцију је да отворите Network таб у прегледачу, филтрирате по Google доменима и поново учитате страницу. Не би требало да се појави ниједан Google захтев пре него што се у конзоли појави команда за подразумевану сагласност. Ако се појави, ваш CMP се учитава прекасно.
FlexyConsent-ов бесплатни план подржава неограничен број прегледа страница и ради са Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix и обичним HTML-ом. Интеграција је иста у свима: један script таг, правилно постављен.