Alternativa sin cookies a Google analytics: Umami Cloud

Primeros pasos para medir con Umami

En el mundo del SEO, «lo que no se mide, no se conoce«. Igual que consultamos el desnivel acumulado o el tiempo por kilómetro en nuestras rutas, en un proyecto digital necesitamos métricas que nos indiquen si el contenido es realmente útil para nuestra comunidad.

Tras buscar una alternativa que respetara la privacidad de los usuarios y que no pesara en la carga de la web, la solución elegida ha sido Umami.is.

¿Por qué Umami resulta una alternativa interesante?

La mayoría de los blogs utilizan herramientas complejas que recopilan demasiados datos personales. Para un blog corporativo o pequeño, las motivaciones para elegir Umami son claras:

  1. Privacidad por bandera: No usa cookies ni rastrea datos personales, algo vital para la ética de un proyecto en pleno 2026.
  2. Ligereza: El script es minúsculo. No queremos que nuestra web tarde en cargar en mitad de la montaña con poca cobertura.
  3. Métricas de intención: Más allá de las «visitas», queremos medir interacciones reales. ¿Están leyendo los consejos? ¿Están guardando las coordenadas del parking?
  4. Es gratuito hasta 100.000 interacciones. Muy válido para blogs corporativos pequeños.
  5. Si tienes capacidad técnica lo puedes instalar en tu servidor y no tener ningún límite ni poner los datos en hosting fuera de tu alcance.

El Código: personalizar los objetivos de medida

Los que llevamos tiempo en esto de la análitica web, no tenemos problema en usar Google Tag manager y Analytics para saber cuanto nos interesa de las interaciones de los visitantes con nuestras páginas. Para transformar las estadísticas básicas en información accionable, hemos implementado varias mediciones mediante JavaScript.

1. Medir el interés del usuario: Scroll del 50% y 90%

No basta con que alguien entre a un artículo sobre la «incremento de precio de carburantes por la ofensiva de Israel». Queremos saber si llegan al final. Si la mayoría se queda al 50%, quizás el texto es demasiado largo o las fotos están mal ubicadas.

El objetivo: Disparar un evento cuando el usuario consume el contenido.


window.addEventListener('scroll', function() {
const h = document.documentElement, b = document.body;
const porcentaje = (h.scrollTop || b.scrollTop) / (h.scrollHeight - h.clientHeight) * 100;
if (porcentaje >= 50 && !window.scroll50) {
umami.track('Scroll-Mitad');
window.scroll50 = true;
}
if (porcentaje >= 90 && !window.scroll90) {
umami.track('Scroll-Final');
window.scroll90 = true;
}
});

2. Capturando la utilidad: El evento de «Copiado»

En algunos proyectos, copiar el nombre de una referencia de producto o alguna palabra interesante es justo la métrica de éxito definitiva para un blog informativo.

El objetivo: Saber qué datos específicos son los más valiosos para el lector.

document.addEventListener('copy', function() {
const texto = window.getSelection().toString().substring(0, 50);
if (texto && typeof umami !== 'undefined') {
umami.track('Contenido-Copiado', { contenido: texto });
}
});

3. El mapa de clics automático

Para no tener que etiquetar cada botón manualmente, usamos un script que escucha cualquier clic en enlaces o botones y nos dice qué texto tenían. Así sabemos si prefieren «Contacto» o «Descargar PDF».

document.addEventListener('click', function (event) {
const elemento = event.target.closest('a, button');
if (elemento && typeof umami !== 'undefined') {
umami.track('Click-Interaccion', { etiqueta: elemento.innerText.trim() });
}
}, true);

4. El formulario enviado:

Medir el envío de los formularios es el top de las medidas junto a los pagos si se trata de una tienda.

Formularios Sureforms:


document.addEventListener('submit', function(event) {
// Verificamos si es el formulario correcto por su ID
if (event.target && event.target.id === 'srfm-form-231') {
// Usamos un pequeño delay para verificar si SureForms oculta el form o muestra éxito
setTimeout(function() {
// SureForms suele poner "display: none" al form o mostrar un mensaje de éxito
const isHidden = window.getComputedStyle(event.target).display === 'none';
const hasError = event.target.querySelector('.srfm-common-error-message:not([hidden])');
if (isHidden || !hasError) {
if (typeof umami !== 'undefined') {
umami.track('Formulario-Contacto-Enviado', {
form_id: '231',
url: window.location.pathname
});
}
}
}, 1000); // Esperamos 1 segundo a que procese el AJAX
}
});

