Згода на cookie для Next.js, Gatsby і статычных сайтаў: кіраўніцтва па інтэграцыі для распрацоўшчыкаў
Праблема згоды на статычных сайтах
Сучасныя JavaScript-фрэймворкі, такія як Next.js, Gatsby і Nuxt.js, прынеслі змену парадыгмы ў спосаб стварэння і дастаўкі вэб-старонак. Старонкі папярэдне рэндэрацца падчас зборкі ці на серверы, а потым гідратуюцца на кліенце. Гэта стварае ўнікальную праблему для згоды на cookie: банер згоды павінен быць гатовы да выканання любых скрыптоў адсочвання, але сама старонка можа быць ужо адрэндэрана і закэшавана на мяжы сеткі.
Традыцыйныя CMP былі распрацаваны для серверна рэндэрымых PHP ці простых HTML-старонак, дзе дакумент загружаецца лінейна зверху ўніз. У свеце фрэймворкаў з падзелам кода, лянівай загрузкай і патокавым серверным рэндэрынгам гэтыя дапушчэнні парушаюцца. Каб правільна наладзіць згоду ў гэтых асяроддзях, трэба разумець канвеер рэндэрынгу.
Чаму таймінг важнейшы, чым вы думаеце
На стандартнай HTML-старонцы размяшчэнне скрыпта CMP у <head> перад іншымі скрыптамі простае. У Next.js App Router ці Gatsby сітуацыя складанейшая:
- Папярэдне адрэндэраны HTML прыходзіць першым: браўзер атрымлівае поўны HTML з CDN ці сервера. Калі ў гэты HTML убудаваны якія-небудзь інлайн-скрыпты ці староннія тэгі, яны могуць выканацца да загрузкі вашай логікі згоды.
- Разрыў гідратацыі: гідратацыя React адбываецца пасля адмалёўкі HTML. Калі ваш кампанент згоды з'яўляецца кампанентам React, ён не існуе ў функцыянальным стане да завяршэння гідратацыі. На працягу гэтага разрыву тэгі Google ці скрыпты аналітыкі могуць спрацаваць без згоды.
- Складанасці з кэшаваннем на мяжы: калі вы выкарыстоўваеце ISR (інкрэментальную статычную рэгенерацыю) ці межавыя функцыі, HTML кэшуецца. Вы не можаце дынамічна ўкараняць залежную ад згоды логіку ў кэшаваны HTML без кліенцкага механізму.
Асноўны прынцып такі: згода павінна ўсталёўвацца на ўзроўні скрыпта, а не на ўзроўні кампанента. Кампанент React, які рэндэрыць банер згоды, занадта спазняецца, калі становіцца інтэрактыўным толькі пасля гідратацыі.
Інтэграцыя з Next.js App Router
Next.js 13+ з App Router прынёс новы спосаб апрацоўкі скрыптоў. Вось рэкамендаваны падыход для інтэграцыі згоды:
Крок 1: загрузіце скрыпт CMP у каранёвым макеце
Выкарыстоўвайце кампанент Next.js Script са стратэгіяй beforeInteractive у вашым каранёвым layout.tsx. Гэта ўказвае Next.js укараніць скрыпт у зыходны HTML-дакумент да пачатку гідратацыі:
Стратэгія beforeInteractive крытычна важная. Стратэгія па змаўчанні afterInteractive загружае скрыпты пасля гідратацыі, што занадта позна для згоды. Пры beforeInteractive скрыпт CMP уключаецца ў серверна рэндэрымы HTML і выконваецца пры загрузцы старонкі.
Крок 2: усталюйце згоду па змаўчанні перад тэгамі Google
Перад вашым сніпетам Google Tag Manager ці gtag.js уключыце інлайн-скрыпт, які ўсталёўвае станы згоды па змаўчанні. Гэта гарантуе, што нават калі GTM загрузіцца да з'яўлення банера CMP, ён будзе паважаць налады адмовы па змаўчанні:
Гэты інлайн-скрыпт варта размясціць у <head> вашага каранёвага макета, перад скрыптамі CMP і GTM. У Next.js для гэтай мэты вы можаце выкарыстоўваць звычайны тэг <script> унутры элемента <head> вашага макета.
Крок 3: апрацоўвайце змены маршруту
У навігацыі аднастаронкавага дадатку скрыпт CMP загружаецца адзін раз, але змены маршруту не выклікаюць поўную перазагрузку старонкі. Ваша CMP павінна захоўвацца пры навігацыі на баку кліента. FlexyConsent апрацоўвае гэта аўтаматычна — пасля загрузкі яна застаецца актыўнай пры ўсіх зменах маршруту без паўторнай ініцыялізацыі.
Інтэграцыя з Next.js Pages Router
Для праектаў, якія ўсё яшчэ выкарыстоўваюць Pages Router, падыход аналагічны, але выкарыстоўвае _document.tsx замест каранёвага макета. Размясціце скрыпт CMP у кампаненце <Head> вашага карыстальніцкага класа Document. Стратэгія beforeInteractive працуе такім жа чынам у Pages Router.
Ключавое адрозненне ў тым, што _document.tsx рэндэрыцца толькі на серверы, таму любая логіка згоды тут гарантавана знаходзіцца ў зыходнай карыснай нагрузцы HTML.
Інтэграцыя са статычным сайтам Gatsby
Gatsby генеруе цалкам статычны HTML падчас зборкі. Сервернага рэндэрынгу падчас запыту няма, што спрашчае адны аспекты, але ўскладняе іншыя:
- Выкарыстоўвайце
gatsby-ssr.tsxдля ўкаранення скрыпта CMP у<head>кожнай старонкі. APIonRenderBodyдазваляе дадаваць скрыпты ў head, якія будуць прысутнічаць у кожным статычным HTML-файле. - Пазбягайце плагінаў Gatsby, якія лянíва загружаюць згоду: некаторыя плагіны супольнасці абгортваюць згоду ў кампаненты React, якія мантуюцца толькі пасля гідратацыі. Гэта стварае раней абмеркаваны разрыў таймінгу.
- Размяшчайце налады згоды па змаўчанні інлайн: выкарыстоўвайце
setHeadComponentsуgatsby-ssr.tsx, каб дадаць інлайн-скрыпт, які ўсталёўвае станы згоды па змаўчанні. Гэты скрыпт будзе ў статычным HTML і выканаецца неадкладна.
Падыход Gatsby на аснове часу зборкі азначае, што кожны HTML-файл на вашым CDN будзе ўключаць скрыпт згоды. Гэта на самай справе ідэальна — няма сервернай логікі, якая можа даць збой ці няправільна закэшавацца.
Меркаванні па Nuxt.js
Nuxt.js (на аснове Vue) мае свае ўласныя патэрны. У Nuxt 3 выкарыстоўвайце composable useHead ці канфігурацыю app head у nuxt.config.ts, каб дадаць скрыпт CMP глабальна. Nuxt падтрымлівае опцыю body: false (якая размяшчае скрыпты ў head) і атрыбут async для неблакіруючай загрузкі.
Для рэжыму сервернага рэндэрынгу Nuxt прымяняецца той жа прынцып: скрыпт CMP павінен быць у зыходным HTML-адказе, а не дынамічна ўкараняцца кампанентам Vue пасля мантавання.
Пазбяганне зруху макета
Банеры згоды сумна вядомыя тым, што выклікаюць Cumulative Layout Shift (CLS) — Core Web Vital, які ўплывае на SEO-рэйтынгі. Калі банер усплывае пасля рэндэрынгу старонкі, ён зрушвае кантэнт уніз ці нечакана накладваецца на яго.
Стратэгіі мінімізацыі CLS ад банераў згоды:
- Выкарыстоўвайце банер з ніжнім пазіцыянаваннем: банеры ўнізе вобласці прагляду не зрушваюць кантэнт старонкі. Гэта найбольш спрыяльны для CLS падыход.
- Зарэзервуйце месца: калі вы павінны выкарыстоўваць верхні банер, зарэзервуйце вертыкальную прастору ў вашым CSS, каб макет старонкі ўлічваў банер да яго рэндэрынгу.
- Пазбягайце мадальных накладанняў пры загрузцы: поўнаэкранныя сцены згоды, якія з'яўляюцца пасля рэндэрынгу старонкі, выклікаюць успрыманую нестабільнасць макета. Калі вам патрэбна сцяна, рэндэрыце яе як частку зыходнага стану старонкі.
- Загружайце CMP сінхронна ў head: калі CMP загружаецца як блакіруючы рэндэрынг скрыпт у head, банер можа з'явіцца як частка зыходнай адмалёўкі, а не ўсплываць пазней.
Фрэймворк-незалежны падыход FlexyConsent
FlexyConsent быў распрацаваны для працы з любым фрэймворкам — ці наогул без фрэймворка — за кошт працы на ўзроўні скрыпта, а не на ўзроўні кампанента. Вось чаму гэта важна:
- Адзін асінхронны тэг скрыпта: адзін тэг
<script>у<head>— гэта ўсё, што патрэбна. Няма npm-пакетаў для ўсталёўкі, няма фрэймворк-спецыфічных абгортак, няма канфігурацыі зборкі. - Налады згоды па змаўчанні спрацоўваюць неадкладна: скрыпт усталёўвае налады па змаўчанні Consent Mode V2 у якасці свайго першага дзеяння, да любога колбэку ці маніпуляцыі з DOM. Гэта азначае, што тэгі Google паважаюць згоду з самай першай мілісекунды.
- Няма залежнасці ад DOM: логіка згоды не чакае гідратацыі React, Vue ці Svelte. Яна працуе незалежна ад жыццёвага цыкла фрэймворка.
- Працуе з SSG, SSR, ISR і CSR: паколькі гэта звычайны скрыпт, ён функцыянуе ідэнтычна, незалежна ад таго, ці была старонка статычна згенеравана, серверна адрэндэрана, інкрэментальна рэгенеравана ці адрэндэрана на баку кліента.
Парада распрацоўшчыку: самы просты тэст правільнай інтэграцыі CMP — адкрыць укладку Network у браўзеры, адфільтраваць па дамёнах Google і перазагрузіць старонку. Ніякія запыты Google не павінны спрацоўваць да з'яўлення каманды згоды па змаўчанні ў кансолі. Калі яны спрацоўваюць, ваша CMP загружаецца занадта позна.
Бясплатны план FlexyConsent падтрымлівае неабмежаваныя прагляды старонак і працуе з Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix і звычайным HTML. Інтэграцыя аднолькавая для ўсіх іх: адзін тэг скрыпта, правільна размешчаны.