Los eventos personalizados son donde la analítica empieza a ser rentable, y una aplicación de Webflow Cloud puede activarlos desde el navegador y desde un Route Handler.
Las visitas a la página le dicen al equipo de marketing que alguien llegó. Pero no dicen si el visitante abrió la calculadora de precios o si recibió una confirmación del servidor.
Google Analytics 4 está diseñado en torno a eventos precisamente por esta razón, y una aplicación de Webflow Cloud es el lugar ideal para enviarlos, ya que es donde ocurre la interacción real: botones que llaman a una API y formularios que llegan a un Route Handler.
Dos capas de seguimiento de eventos personalizados se integran en una aplicación Next.js montada en un sitio de Webflow: eventos del lado del cliente activados con gtag desde una etiqueta cargada en el diseño raíz de la aplicación, y eventos del lado del servidor enviados desde un Route Handler a través del Measurement Protocol de GA4.
Ambas capas leen el mismo ID de medición, y un conjunto de variables de entorno en el entorno de Webflow Cloud contiene todo lo que necesitan.
¿Qué necesitas para realizar el seguimiento de eventos personalizados con Google Analytics en Webflow?
Debes preparar estos cinco elementos:
- Propiedad de Google Analytics 4: Créala con un flujo de datos web. El ID de medición que comienza con
G-alimenta tanto la etiqueta del lado del cliente como la ruta del lado del servidor. - Sitio de Webflow y entorno Cloud: Cualquier plan de sitio desde Starter en adelante, con un proyecto de Webflow Cloud y un entorno que ya realice compilaciones y despliegues.
- Next.js 15 o superior: La documentación de Webflow Cloud indica la versión 15 como requisito mínimo. Se asume el uso del App Router en todo momento; el patrón de Route Handler depende de él.
- npm como gestor de paquetes: Webflow Cloud solo admite npm, por lo que cualquier
pnpm addoyarn addque traigas de otro proyecto producirá una compilación que no se instalará. - Acceso a variables de entorno: Necesitas permisos de edición para las variables de entorno del proyecto. Almacena el secreto de la API de GA allí, nunca en el repositorio.
El plan de sitio gratuito Starter incluye Webflow Cloud, mientras que el montaje en un dominio personalizado requiere el plan Premium o superior. Reúne los cinco requisitos a continuación antes de la compilación básica. Todo lo demás es una propiedad de Google Analytics y una aplicación Next.js que ya se despliega en Webflow Cloud.
Con estos requisitos previos listos, puedes configurar las rutas de eventos del navegador y del servidor de las que depende la compilación.
6 pasos para realizar el seguimiento de eventos personalizados de Google Analytics en Webflow Cloud
Un seguimiento preciso de GA4 en Webflow Cloud requiere seis tareas conectadas: crear el secreto de la API, cargar la etiqueta del navegador, configurar las variables de entorno, añadir un asistente de cliente, crear un Route Handler y verificar ambas rutas de eventos.
Completa la configuración en este orden para que cada componente del navegador y del servidor tenga las credenciales y la información de enrutamiento que necesita.
1. Crea un secreto de API del Measurement Protocol en Google Analytics
Crea el secreto de la API en el panel de detalles del flujo web; solo aparece cuando lo creas. Abre tu propiedad de GA4, ve a Administrar, luego a Recopilación y modificación de datos, después a Flujos de datos y selecciona el flujo web de tu sitio.
Copia el ID de medición que aparece en la parte superior de los detalles del flujo. Más abajo en el mismo panel, abre Secretos de la API del Protocolo de medición y crea un nuevo secreto con un apodo que identifique el entorno, comowebflow-cloud-production
Copia el valor del secreto inmediatamente. Ten en cuenta que si regeneras un secreto, el anterior queda invalidado. Un controlador de rutas que siga usando el valor anterior puede seguir devolviendo un éxito mientras GA descarta silenciosamente cada carga útil.
Mantén un secreto por cada entorno de Webflow Cloud si utilizas entornos de prueba y de producción; de esta forma, si un secreto de prueba se filtra, puedes rotarlo sin afectar al flujo de producción. Guarda el ID de medición que empieza por y el secreto de la API en un gestor de contraseñas, nunca en el código fuente.G-
Ya tienes el ID de medición y el secreto de la API (solo para servidor) listos para la configuración.
2. Carga la etiqueta de Google Analytics en el diseño raíz de Next.js
Carga la etiqueta de GA en , por donde pasa cada página renderizada por la aplicación montada. Lee el ID de medición desde , que Next.js inserta en el paquete del navegador durante la compilación, y no renderices nada si no está presente para que el desarrollo local no falle al no encontrar la variable.app/layout.tsxNEXT_PUBLIC_GA_MEASUREMENT_ID
Conecta la etiqueta a través de de esta manera:next/script
// app/layout.tsx
import Script from 'next/script';
const GA_ID = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
{GA_ID && (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`}
strategy="afterInteractive"
/>
<Script id="ga-init" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', '${GA_ID}');
`}
</Script>
</>
)}
</body>
</html>
);
}
La estrategia carga la etiqueta después de la hidratación, lo que la mantiene fuera de la ruta crítica sin retrasarla hasta que el visitante haga scroll.afterInteractive
Después de un local con la variable configurada en , la pestaña Red de tu navegador debería mostrar una solicitud a con tu ID de medición en la cadena de consulta, y el informe en tiempo real de GA debería registrar una vista de página.npm run dev.env.localgoogletagmanager.com/gtag/js
3. Configura las variables de entorno en Webflow Cloud
Añade ambas credenciales al entorno de Webflow Cloud que despliega la aplicación. Next.js gestiona las dos credenciales de forma distinta: el ID de medición es público y está disponible durante la compilación, mientras que el secreto de la API permanece solo en el servidor para las solicitudes.
Manténlas fuera del repositorio. Webflow Cloud pone a disposición del proceso de compilación y de la aplicación desplegada en tiempo de ejecución tanto las variables secretas como las que no lo son, lo cual es importante aquí porque los valores de deben existir en el momento de la compilación para ser insertados. Por el contrario, el secreto de la API solo se lee en el momento de la solicitud dentro del controlador de rutas.NEXT_PUBLIC_
Webflow Cloud oculta las variables secretas de los registros de compilación.
Las tres variables y cómo se define el ámbito de cada una:
| Variable | Tipo | Valor | Dónde se lee |
|---|---|---|---|
NEXT_PUBLIC_GA_MEASUREMENT_ID |
No secreta | Tu ID de mediciónG- |
Paquete del navegador y controlador de rutas |
GA_API_SECRET |
Secreto | El secreto de la API del Protocolo de medición para el flujo web | Solo para el manejador de rutas |
NEXT_PUBLIC_BASE_PATH |
No secreta | La ruta de montaje de la aplicación, como /app |
Llamadas fetch del lado del cliente |
| Variable → Tipo → Valor → Dónde se lee |
|---|
NEXT_PUBLIC_GA_MEASUREMENT_ID |
| No secreta |
Tu ID de mediciónG- |
| Paquete del navegador y controlador de rutas |
GA_API_SECRET |
| Secreto |
| El secreto de la API del Protocolo de medición para el flujo web |
| Solo para el manejador de rutas |
NEXT_PUBLIC_BASE_PATH |
| No secreta |
La ruta de montaje de la aplicación, como /app |
| Llamadas fetch del lado del cliente |
La tercera variable existe porque Webflow Cloud inyecta basePath durante la compilación y no reescribe las llamadas fetch del lado del cliente. Una solicitud del navegador a /api/track desde una aplicación montada en /app se resuelve en la raíz del sitio de Webflow, por lo que nunca llega al manejador de rutas.
La documentación requiere que las peticiones del cliente incluyan la ruta base manualmente; pasarla a través de NEXT_PUBLIC_BASE_PATH es la forma más limpia de hacerlo. Usa la ruta de montaje exacta con una barra diagonal al principio y sin barra al final.
Guarda las variables y activa un nuevo despliegue, ya que un valor añadido después de la última compilación no estará en el paquete hasta que la aplicación se compile de nuevo.
Una vez finalizado el despliegue, confirma que la aplicación montada carga la etiqueta de GA con el ID de medición de producción.
4. Escribe un asistente de eventos del lado del cliente y dispara un evento personalizado
Crea un protector compartido que impida que los componentes llamen a gtag('event', ...) antes de que la etiqueta esté disponible. Una llamada directa a window.gtag dispersa por los componentes falla en cuanto una página se renderiza en el servidor o un bloqueador de contenido impide la carga de la etiqueta; el asistente te ofrece un único lugar para proteger ambas situaciones.
Ponlo en lib/ga.ts, declara el gtag global para que TypeScript deje de quejarse y mantén el tipo de parámetro lo suficientemente restringido para que un componente no pueda enviar accidentalmente un objeto que GA rechazaría.
Mantén el asistente breve:
// lib/ga.ts
type EventParams = Record<string, string | number | boolean>;
declare global {
interface Window {
gtag?: (...args: unknown[]) => void;
}
}
export function trackEvent(name: string, params: EventParams = {}): void {
if (typeof window === 'undefined' || typeof window.gtag !== 'function') {
return;
}
window.gtag('event', name, params);
}
Los nombres de los eventos son tu propio vocabulario, así que elígelos como si estuvieras nombrando una columna de base de datos: en minúsculas, con guiones bajos y lo suficientemente específicos para que un profesional de marketing que lea el informe de eventos de GA sepa qué ocurrió sin tener que abrir el código. pricing_sheet_download es mejor que click.
Los parámetros viajan con el evento. Registrar un parámetro como dimensión personalizada en la sección de administración es lo que lo promociona a los informes estándar; hasta que lo hagas, el parámetro solo será visible en DebugView y en tiempo real. Los componentes del cliente ahora pueden emitir eventos de GA4 protegidos y tipados llamando a trackEvent.
5. Envía eventos del lado del servidor desde un manejador de rutas con el Protocolo de medición
Crea un manejador de rutas en app/api/track/route.ts que acepte un ID de cliente y un evento del navegador y los reenvíe al Protocolo de medición con el secreto de la API adjunto. La referencia del Protocolo de medición de Google describe el punto final y la estructura requerida para la carga útil. Mantener el secreto de la API en el manejador de rutas lo protege de la exposición en el navegador.
Este manejador de rutas solicitado por el navegador registra una solicitud de seguimiento. Envía los resultados verificados desde el código del servidor que completa la acción o desde un manejador de webhooks una vez que el webhook haya sido autenticado.
El manejador de rutas lee el secreto de GA_API_SECRET, que no tiene el prefijo NEXT_PUBLIC_ y, por lo tanto, nunca entra en el paquete.
Advertencia de seguridad: El Route Handler que aparece a continuación es una demostración local no segura. Un endpoint de seguimiento en producción requiere autenticación y autorización, controles de limitación de tasa o abuso de cuotas, una lista blanca estricta de eventos y esquemas de parámetros, además de un límite en el tamaño de las solicitudes.
No lo implementes tal como se muestra. Añade todos esos controles antes de exponer un endpoint de seguimiento en un sitio activo; de lo contrario, cualquiera que pueda acceder al Route Handler podrá enviar tráfico a través de tus credenciales de GA.
El Route Handler de demostración realiza publicaciones en el Measurement Protocol:
// app/api/track/route.ts
import { NextResponse } from 'next/server';
const GA_ENDPOINT = 'https://www.google-analytics.com/mp/collect';
export async function POST(request: Request) {
const measurementId = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
const apiSecret = process.env.GA_API_SECRET;
if (!measurementId || !apiSecret) {
return NextResponse.json(
{ error: 'Analytics is not configured for this environment' },
{ status: 500 },
);
}
const body = await request.json().catch(() => null);
if (!body?.clientId || !body?.name) {
return NextResponse.json(
{ error: 'clientId and name are required' },
{ status: 400 },
);
}
const payload = {
client_id: String(body.clientId),
events: [
{
name: String(body.name),
params: {
...(body.params ?? {}),
// Without these two, Measurement Protocol events routinely
// fail to surface in Realtime and standard reports.
session_id: body.session_id,
engagement_time_msec: 100,
},
},
],
};
const url = `${GA_ENDPOINT}?measurement_id=${measurementId}&api_secret=${apiSecret}`;
const gaResponse = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
return NextResponse.json(
{ ok: gaResponse.ok },
{ status: gaResponse.ok ? 200 : 502 },
);
}
El client_id tiene como objetivo asociar el evento con el visitante identificado por la etiqueta del navegador. Una respuesta exitosa del Measurement Protocol confirma que la solicitud llegó a Google. GA aún puede descartar el evento, así que trata el gaResponse.ok únicamente como una verificación de entrega. La validación de la carga útil requiere una solicitud independiente al endpoint de depuración de Google.
El Route Handler se ciñe a las API de solicitud y respuesta estándar de la web y nunca toca node:fs, que no está disponible en la fecha de compatibilidad fijada de Webflow Cloud. Solo para pruebas locales, un curl POST con un cuerpo JSON que contenga clientId y name contra http://localhost:3000/api/track debería devolver ahora {"ok":true}.
6. Llama a ambas capas desde un componente cliente y verifica en Tiempo real
Dispara el evento del navegador y solicita el Route Handler de demostración desde una única interacción de prueba. Luego podrás compararlos lado a lado en GA durante las pruebas locales.
El componente solicita gtag para el client_id actual a través de gtag('get', ...), dispara trackEvent para el clic y luego publica en el Route Handler usando el NEXT_PUBLIC_BASE_PATH configurado. El uso en producción depende de la autenticación y autorización, controles de abuso de cuotas, una lista blanca de eventos y esquemas de parámetros, y un límite de tamaño de solicitud.
Aquí tienes el componente que llama a ambas capas:
// components/PricingDownload.tsx
'use client';
import { trackEvent } from '../lib/ga';
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? '';
const measurementId = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID ?? '';
function getClientId(): Promise<string | undefined> {
return new Promise((resolve) => {
if (typeof window.gtag !== 'function' || !measurementId) {
resolve(undefined);
return;
}
window.gtag('get', measurementId, 'client_id', (id: unknown) => {
resolve(typeof id === 'string' ? id : undefined);
});
});
}
export default function PricingDownload() {
async function handleClick() {
trackEvent('pricing_sheet_download', { file_name: 'pricing-2026.pdf' });
const clientId = await getClientId();
if (!clientId) return;
await fetch(`${basePath}/api/track`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId,
name: 'pricing_sheet_relay_requested',
params: { source: 'webflow_cloud' },
}),
keepalive: true,
});
}
return <button onClick={handleClick}>Download the pricing sheet</button>;
}
La bandera keepalive solicita al navegador que mantenga la solicitud activa si el clic también inicia una navegación. La finalización y la entrega de archivos requieren confirmación por separado. Coloca el componente en una página de prueba local, haz clic en el botón y observa el informe de Tiempo real de GA:
pricing_sheet_download se solicita desde la etiqueta del navegador, y pricing_sheet_relay_requested se solicita a través del Route Handler usando el client_id del navegador. Cuando ambos nombres aparecen bajo el recuento de eventos por nombre de evento, ambas solicitudes han llegado a GA.
¿Qué causa que los eventos personalizados de Google Analytics fallen en Webflow Cloud?
Los eventos personalizados suelen fallar porque la etiqueta implementada carece de su ID de medición, las solicitudes del cliente omiten la ruta de montaje, una directiva de tiempo de ejecución perimetral rompe la compilación o las cargas útiles del Measurement Protocol llegan a Google pero son descartadas.
Relaciona cada síntoma visible con su causa en Webflow Cloud y el cambio de configuración que lo resuelve.
La etiqueta se carga en el desarrollo local, pero la aplicación implementada no envía vistas de página
Causa: El paquete implementado se compiló sin NEXT_PUBLIC_GA_MEASUREMENT_ID, por lo que Next.js integró undefined, el GA_ID && protector en el diseño no renderizó nada y la etiqueta nunca llegó a la página. El desarrollo local lee el valor de .env.local, que no está implementado.
Solución: Confirma la configuración del entorno de Webflow Cloud y activa una nueva implementación. Luego abre la pestaña Red y busca una solicitud a googletagmanager.com/gtag/js. No intentes ver el código fuente aquí: la estrategia afterInteractive inyecta la etiqueta desde el cliente después de la hidratación, por lo que una aplicación configurada correctamente no tiene nada que encontrar en el HTML renderizado por el servidor.
Comprueba si un bloqueador de contenido del navegador está deteniendo la solicitud. La pestaña Red también debería mostrar una solicitud a googletagmanager.com/gtag/js con el ID de medición de producción en su cadena de consulta.
POST /api/track falla en el sitio activo pero tiene éxito en next dev
Causa: El componente omitió la ruta base configurada, por lo que la solicitud en vivo nunca llegó al Route Handler. Localmente, no hay ruta de montaje, por lo que la URL simple funciona y el error permanece oculto hasta la producción.
Solución: Aplica el ajuste a cada fetch del lado del cliente. No intentes leer desde en el código del cliente; la documentación actual de Webflow Cloud Next.js ya no muestra ese patrón, y el valor inyectado no está disponible de forma fiable para el navegador de esa manera.NEXT_PUBLIC_BASE_PATHbasePathnext.config
Vuelve a desplegar y confirma en la pestaña Red que la URL de la solicitud comienza ahora con la ruta de montaje. Para una aplicación montada en , la solicitud de seguimiento en vivo debe dirigirse a en lugar de a la raíz del sitio de Webflow./app/app/api/track
El despliegue en Webflow Cloud falla en el paso de compilación con un error de tiempo de ejecución edge
Causa: Webflow Cloud despliega Next.js a través del adaptador OpenNext Cloudflare, que acepta el destino de la plataforma Workers y rechaza el destino de tiempo de ejecución de Next.js . La palabra "edge" tiene dos significados en la documentación de Webflow. Webflow Cloud se ejecuta en Cloudflare Workers, una plataforma edge, y la documentación describe el despliegue "usando el tiempo de ejecución Edge" en ese sentido de plataforma.edge
La misma página de "trae tu propia aplicación" sigue indicando a los lectores que añadan a las rutas de la API. Esa directiva selecciona un destino de tiempo de ejecución de Next.js diferente que el adaptador rechaza. Un desarrollador que siga esa línea al pie de la letra enviará una compilación rota.export const runtime = 'edge'
Solución: Elimina la directiva de todas las rutas, diseños y páginas. El controlador de ruta del Protocolo de medición se ejecuta en Workers porque el adaptador gestiona el destino de la plataforma.
Si también necesitas lógica a nivel de solicitud, como adjuntar un indicador de consentimiento antes de que se disparen los eventos, ponla en ; el tiempo de ejecución de Workers solo admite middleware de tiempo de ejecución Edge, así que no cambies el nombre del archivo a , que se ejecuta en el tiempo de ejecución de Node y no puede ejecutarse en Webflow Cloud.middleware.tsproxy.ts
El controlador de ruta devuelve ok: true, pero no aparecen eventos del lado del servidor en Google Analytics
Causa: El Protocolo de medición devuelve un estado de éxito para cualquier solicitud HTTP bien formada, incluidos los payloads con un nombre de evento no válido o un que no coincide con ninguna sesión del navegador. Por lo tanto, la comprobación de de tu controlador de ruta solo confirma la entrega a Google y nada más.client_idgaResponse.ok
La variante más común en Webflow Cloud es que resolvió porque la etiqueta aún no se había cargado en la aplicación montada, el componente devolvió un resultado prematuro y el controlador de ruta nunca fue llamado. Una prueba de exitosa solo verifica la solicitud de prueba. Confirma el estado de un clic real en el botón.getClientIdundefinedcurl
Solución: El punto final de validación de Google acepta el mismo payload en y devuelve una matriz que nombra el campo infractor. En el navegador, confirma que la etiqueta se ha cargado antes de que el botón sea interactivo, o recurre a disparar solo el evento del lado del cliente cuando resuelve vacío.https://www.google-analytics.com/debug/mp/collectvalidationMessagesgetClientId
Qué puedes construir a continuación con Google Analytics y Webflow
Para una configuración de análisis más amplia en tu sitio y aplicación Cloud, Google Analytics proporciona la ruta de integración principal, mientras que Webflow Analyze ofrece datos nativos de comportamiento en el sitio dentro de la plataforma. Utiliza el controlador de ruta para obtener resultados verificados y autenticados del lado del servidor.
El mismo patrón de controlador de ruta se extiende a cualquier resultado del lado del servidor que valga la pena medir: un webhook de Stripe que confirma un pago u otro resultado verificado del lado del servidor. Aplica autenticación y autorización, controles contra el abuso de cuotas, una lista de permitidos de eventos estricta, un esquema de parámetros y un límite de tamaño de solicitud antes de enviar eventos.
Preguntas frecuentes
¿Deberían las páginas renderizadas por el Diseñador usar la misma propiedad de Google Analytics?
Si Google Analytics ya está configurado en las páginas renderizadas por el Diseñador, utiliza el mismo ID de medición para la aplicación Next.js. Un visitante que pase de una página de marketing a la aplicación montada puede seguir siendo un solo usuario en GA, mientras que la etiqueta del navegador suministra el utilizado para asociar los eventos del controlador de ruta con ese visitante.client_id
¿Puedo usar Google Tag Manager en lugar de gtag en la aplicación de Webflow Cloud?
Puedes cargar el contenedor de GTM a través en el mismo espacio de diseño y enviar a en lugar de llamar a . El controlador de ruta no se ve afectado porque el Protocolo de medición se comunica directamente con GA y nunca pasa por el contenedor. Mantén la búsqueda de porque las etiquetas cargadas por GTM siguen exponiéndolo al componente.next/scriptdataLayergtagclient_id
¿Los eventos de local next dev contaminarán mis datos de producción de Google Analytics?
Lo harán si tu contiene el ID de medición de producción. Aísla los eventos locales en una propiedad de GA4 separada o en un segundo flujo de datos con credenciales distintas. Verifica los eventos del lado del servidor en un entorno de pruebas desplegado en lugar de confiar en los resultados locales, y mantén un ID de medición separado para las pruebas para que el tráfico de desarrollo nunca llegue a la propiedad de producción..env.local
¿Las cuotas cambian lo que puedo rastrear en un plan más económico?
Sí. Algunos límites de Webflow Cloud varían según el plan del sitio, mientras que otros son iguales para todos; así que consulta la página de límites en lugar de dar por sentado a qué tipo te enfrentas. Antes de aumentar el volumen de eventos o añadir solicitudes del lado del servidor, revisa los límites actuales de tu sitio específico. El tope relevante depende del historial del plan de ese sitio, no solo de su configuración actual.





