> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanova.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Eventos personalizados

> Registra acciones concretas en tu sitio con scanova('track', ...): clics en botones, registros completados, reproducciones de vídeo y cualquier otra acción.

Los eventos personalizados te permiten registrar las acciones que importan a tu negocio, más allá de lo que captura el registro automático. Tú defines el nombre y los metadatos, y el SDK lo envía con la atribución del QR ya adjunta.

## Sintaxis

```javascript theme={null}
scanova('track', 'event_name', { key: 'value' });
```

* **`event_name`**: una cadena que describe la acción. Usa `snake_case`.
* **`metadata`**: un objeto opcional con los datos clave-valor que quieras. Máximo 10 KB.

Puedes llamar a `scanova('track', ...)` en cualquier momento después de `scanova('init', ...)`: desde escuchadores de eventos, callbacks asíncronos o cualquier otro contexto JavaScript.

<Note>
  En la petición, el SDK envía cada evento personalizado con `event_type` igual a `custom` y tu nombre en un campo `event_name` de nivel superior, no dentro de `metadata`. Esto difiere de llamar directamente a `POST /ct`, donde es `event_type` quien lleva el nombre semántico. Consulta la [referencia del modelo de eventos](/es/conversion-tracking/event-model).
</Note>

## Ejemplos

### Clic en un botón

Registrar cuándo alguien hace clic en una llamada a la acción concreta:

```javascript theme={null}
document.getElementById('start-trial-btn').addEventListener('click', () => {
  scanova('track', 'cta_click', {
    button_text: 'Start Free Trial',
    section: 'hero',
    plan: 'pro'
  });
});
```

### Registro completado

Envíalo cuando el envío de tu formulario de registro se confirme en el cliente:

```javascript theme={null}
scanova('track', 'signup_completed', {
  method: 'email',
  plan: 'free'
});
```

<Note>
  Para confirmaciones de compra o registro que ocurren **en el servidor**, usa los [eventos de servidor](/es/conversion-tracking/server/send-events). Son más fiables y las extensiones del navegador no pueden bloquearlos.
</Note>

### Interacción con vídeo

```javascript theme={null}
video.addEventListener('play', () => {
  scanova('track', 'video_play', { video_id: 'intro-tour' });
});

video.addEventListener('ended', () => {
  scanova('track', 'video_complete', { video_id: 'intro-tour' });
});
```

### Interacción con productos

```javascript theme={null}
document.querySelectorAll('.product-card').forEach(card => {
  card.addEventListener('click', () => {
    scanova('track', 'product_click', {
      product_id: card.dataset.productId,
      product_name: card.dataset.productName,
      position: card.dataset.position
    });
  });
});
```

### Interacción con pestañas o acordeones

```javascript theme={null}
document.querySelectorAll('.tab-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    scanova('track', 'tab_click', { tab_name: btn.textContent.trim() });
  });
});
```

### Clic en un enlace externo

```javascript theme={null}
document.querySelectorAll('a[href^="http"]').forEach(link => {
  link.addEventListener('click', () => {
    scanova('track', 'external_link_click', { destination: link.href });
  });
});
```

## Elegir entre eventos personalizados y registro automático

| Situación                                                                      | Usa                     |
| ------------------------------------------------------------------------------ | ----------------------- |
| Registrar todos los clics en enlaces y botones con la mínima configuración     | `autoClicks: true`      |
| Registrar un botón concreto con metadatos propios                              | `scanova('track', ...)` |
| Registrar todos los envíos de formulario                                       | `autoForms: true`       |
| Registrar un formulario concreto con contexto de campos (sin datos personales) | `scanova('track', ...)` |
| Cualquier interacción que el registro automático no cubra                      | `scanova('track', ...)` |

Puedes combinar ambos: `autoClicks: true` más eventos personalizados selectivos para las acciones de más valor.

## Event naming best practices

* Use `snake_case`: `cta_click`, not `ctaClick` or `CTAClick`
* Be specific enough to be self-explanatory in reports: `signup_completed` is better than `completed`
* Be consistent: pick one name and stick to it. Changing event names later fragments your historical data
* Do not include user-identifying information in the event name

## Metadata best practices

* Keep metadata flat where possible — deeply nested objects are harder to query
* Max object size: **10 KB**
* Max nesting depth: **5 levels**
* **Never include raw email addresses, phone numbers, or other PII** — use server events with `user_identifiers` for that
* Use stable keys — changing key names later fragments your data

```javascript theme={null}
// Good
scanova('track', 'download_click', {
  file_name: 'product-guide.pdf',
  section: 'resources'
});

// Avoid
scanova('track', 'download_click', {
  user_email: 'john@example.com',  // never include PII
  data: { nested: { too: { deep: { for: 'queries' } } } }
});
```

## When to use server events instead

Use [Server-Side Events](/es/conversion-tracking/server/send-events) rather than custom browser events when:

* The action happens on your server (payment confirmation, CRM creation, email verification)
* You need to pass a conversion value (order total, subscription price)
* You want to include hashed user identifiers for identity matching
* You need guaranteed delivery (server events cannot be blocked by ad blockers)
