# GTM: dataLayer avanzado, triggers, variables y server-side

## Arquitectura de GTM

GTM funciona con tres conceptos fundamentales que se relacionan en orden:

```
Trigger (cuándo) ──► Tag (qué hacer) ──► Variable (con qué datos)
```

Un **trigger** detecta un evento en la página. Una **tag** se dispara cuando
el trigger se activa. Las **variables** proveen los datos que la tag necesita.

### Workspace y versiones

- El **workspace** es el entorno de trabajo en progreso (sin publicar).
- Cada **versión** es un snapshot publicado con nombre, fecha y descripción.
- Crear una versión antes de cada cambio relevante: `Versión > Nueva versión`.
- En producción usar siempre un contenedor publicado, nunca el workspace.
- Ambientes (`Environments`): crear uno por stage (dev, staging, prod) para
  probar sin afectar el contenedor de producción.

## Variables

### Variables built-in

GTM incluye variables activables sin configuración extra:

| Variable | Valor |
|----------|-------|
| `Page URL` | URL completa de la página actual |
| `Page Path` | Solo el path: `/productos/sku-001` |
| `Click URL` | URL del elemento clickeado |
| `Click Text` | Texto del elemento clickeado |
| `Click Classes` | Clases CSS del elemento clickeado |
| `Form URL` | URL de acción del formulario enviado |
| `Scroll Depth Threshold` | Porcentaje de scroll alcanzado |

Activarlas en: Variables > Built-In Variables > Configure.

### Variables personalizadas de dataLayer

Para leer valores del objeto `ecommerce` del dataLayer:

- Tipo: **Data Layer Variable**
- Nombre de variable: `ecommerce.transaction_id` (notación de punto)
- Versión del dataLayer: **Version 2** (siempre para GA4)
- Nombre de la variable en GTM: `{{DL - ecommerce.transaction_id}}`

Convención de naming para variables de dataLayer: `{{DL - ruta.al.valor}}`.

### Variables de JavaScript personalizado

Para lógica más compleja (formateo, cálculos, lectura de cookies):

```javascript
// Variable: {{JS - GA Client ID}}
function() {
  var cookie = document.cookie.match(/_ga=([^;]+)/);
  if (!cookie) return undefined;
  var parts = cookie[1].split('.');
  return parts.slice(-2).join('.');
}
```

```javascript
// Variable: {{JS - FBC Cookie}}
function() {
  var match = document.cookie.match(/_fbc=([^;]+)/);
  return match ? match[1] : undefined;
}
```

## Triggers

### Tipos de trigger más usados

**All Pages (Pageview)**: Se dispara en cada carga de página. Base para GA4
Configuration tag. Siempre presente en todo contenedor.

**Custom Event**: Se dispara cuando `dataLayer.push({ event: 'nombre' })`
coincide con el nombre configurado. Usar para eventos de e-commerce.

```
Trigger > Custom Event
Event name: purchase
(Para capturar todos los eventos custom: usar regex .*)
```

**Click - All Elements**: Se dispara en cualquier click. Útil para tracking
de botones sin código JavaScript adicional.

**Form Submission**: Se dispara al enviar un formulario. Requiere activar
`Form` en Built-In Variables.

**History Change**: Esencial en Single-Page Apps (React, Angular, Vue) donde
la URL cambia sin recarga completa. Usar en lugar de Pageview para SPAs.

### Race conditions en SPAs

En aplicaciones de una sola página, el trigger `History Change` puede
dispararse antes de que el componente actualice el dataLayer. Solución:

```javascript
// Después del cambio de ruta, esperar al siguiente tick
router.afterEach((to) => {
  setTimeout(() => {
    dataLayer.push({ ecommerce: null });
    dataLayer.push({
      event: 'page_view',
      page_path: to.path,
      page_title: to.meta.title,
    });
  }, 0);
});
```

Alternativa con GTM: usar la variable `{{JS - Page Path}}` con `Page Path`
built-in, que siempre refleja la URL actual al momento del trigger.

## Tags