Formularios Hubspot:


window.addEventListener('message', function(event) {
// 1. Verificamos que el mensaje viene de HubSpot
if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
// 2. Extraemos el ID del formulario para saber cuál es
const formId = event.data.id;
if (typeof umami !== 'undefined') {
umami.track('HubSpot-Form-Success', {
hubspot_id: formId,
url: window.location.pathname
});
console.log('Evento de HubSpot enviado a Umami: ' + formId);
}
}
});
//puedes humanizar los id de Hubspot para analizarlos con mayor facilidad en el panel de Umami
const nombresForms = {
'id-largo-de-hubspot-1': 'Contacto Principal',
'id-largo-de-hubspot-2': 'Suscripción Blog'
};
// En el track de Umami usarías:
umami.track(nombresForms[formId] || 'Form-HubSpot-Desconocido');

Formularios de Contact form 7:

(function() {
const trackCF7 = (eventName, label) => {
document.addEventListener(eventName, function(event) {
if (typeof umami !== 'undefined') {
umami.track(label, {
form_id: event.detail.contactFormId,
url: window.location.pathname,
unit_tag: event.detail.unitTag
});
}
}, false);
};
// 1. Envío Exitoso
trackCF7('wpcf7mailsent', 'CF7-Exito');
// 2. Error de Validación (Campos mal rellenos)
trackCF7('wpcf7invalid', 'CF7-Error-Validacion');
// 3. Detectado como Spam
trackCF7('wpcf7spam', 'CF7-Spam');
// 4. Fallo técnico (Error en el servidor o AJAX)
trackCF7('wpcf7mailfailed', 'CF7-Fallo-Servidor');
})();
const nombreForm = (id) => {
const forms = {
'231': 'Contacto Principal',
'50': 'Newsletter Pie'
};
return forms[id] || 'Form-' + id;
};
// Y en el umami.track usarías:
// name: label + '-' + nombreForm(event.detail.contactFormId)

Detectar errores 404


// Detectar Errores 404 (Pon esto en tu plantilla 404.php o similar)
if (document.title.includes('Page Not Found') || document.body.classList.contains('error404')) {
if (typeof umami !== 'undefined') {
umami.track('Error-404', {
url_intentada: window.location.pathname,
referencia: document.referrer
});
}
}

Búsquedas internas

(function() {
// 1. Obtenemos los parámetros de la URL
const urlParams = new URLSearchParams(window.location.search);
const termino = urlParams.get('s'); // 's' es el estándar de WordPress
// 2. Si existe el parámetro 's' y hay una función de umami disponible
if (termino && typeof umami !== 'undefined') {
// 3. Enviamos el evento
umami.track('Busqueda-Interna', {
keyword: termino.toLowerCase().trim(),
url_completa: window.location.href
});
console.log('Búsqueda detectada y enviada a Umami: ' + termino);
}
})();

Copiado de imágenes

No es algo muy utilizado pero puede aportar información interesante en algunos proyectos.


document.addEventListener('copy', function(e) {
if (e.target.tagName === 'IMG') {
if (typeof umami !== 'undefined') {
umami.track('Imagen-Copiada', { src: e.target.src });
}
}
});

Imprimir página

Útil métrica para algunos proyectos como tutoriales.


window.addEventListener('beforeprint', function() {
if (typeof umami !== 'undefined') {
umami.track('Imprimir-Pagina', { url: window.location.pathname });
}
});

El análisis: Transformando datos en decisiones estratégicas

En un blog corporativo, la analítica no es una cuestión de vanidad (cuántos clics recibo), sino de rendimiento y conversión. Medir con Umami nos permite entender el «viaje del cliente» desde que entra a un artículo informacional hasta que muestra una intención clara de negocio.

Así es como debemos interpretar los datos para optimizar cualquier estrategia de contenidos:

1. Auditoría de Retención ¿Nos están leyendo?

Si un artículo tiene un alto volumen de visitas pero el evento Scroll-Mitad es inusualmente bajo, estamos perdiendo al cliente potencial en los primeros párrafos.

  • Diagnóstico: El título genera una expectativa que el contenido no cumple rápidamente, o el diseño es poco legible (bloques de texto demasiado densos).
  • Acción Corporativa: Reestructurar el artículo con subtítulos más claros, añadir elementos visuales o mejorar el «gancho» inicial para asegurar que el mensaje de marca llegue al usuario.

