Consentimento de cookies en Next.js, Gatsby e sitios estáticos: guía de integración para desenvolvedores
O problema do consentimento en sitios estáticos
Os frameworks modernos de JavaScript como Next.js, Gatsby e Nuxt.js introduciron un cambio de paradigma na forma en que se constrúen e entregan as páxinas web. As páxinas pré-renderízanse no momento da construción ou no servidor e despois son hidratadas no cliente. Isto crea un desafío único para o consentimento de cookies: a barra de consentimento debe estar lista antes de que se execute calquera script de seguimento, pero a propia páxina pode estar xa renderizada e almacenada en caché no edge.
Os CMP tradicionais foron deseñados para páxinas PHP renderizadas no servidor ou para HTML sinxelo, onde o documento se carga de forma lineal de arriba abaixo. Nun mundo de frameworks con code splitting, carga diferida e streaming server-side rendering, esas suposicións deixan de ser válidas. Conseguir un consentimento correcto nestes contornos require comprender o pipeline de renderizado.
Por que o tempo importa máis do que pensas
Nunha páxina HTML estándar, colocar un script de CMP no <head> antes doutros scripts é algo directo. En Next.js App Router ou Gatsby, a situación é máis complexa:
- O HTML pré-renderizado chega primeiro: O navegador recibe HTML completo desde o CDN ou o servidor. Se nese HTML hai scripts inline ou etiquetas de terceiros incrustadas, poden executarse antes de que cargue a túa lóxica de consentimento.
- Gap de hidratación: A hidratación de React prodúcese despois de que o HTML se pinte. Se o teu compoñente de consentimento é un compoñente de React, non existe en estado funcional ata que a hidratación remata. Durante este intervalo, as etiquetas de Google ou scripts de analítica poderían dispararse sen consentimento.
- Complicacións co caché no edge: Se utilizas ISR (Incremental Static Regeneration) ou funcións edge, o HTML almacénase en caché. Non podes inxectar de forma dinámica lóxica dependente do consentimento nun HTML en caché sen un mecanismo no cliente.
O principio fundamental é este: o consentimento debe establecerse a nivel de script, non a nivel de compoñente. Un compoñente de React que renderiza unha barra de consentimento chega demasiado tarde se só se volve interactivo despois da hidratación.
Integración con Next.js App Router
Next.js 13+ co App Router introduciu unha nova forma de xestionar scripts. Esta é a aproximación recomendada para integrar o consentimento:
Paso 1: Cargar o script do CMP no layout raíz
Usa o compoñente Script de Next.js coa estratexia beforeInteractive no teu layout.tsx raíz. Isto indícalle a Next.js que inxecte o script no documento HTML inicial, antes de que comece a hidratación:
A estratexia beforeInteractive é crítica. A estratexia por defecto, afterInteractive, carga os scripts despois da hidratación, o que é demasiado tarde para o consentimento. Con beforeInteractive, o script do CMP inclúese no HTML renderizado no servidor e execútase mentres a páxina se carga.
Paso 2: Definir o consentimento por defecto antes das etiquetas de Google
Antes do teu snippet de Google Tag Manager ou gtag.js, inclúe un script inline que estableza os estados de consentimento por defecto. Isto garante que, mesmo se GTM se carga antes de que apareza a barra do CMP, respecte os valores denegados por defecto:
Este script inline debe colocarse no <head> do teu layout raíz, antes dos scripts do CMP e de GTM. En Next.js, podes usar unha etiqueta <script> normal dentro do elemento <head> do teu layout para este fin.
Paso 3: Xestionar os cambios de ruta
Na navegación dunha single-page application, o script do CMP cárgase unha vez, pero os cambios de ruta non desencadean unha recarga completa da páxina. O teu CMP debe persistir nas navegacións no cliente. FlexyConsent xestiona isto automaticamente: unha vez cargado, permanece activo en todos os cambios de ruta sen necesidade de reinicialización.
Integración con Next.js Pages Router
Para proxectos que aínda usan o Pages Router, a aproximación é similar pero emprega _document.tsx no canto do layout raíz. Coloca o script do CMP no compoñente <Head> da túa clase Document personalizada. A estratexia beforeInteractive funciona do mesmo xeito no Pages Router.
A diferenza clave é que _document.tsx só se renderiza no servidor, polo que calquera lóxica de consentimento aquí está garantida no payload HTML inicial.
Integración con sitios estáticos en Gatsby
Gatsby xera HTML totalmente estático no momento da construción. Non hai renderizado no servidor no momento da petición, o que simplifica algúns aspectos pero complica outros:
- Usa
gatsby-ssr.tsxpara inxectar o script do CMP no<head>de cada páxina. A APIonRenderBodypermíteche engadir scripts ao head que estarán presentes en cada ficheiro HTML estático. - Evita plugins de Gatsby que cargan o consentimento de forma diferida: Algúns plugins da comunidade envolven o consentimento en compoñentes de React que só se montan despois da hidratación. Isto crea o gap de tempo comentado antes.
- Coloca os valores por defecto de consentimento como inline: Usa
setHeadComponentsengatsby-ssr.tsxpara engadir un script inline que defina os estados de consentimento por defecto. Este script estará no HTML estático e executarase de inmediato.
O enfoque de construción de Gatsby implica que cada ficheiro HTML no teu CDN incluirá o script de consentimento. Isto é en realidade ideal: non hai lóxica no servidor que poida fallar ou almacenarse en caché de forma incorrecta.
Consideracións para Nuxt.js
Nuxt.js (baseado en Vue) ten os seus propios patróns. En Nuxt 3, usa o composable useHead ou a configuración app head en nuxt.config.ts para engadir o script do CMP de forma global. Nuxt admite unha opción body: false (que coloca os scripts no head) e o atributo async para unha carga non bloqueante.
Para o modo de server-side rendering de Nuxt, aplícase o mesmo principio: o script do CMP debe estar na resposta HTML inicial, non ser inxectado de forma dinámica por un compoñente de Vue despois do mount.
Como evitar o layout shift
As barras de consentimento son famosas por causar Cumulative Layout Shift (CLS), un Core Web Vital que afecta ás clasificacións de SEO. Cando unha barra aparece despois de que a páxina se renderiza, empurra o contido cara abaixo ou superpóñese de forma inesperada.
Estratexias para minimizar o CLS provocado polas barras de consentimento:
- Usar unha barra situada na parte inferior: As barras na parte inferior da ventá de visualización non desprazan o contido da páxina. É a opción máis respectuosa co CLS.
- Reservar espazo: Se tes que usar unha barra na parte superior, reserva o espazo vertical no teu CSS para que o layout da páxina teña en conta a barra antes de que se renderice.
- Evitar modais superpostos ao cargar: Os muros de consentimento a pantalla completa que aparecen despois de que a páxina se renderizou provocan unha sensación de inestabilidade no layout. Se precisas un muro, renderízao como parte do estado inicial da páxina.
- Cargar o CMP de forma síncrona no head: Cando o CMP se carga como script bloqueante de renderizado no head, a barra pode aparecer como parte do primeiro pintado en lugar de aparecer máis tarde.
O enfoque agnóstico a frameworks de FlexyConsent
FlexyConsent foi deseñado para funcionar con calquera framework —ou sen ningún— operando a nivel de script en lugar de a nivel de compoñente. Isto é importante por varios motivos:
- Un único script tag async: Só é necesario un
<script>no<head>. Sen paquetes de npm que instalar, sen wrappers específicos de framework, sen configuración de build. - Os valores por defecto de consentimento execútanse de inmediato: O script establece os valores por defecto de Consent Mode V2 como primeira acción, antes de calquera callback ou manipulación do DOM. Isto significa que as etiquetas de Google respectan o consentimento desde o primeiro milisegundo.
- Sen dependencia do DOM: A lóxica de consentimento non espera a que React, Vue ou Svelte se hidraten. Opera de forma independente do ciclo de vida do framework.
- Funciona con SSG, SSR, ISR e CSR: Ao ser un script plano, funciona de forma idéntica tanto se a páxina foi xerada de forma estática, renderizada no servidor, rexenerada de forma incremental ou renderizada no cliente.
Consello para desenvolvedores: A proba máis sinxela para verificar unha integración correcta do CMP é abrir a lapela Network do navegador, filtrar por dominios de Google e recargar a páxina. Non debería haber peticións a Google antes de que apareza no consola o comando de valores por defecto de consentimento. Se as hai, o teu CMP está cargando demasiado tarde.
O plan gratuíto de FlexyConsent admite páxinas vistas ilimitadas e funciona con Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix e HTML plano. A integración é a mesma en todos eles: unha etiqueta de script, colocada correctamente.