Next.js
Componente Script, estrategia correcta y CSP.
Growth Lab es una etiqueta de terceros, así que en Next.js se instala como cualquier script externo: con el componente Script y la estrategia correcta.
App Router
Añádelo al layout raíz, dentro de <body>:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="es">
<body>
{children}
<Script
src="https://cdn.growthlab.ecomlabs.dev/sdk/v1/bootstrap.js"
data-site-id={process.env.NEXT_PUBLIC_GROWTHLAB_SITE_ID}
strategy="afterInteractive"
/>
</body>
</html>
);
}
NEXT_PUBLIC_GROWTHLAB_SITE_ID puede ir en el código directamente: el site id es público por diseño. Usar una variable solo sirve para tener entornos distintos (producción y staging) sin tocar el código.
Pages Router
// pages/_app.tsx
import Script from 'next/script';
export default function App({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<Script
src="https://cdn.growthlab.ecomlabs.dev/sdk/v1/bootstrap.js"
data-site-id={process.env.NEXT_PUBLIC_GROWTHLAB_SITE_ID}
strategy="afterInteractive"
/>
</>
);
}
Qué estrategia usar
| Estrategia | Resultado |
|---|---|
afterInteractive |
Recomendada. Carga en cuanto la página es interactiva. |
beforeInteractive |
Solo si aceptas bloquear la hidratación. Reduce el parpadeo al mínimo a costa de LCP. |
lazyOnload |
No la uses: el SDK cargaría después del primer render y la variante se vería aplicarse. |
Con afterInteractive el anti-flicker del SDK sigue funcionando: oculta solo los elementos que la variante va a modificar, nunca la página entera, y los revela pasados 1,5 segundos aunque la configuración no haya llegado.
Content Security Policy
Si tu aplicación envía una CSP, añade los orígenes de Growth Lab:
script-src 'self' https://cdn.growthlab.ecomlabs.dev;
connect-src 'self' https://events.growthlab.ecomlabs.dev https://sessions.growthlab.ecomlabs.dev;
Sin connect-src el navegador bloquea el envío de eventos en silencio y el panel mostrará la instalación como pending para siempre.
Navegación por cliente
El App Router navega sin recargar. El SDK detecta el cambio de ruta con history y MutationObserver y vuelve a resolver los experimentos en cada URL, así que no hace falta llamar a nada manualmente.
Un visitante no cambia de variante al navegar: la asignación es determinística sobre su identificador y la clave del experimento.
Registrar una conversión
'use client';
export function CheckoutButton({ total }: { total: number }) {
return (
<button
onClick={() => {
window.GrowthLab?.conversion('purchase', { revenue: total, currency: 'MXN' });
}}
>
Pagar
</button>
);
}
Consulta Conversiones y revenue para la deduplicación por identificador de pedido, que es lo que impide contar dos veces una compra si el usuario recarga la página de gracias.