### GA4 Configuration Tag

Una sola por contenedor. Se dispara en All Pages.

- Tag type: **Google Analytics: GA4 Configuration**
- Measurement ID: `{{Constant - GA4 Measurement ID}}`
- Fields to set: `debug_mode` = `true` (solo en workspace de desarrollo)

### GA4 Event Tag

Una por tipo de evento e-commerce.

- Tag type: **Google Analytics: GA4 Event**
- Configuration Tag: seleccionar la Configuration Tag creada arriba
- Event Name: `{{DL - event}}` (lee el nombre del evento del dataLayer)
- Trigger: Custom Event con el nombre del evento

Para pasar el objeto `ecommerce` completo:
- Event Parameters: agregar `items` = `{{DL - ecommerce.items}}`
- Marcar **Send Ecommerce data**: activado, Source: Data Layer

### Conversion Linker

Tag obligatoria para Enhanced Conversions y cross-device tracking:

- Tag type: **Conversion Linker**
- Trigger: All Pages
- Colocar antes que cualquier tag de conversión de Google Ads

## GTM Server-Side en Cloud Run

El servidor GTM actúa como proxy entre el browser y las plataformas de ads,
permitiendo enviar datos first-party sin depender de las restricciones del browser.

### Setup mínimo

1. Crear un contenedor de tipo **Server** en GTM.
2. Desplegar la imagen `gcr.io/cloud-tagging-10302018/gts-preview:latest`
   en Cloud Run (mínimo 1 instancia siempre activa para latencia).
3. Configurar el **Server Container URL** en el contenedor browser de GTM.
4. Verificar que las requests van a `tu-dominio.com/g/collect` en vez de
   directamente a `google-analytics.com`.

### Client templates

El servidor GTM necesita un **Client** que reciba las requests del browser:

- **GA4 Client**: recibe requests del tag GA4 del browser.
- **Meta Pixel Client**: recibe requests del Meta Pixel del browser.

Cada client parsea el payload y lo pone disponible para los tags del servidor.

### Tag templates del servidor

Los tags del servidor envían datos a las plataformas finales:

- **GA4 (server-side)**: usa `measurement_id` y `api_secret` como variables.
- **Meta CAPI**: usa `pixel_id` y `access_token` como variables de entorno.

Ventaja clave: las variables con credenciales viven en el servidor,
nunca expuestas en el browser.

## Modo de depuración

### Tag Assistant

1. En GTM workspace > Preview: abre Tag Assistant en una nueva pestaña.
2. Ingresar la URL del sitio y activar la sesión de debug.
3. El panel izquierdo muestra todos los eventos del dataLayer en orden.
4. Hacer click en un evento para ver qué tags se dispararon y cuáles no.

### GA4 DebugView

En GA4 > Admin > DebugView: muestra eventos en tiempo real del browser
con `debug_mode: true`. Indispensable para validar eventos e-commerce.

### Regla de validación antes de pasar a producción

1. Verificar en Tag Assistant que cada evento tiene `ecommerce: null` previo.
2. Confirmar en GA4 DebugView que el evento `purchase` llega con el
   `transaction_id` correcto.
3. Publicar una versión con nombre descriptivo: `"feat: purchase event GA4"`.
4. Monitorear GA4 > Realtime durante las primeras 24 horas post-deploy.

## Buenas prácticas de naming

| Tipo | Convención | Ejemplo |
|------|-----------|---------|
| Variable dataLayer | `{{DL - ruta.del.valor}}` | `{{DL - ecommerce.transaction_id}}` |
| Variable JavaScript | `{{JS - Descripción}}` | `{{JS - GA Client ID}}` |
| Constante | `{{Constant - Nombre}}` | `{{Constant - GA4 Measurement ID}}` |
| Trigger custom event | Igual que el nombre del evento | `purchase`, `view_item` |
| Tag GA4 | `GA4 - Nombre del evento` | `GA4 - Purchase`, `GA4 - Config` |
| Tag conversión | `Ads - Nombre conversión` | `Ads - Purchase Conversion` |
