Guía de integración de Argumentum
Todo lo necesario para integrar Argumentum en cualquier aplicación web — HTML plano, React, Vue, Angular o lo que venga — y sacarle valor desde el primer día: analítica de uso (páginas, clicks, funnels, paths, adopción, clientes/tenants) y guías in-app (tooltips, lightboxes, banners, checklists).
1. Instalación (5 minutos)
1.1 Crea la aplicación en el panel
Panel → Apps e integración → escribe el nombre de tu web → Crear app. Copia la app key (sk_…). Cada web/bundle que instrumentes lleva su propia key; todas comparten el mismo servidor y la misma base analítica.
1.2 Pega el snippet en tu web
En el <head> (o al final del <body>) de todas las páginas:
<script src="https://TU-ARGUMENTUM/agent.js"
data-key="sk_xxxxxxxxx"
data-endpoint="https://TU-ARGUMENTUM"></script>
data-endpointes opcional si el agente se sirve del mismo origen que la API. En despliegues con dominio propio, será tu dominio.- El agente es first-party: sírvelo desde tu dominio (o el del servidor) y no será bloqueado por ad-blockers ni pierde cookies de terceros.
- Sin más configuración ya está auto-capturando: páginas vistas y clicks (con selector resuelto), y auto-registrando páginas nuevas.
1.3 (Recomendado) Identifica a tus usuarios
Sin identificar, todo funciona con visitantes anónimos. Con identify activas: segmentación de guías por rol/plan/lo-que-quieras, la vista de Clientes (tenants) y filtros por usuario.
// en el momento en que sabes quién es el usuario (tras login, bootstrap, etc.)
argumentum('identify', {
visitorId: user.id, // estable y único por usuario
tenantId: user.orgId, // opcional: id de su empresa/cliente (SaaS multitenant)
visitor: { rol: user.role, idioma: user.locale }, // metadata de usuario
tenant: { plan: user.plan, sector: user.sector } // metadata de la empresa
});
// eventos de negocio con propiedades
argumentum('track', 'proyecto_creado', { plantilla: 'marketing' });
argumentum('track', 'checkout_completado', { importe: 49.9, moneda: 'EUR' });
Reglas de la metadata:
- Los campos que envíes quedan disponibles para segmentar (audiencias de guías, filtros del panel, estimates de segmentos).
- Nunca envíes PII libre (email, DNI, teléfono) como valor de campo: usa ids o categorías. El esquema recomendado:
rol,idioma(visitor) ynombre,plan,sector,pais,fecha_alta(tenant). visitorIddebe ser estable entre sesiones (el id de tu base de datos). Si no lo envías, el agente genera uno anónimo enlocalStorage.
2. Etiquetado preciso (Pages y Features)
El tagging conecta el tráfico capturado con conceptos de producto. Es la base de clickmaps, funnels, adopción y paths. Se gestiona en Panel → Páginas y features (o por API, sección 5).
2.1 Pages: qué cuenta como página
Una page agrupa URLs bajo un nombre. Reglas posibles (una page puede tener varias; se evalúan en OR, basta con que una encaje):
| Regla | Significado | Ejemplo | Encaja con |
|---|---|---|---|
exacta:/facturacion | URL idéntica (path+query) | /facturacion | solo esa |
prefijo:/app/fact/ | empiece por | /app/fact/ | /app/fact/2026, /app/fact/lista |
contiene:checkout | contenga en cualquier posición | checkout | /es/checkout/ok, /checkout |
regex:^/fact/[0-9]+$ | expresión regular | ^/fact/[0-9]+$ | /fact/123, no /fact/abc |
Una cadena sin prefijo ("checkout") equivale a contiene:checkout.
Buenas prácticas
- General después de específica: el matcher devuelve la primera page cuyas reglas encajen (puedes reordenarlas). Crea primero las pages específicas (
exacta:/app/fact/nueva→ «Nueva factura») y al final la genérica (prefijo:/app/fact/→ «Facturación»). - Normaliza ids variables con regex: para
/fact/1234usaregex:^/fact/[0-9]+$en vez decontiene:/fact/, que también capturaría/facturacion. - Excluye lo que no es producto: en Apps → Ámbito de tracking puedes excluir rutas (
prefijo:/panel-admin,regex:^/legal/). Lo excluido no genera datos. - Auto-registro: si llega tráfico de una ruta sin página, el servidor crea una page automática (
exacta:ruta). Revísalas en Páginas y features y renómbralas o fusiónalas añadiendo su regla a otra page.
2.2 Features: qué elemento es cada cosa
Una feature es un elemento concreto de la UI (botón, enlace, pestaña, toggle). Se define por selector CSS. La adopción, los clickmaps y los funnels cuentan clicks que caen dentro del elemento seleccionado.
Cómo escribir un selector que no se rompa (por orden de preferencia):
- Data-atributo propio — el más estable:
[data-sv='crear-proyecto'],[data-testid='exportar']. Si controlas el frontend, añadedata-*semánticos a los elementos importantes. Es la práctica que hace el tagging inmune a rediseños. #idsi es único y estable:#btn-exportar.[aria-label='…']para botones icónicos accesibles.- Ruta CSS corta como último recurso:
nav > button:nth-of-type(2). Frágil ante cualquier cambio de maquetación: úsala solo como respaldo.
Cada feature admite respaldos (selector.respaldo): lista ordenada de selectores alternativos. El agente usa el primero que encuentre en el DOM.
Verifica siempre tu selector antes de guardarlo, en la consola del navegador sobre la página real:
document.querySelectorAll("[data-sv='crear-proyecto']").length // debe ser exactamente 1
(1 = perfecto; >1 = coge el primero visible; 0 = no existe en esa página).
Captura con el modo diseñador: en Páginas y features, escribe la URL de tu web y pulsa 🎯: se abre tu web con el agente en modo selección; al hacer click en un elemento, el selector se rellena en el formulario. También puedes abrir directamente https://tu-web?argumentum_designer=feature.
Detalles por framework (el agente es vanilla JS y funciona igual en todos):
- Vue: los atributos
scoped(data-v-3f2a1b) cambian entre builds — taggea condata-*propios, no con los generados. - React: los
classNamegenerados (CSS modules, styled-components tipoButton-sc-1x2y3z) cambian en cada build — usadata-testidoid. - Angular: evita
_ngcontent-xxx/_nghost-xxx(cambian por compilación);data-*propios oaria-label. - Elementos dentro de Shadow DOM: el autocapture no los ve; usa
argumentum('track', …)para ellos.
2.3 Track events (lo que no es un click)
Para hitos de negocio que no son interacciones de UI (compras, importaciones, validaciones), usa argumentum('track', nombre, props). Aparecen en la vista Adopción/top como «eventos» y son pasos válidos de funnels y paths (tipo: "track").
3. Guías in-app
3.1 Crear y publicar
Panel → Guías → Nueva guía:
- Pasos: cada paso tiene tipo (tooltip / lightbox / banner), título, cuerpo, texto del botón y ancla (selector CSS, opcional). Con «🎯 Elegir ancla» el modo diseñador captura el selector sobre tu web real.
- Paso sin ancla: tooltip centrado (o banner si es de tipo banner).
- Ancla
obligatorio: true: si el elemento no está en la página, el paso no se muestra (nunca molestar sin contexto).
- Audiencia: reglas sobre la metadata (
tenant.plan es Enterprise,visitor.rol es admin), páginas donde aparece (reglas de URL, vacío = todas) y frecuencia (siempre/una_vez/sesión). - Programa: fechas de visibilidad. No hay distinción de entornos: solo lo
publicadallega al bundle (para probar en otra web, crea otra app con su propia key). - Publicar: regenera el bundle
GET /v1/config; los usuarios lo reciben al recargar o navegar. Guardar como borrador o staged para pruebas.
El throttle global de la app (Ajustes: máx. guías por usuario y ventana, por defecto 2/semana) evita saturar: si dos guías compiten por el mismo usuario, gana la de menor prioridad.
Tipos: tooltip (anclado con flecha), lightbox (centrado con fondo), banner (barra superior) y checklist (widget fijo con progreso; cada tarea lanza su paso anclado y cuenta como completada).
3.2 Por API (sin panel)
curl -X PUT https://TU-ARGUMENTUM/v1/panel/guides/sk_xxx \
-H "Authorization: Bearer ADMIN_TOKEN" -H "Content-Type: application/json" \
-d '{
"id": "g-onboarding-1",
"nombre": "Tour de bienvenida",
"tipo": "tooltip",
"estado": "publicada",
"prioridad": 1,
"paginas": ["prefijo:/app/"],
"frecuencia": { "tipo": "una_vez" },
"segmentoReglas": [{ "campo": "visitor.rol", "operador": "es", "valor": "editor" }],
"steps": [
{ "tipo": "tooltip", "contenido": { "titulo": "Bienvenido", "cuerpo": "3 pasos y fuera.", "cta": "Empezar" }, "anclaje": null },
{ "tipo": "tooltip", "contenido": { "titulo": "Crea tu primer proyecto", "cuerpo": "Con este botón.", "cta": "Siguiente" },
"anclaje": { "selector": "[data-sv='crear']", "obligatorio": true } }
]
}'
Estados: borrador → staged → publicada → pausada (DELETE elimina la guía). Un PUT guarda el def completo y sobrescribe lo anterior: no hay histórico de versiones (lo que se fue, se fue; usa borrador hasta tenerlo claro). POST /v1/panel/guides/:appKey/:id/publish pasa la guía a publicada, y el bundle GET /v1/config se regenera por ETag.
3.3 Métricas de guías
Impresiones, avances y completación por guía: vista Guías del panel o POST /v1/query/guias. Eventos generados por el agente: impresion, siguiente, atras, cta, cierre, completo.
4. Importar desde Pendo
- Conexión directa: Panel → Guías → Importar desde Pendo → pega la integration key → el servidor descarga guías, pages, features y metadata → selecciona qué importar.
- CLI:
node tools/pendo-export/export.mjs --key KEY(volcado) ynode tools/pendo-import.mjs --app-key sk_xxx --dir pendo-export-….
Detalle del mapeo, estados y deduplicación: sección «Importar desde Pendo» del README y docs/pruebas-finales.md.
5. API de consulta (BI, informes, tu propio código)
Autenticación: Authorization: Bearer ADMIN_TOKEN (o el token de sesión del panel). Todas aceptan appKey (obligatorio), tenantId (opcional, filtra a un cliente), rango (24h|7d|30d|12w|6m; un valor desconocido cae al defecto 12w) y from/to ISO explícitos.
Función (POST /v1/query/…) | Parámetros extra | Devuelve |
|---|---|---|
mau | granularity: day|week|month | serie {periodo, usuarios} |
kpis | — | usuarios, sesiones, pageviews, clicks, tenants |
top | kind: pages|features|tracks, limit | ranking con usuarios y usos |
funnel | pasos: [{tipo, id}] (≥2), ventanaHoras, ventanaModo: inicio|paso, desglose: {campo} | usuarios, % y tiempo hasta paso (mediana/media) por nivel; la ventana puede medir desde el primer paso o entre pasos; con desglose un funnel por valor del campo, visitantes sin identify en (sin valor) |
paths | evento {tipo,id}, direccion: antes|despues, niveles | niveles con distribución y salidas |
arbol | profundidad (def. 4), topHijos (def. 8) | mapa de uso de páginas: árbol de navegación desde la página de entrada, rol de cada página (tránsito, contenido, salida, agujero negro), permanencia mediana, clicks/vista y % salida |
clickmap | pageId, cell (%), dispositivo: desktop|tablet|movil, doc: true | celdas con conteo + desglose por feature; doc usa la posición en el documento (yd) para el mapa de página completa |
clickmap-elementos | pageId, dispositivo, limit | ranking de elementos clicados (feature o selector): clicks, usuarios, rage clicks y último uso |
clickmap-detail | pageId, dispositivo | detalle temporal de los clicks de una página: total, usuarios, serie diaria, por hora y día de semana, zonas por feature |
feature-detail | featureId | detalle temporal de usos de una feature: total, usuarios, primero/último, serie diaria, horas y día de semana |
scroll | pageId | profundidad de scroll: sesiones, media % y tramos ≤25/26–50/51–75/76–100 |
adoption | — | usuarios, usos, tendencia semanal por feature |
guias | — | impresiones/avances/completados por guía |
retencion | semanas (def. 12, máx. 26) | cohorts semanales: matriz de usuarios activos por offset (celda nula = semana aún no llegada) |
nps | — | por encuesta: respuestas, promotores/pasivos/detractores, score NPS, sí/no y comentarios recientes |
encuestas | — | respuestas por pregunta: tipo de escala, NPS, media 1–5, sí/no, distribución de opciones, comentarios y pregunta de abandono |
feedback | — | por ruta/pantalla: total, % de útiles y comentarios recientes (widget de ayuda de la web) |
errores | — | top de errores JavaScript por mensaje: ocurrencias, usuarios y último visto |
formularios | — | por formulario: iniciados, enviados, abandonados, campos y tasa de envío |
tenants | — | por tenant: usuarios, WAU, delta, features, attrs |
Ejemplo con fetch:
const r = await fetch("https://TU-ARGUMENTUM/v1/query/funnel", {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: "Bearer " + TOKEN },
body: JSON.stringify({
appKey: "sk_xxx", tenantId: "cliente-42", rango: "30d",
ventanaHoras: 168, // conversión dentro de 7 días
ventanaModo: "inicio", // o "paso": ventana entre pasos consecutivos
pasos: [
{ tipo: "page", id: "/app/inicio" },
{ tipo: "feature", id: "f-crear" },
{ tipo: "track", id: "proyecto_creado" }
]
})
});
Ingesta server-side (eventos que no pasan por el navegador: backend, ERP…):
curl -X POST https://TU-ARGUMENTUM/v1/events -H "X-Api-Key: sk_xxx" \
-H "Content-Type: application/json" \
-d '{"lote":[{"tipo":"track","ts":1760000000000,"visitorId":"u-1",
"tenantId":"cliente-42","path":"/api/proceso","trackName":"import_completa"}]}'
Smoke test completo de un despliegue: ADMIN_TOKEN=… node tools/api-smoke.mjs --server https://TU-ARGUMENTUM
6. Resolución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
| No llega ningún evento | key errónea, endpoint bloqueado, ruta excluida por el ámbito | consola del navegador → red; revisa data-key y el ámbito en Ajustes |
| Una feature cuenta 0 | selector roto o que matchea 0/2+ elementos | verifícalo con document.querySelectorAll(...) en la página |
| Adopción repentina a 0 tras un despliegue | el selector cambió con la build | añade data-* estables y usa selector.respaldo |
| Cambio de ruta SPA no genera pageview | router poco común que no toca History API ni hash | revisa el router; History API y hash-change están soportados nativamente |
| La guía no aparece | frecuencia ya consumida, throttle, fuera de fechas, ancla obligatoria ausente, segmento no cumple | revisa esos puntos; limpia localStorage.sv_seen para probar; recuerda que solo el estado publicada llega al bundle |
| 401 en el panel | usuario o contraseña incorrectos, sesión expirada (24 h) o usuario desactivado | vuelve a hacer login con tu usuario y contraseña; el ADMIN_TOKEN solo vale por API (Authorization: Bearer) y en el login como acceso de servicio |
7. Seguridad y privacidad (producción)
- Fija siempre
ADMIN_TOKENfuerte (el token de desarrollo solo avisa en log). - La ingesta autentica con la app key (pública por diseño, como cualquier herramienta client-side); el rate de ingesta lo fija la cuota de la organización de la app (
reqPorMinuto, 600/min por defecto,0= sin límite) y frena abusos. HTTPSobligatorio vía tu proxy inverso; el agente no envía cookies.- No se capturan valores de inputs (diseño del agente, no desactivable).
- Datos en TU infraestructura; sin terceros. Exporta o borra a tu criterio (los eventos son filas de ClickHouse).