Contexto
Al crear un template open-source del portfolio, no podia hardcodear el ID de Google Analytics -- cada usuario tiene el suyo. Pero en produccion si queria tracking.
Lo que aprendi
El patron es simple: leer el GA ID de una variable de entorno y renderizar condicionalmente los scripts.
// En el template (version open-source)
const gaId = process.env.NEXT_PUBLIC_GA_ID;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="es">
<body>
{children}
{gaId && (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`}
strategy="afterInteractive"
/>
<Script id="gtag-init" strategy="afterInteractive">
{`window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag('js',new Date());gtag('config','${gaId}')`}
</Script>
</>
)}
</body>
</html>
);
}
// En produccion (hardcodeado, sin variable)
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"
strategy="afterInteractive"
/>
Por que este patron funciona
NEXT_PUBLIC_prefix: Next.js lo inyecta en el bundle del cliente, asi queprocess.env.NEXT_PUBLIC_GA_IDesta disponible en el JSX{gaId && <>...</>}: si la variable no existe, no renderiza nada -- zero scripts de tracking en dev- Template-friendly: el usuario solo necesita agregar
NEXT_PUBLIC_GA_ID=G-XXXXXen.env.localy listo afterInteractive: carga GA despues de la hidratacion, no bloquea el render inicial
Alternativa moderna
Si estas en Vercel, @vercel/analytics es mas simple y no requiere cookie banner:
import { Analytics } from "@vercel/analytics/next";
// En el body, sin condicional -- Vercel lo maneja
<Analytics />