2. Identificación de «Micro-Conversiones» (Copiado de Contenido)

El evento Texto-Copiado es uno de los indicadores de mayor valor en el B2B y blogs técnicos.

  • Diagnóstico: Si los usuarios copian códigos, listas de pasos o definiciones técnicas, significa que tu blog se está convirtiendo en una herramienta de consulta.
  • Acción Corporativa: Identificar qué fragmentos son los más valorados para transformarlos en recursos descargables (PDFs, plantillas o Checklists) a cambio de una suscripción (Lead Magnet).

3. Optimización del CTR y Mapas de Clics

El rastreo automático de clics nos permite ver si nuestras llamadas a la acción (CTAs) están alineadas con la intención del lector.

  • Análisis: ¿Hacen más clic en el botón de «Pedir Demo» al final del post o en el enlace de «Saber más» integrado en el texto?
  • Acción Corporativa: Realizar test A/B sencillos cambiando el texto de los botones basándonos en los datos de Click-Interaccion. Si un artículo atrae mucho tráfico pero nadie hace clic en el CTA comercial, quizás el contenido es demasiado genérico para esa etapa del embudo.

4. Análisis de Calidad frente a Cantidad

Cruzar el tiempo de permanencia (evento Lectura-60s) con el Scroll-Final nos da la métrica real de Engagement.

  • Diagnóstico: Un usuario que pasa 2 minutos y llega al 90% es un «Lead Calificado» en potencia.
  • Acción Corporativa: Priorizar la actualización y promoción de los artículos que generan estos «lectores de calidad» frente a los que solo generan visitas efímeras (Clickbait).

Datos con propósito: De la métrica al ROI

Implementar Umami en un blog corporativo permite pasar de la intuición a la evidencia. Al monitorizar cómo interactúa el usuario con el conocimiento que compartimos, podemos refinar nuestra línea editorial para que no solo atraiga visitas, sino que construya autoridad de marca y facilite el camino hacia la venta.

Como anexos podríamos añadir los códigos de medición analítica precisos para tiendas online como prestashop, magento, woocommerce,… por ahora solo ponemos el de shopify, esa plataforma que tuvo gran éxito para proyectos pequeños que ahora hay incluso proyectos medianos e incluso potentes que lo usan. Sigo pensando que hay un tanto por cien elevado de usuarios que lo eligen por su simplicidad y si el proyecto crece se dan cuenta que tampoco entienden como analizarlo y/o mejorarlo.

Anexo Código Umami para shopify

Para colocar como pixel `personalizado. Este código se centra exclusivamente en escuchar los eventos nativos de Shopify y enviarlos a tu instancia de Umami.

/const send = (name, data = {}) => {
window.parent.postMessage({
source: "shopify-pixel",
event: name,
data
}, "*");
};

// 🟢 PRODUCT VIEW
analytics.subscribe("product_viewed", (event) => {
const p = event.data.productVariant;

send("view_product", {
id: p.product.id,
name: p.product.title,
price: p.price.amount,
currency: p.price.currencyCode
});
});

// 🟢 ADD TO CART
analytics.subscribe("product_added_to_cart", (event) => {
const item = event.data.cartLine;

send("add_to_cart", {
name: item.merchandise?.product?.title || item.title,
variant: item.merchandise?.title,
quantity: item.quantity,
value: item.cost?.totalAmount?.amount,
currency: item.cost?.totalAmount?.currencyCode
});
});

// 🟡 CHECKOUT STARTED (opcional pero recomendado)
analytics.subscribe("checkout_started", (event) => {
const c = event.data.checkout;

send("begin_checkout", {
value: c.totalPrice.amount,
currency: c.totalPrice.currencyCode
});
});

// 🔴 PURCHASE
analytics.subscribe("checkout_completed", (event) => {
const c = event.data.checkout;

send("purchase", {
order_id: c?.order?.id || c?.id,
value: c.totalPrice.amount,
currency: c.totalPrice.currencyCode
});
});

En el head se añade este código para que shopify comunique los datos

window.addEventListener("message", (event) => {
if (!event.data || event.data.source !== "shopify-pixel") return;

if (window.umami) {
umami.track(event.data.event, event.data.data || {});
}
});

Para comportamiento de usuario en shopify es mejor no ponerlo en el pixel personalizado sino dentro del




 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *