Integra el análisis de Zenovay en cualquier framework JavaScript o aplicación de JavaScript puro usando nuestra flexible API de rastreo.
Instalación universal del script
Etiqueta de script básica
Funciona con cualquier framework:
<script
defer
data-tracking-code="YOUR_TRACKING_CODE"
src="https://api.zenovay.com/z.js"
></script>
Atributos del script
| Atributo | Descripción |
|---|---|
data-tracking-code | Requerido. Su código de rastreo del sitio web |
defer | Recomendado. Carga el script sin bloquear el renderizado de la página |
Configuración estándar
<script
defer
data-tracking-code="YOUR_TRACKING_CODE"
src="https://api.zenovay.com/z.js"
></script>
JavaScript puro (Vanilla JS)
Uso básico
// Registrar un evento
window.zenovay('track', 'button_click', {
button_id: 'signup',
location: 'hero'
});
// Registrar una vista de página (si el rastreo automático está deshabilitado)
window.zenovay('page');
// Identificar a un usuario
window.zenovay('identify', 'usuario-123', {
email: '[email protected]',
plan: 'pro'
});
// Registrar una meta
window.zenovay('goal', 'purchase', {
value: 99.99
});
// Registrar ingresos
window.zenovay('revenue', 149.99, 'USD', {
order_id: 'ORD-001'
});
Esperar a que el script se cargue
function waitForZenovay(callback, maxWait = 5000) {
const startTime = Date.now();
function check() {
if (window.zenovay) {
callback(window.zenovay);
} else if (Date.now() - startTime < maxWait) {
requestAnimationFrame(check);
}
}
check();
}
// Uso
waitForZenovay((zenovay) => {
zenovay('track', 'app_ready');
});
Patrón de cola de eventos
// Función de cola (funciona antes de que el script se cargue)
window.zenovay = window.zenovay || function() {
(window.zenovay.q = window.zenovay.q || []).push(arguments);
};
// Ahora puede llamar a zenovay() de inmediato, incluso antes de que el script se cargue
window.zenovay('track', 'early_event', { source: 'inline' });
window.zenovay('page');
Integración con Svelte
Configuración en App.svelte
<script>
import { onMount } from 'svelte';
import { page } from '$app/stores';
onMount(() => {
// Registrar la vista de página inicial
if (window.zenovay) {
window.zenovay('page');
}
});
// Registrar cambios de ruta
$: if ($page && window.zenovay) {
window.zenovay('page');
}
</script>
Store de Svelte
// stores/analytics.js
import { writable } from 'svelte/store';
function createAnalyticsStore() {
const { subscribe } = writable(null);
return {
subscribe,
track: (event, data) => {
if (typeof window !== 'undefined' && window.zenovay) {
window.zenovay('track', event, data);
}
},
identify: (userId, properties) => {
if (typeof window !== 'undefined' && window.zenovay) {
window.zenovay('identify', userId, properties);
}
},
trackGoal: (name, value) => {
if (typeof window !== 'undefined' && window.zenovay) {
window.zenovay('goal', name, { value });
}
}
};
}
export const analytics = createAnalyticsStore();
Uso en componentes Svelte
<script>
import { analytics } from '../stores/analytics';
function handleClick() {
analytics.track('button_click', { button: 'cta' });
}
</script>
<button on:click={handleClick}>
Haga clic aquí
</button>
Integración con SvelteKit
// hooks.client.js
import { page } from '$app/stores';
page.subscribe(($page) => {
if (typeof window !== 'undefined' && window.zenovay && $page) {
window.zenovay('page');
}
});
Integración con Angular
Creación del servicio
// analytics.service.ts
import { Injectable } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
declare global {
interface Window {
zenovay: {
(command: 'track', event: string, data?: Record<string, any>): void;
(command: 'page'): void;
(command: 'goal', name: string, data?: Record<string, any>): void;
(command: 'revenue', amount: number, currency: string, meta?: Record<string, any>): void;
(command: 'identify', userId: string, properties?: Record<string, any>): void;
};
}
}
@Injectable({
providedIn: 'root'
})
export class AnalyticsService {
constructor(private router: Router) {
this.setupRouteTracking();
}
private setupRouteTracking() {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
this.trackPageview(event.urlAfterRedirects);
});
}
track(event: string, data?: Record<string, any>) {
if (window.zenovay) {
(window as any).zenovay('track', event, data);
}
}
trackPageview() {
if (window.zenovay) {
(window as any).zenovay('page');
}
}
trackGoal(name: string, value?: number) {
if (window.zenovay) {
(window as any).zenovay('goal', name, { value });
}
}
identify(userId: string, properties?: Record<string, any>) {
if (window.zenovay) {
(window as any).zenovay('identify', userId, properties);
}
}
}
Uso en componentes
// signup.component.ts
import { Component } from '@angular/core';
import { AnalyticsService } from './analytics.service';
@Component({
selector: 'app-signup',
template: `<button (click)="handleSignup()">Registrarse</button>`
})
export class SignupComponent {
constructor(private analytics: AnalyticsService) {}
handleSignup() {
this.analytics.track('signup_click', {
source: 'header'
});
}
}
Configuración del módulo
// app.module.ts
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { AnalyticsService } from './analytics.service';
export function initAnalytics(analytics: AnalyticsService) {
return () => {
// Inicializar el rastreo
};
}
@NgModule({
providers: [
AnalyticsService,
{
provide: APP_INITIALIZER,
useFactory: initAnalytics,
deps: [AnalyticsService],
multi: true
}
]
})
export class AppModule {}
Integración con Ember.js
Creación del servicio
// app/services/analytics.js
import Service from '@ember/service';
import { inject as service } from '@ember/service';
export default class AnalyticsService extends Service {
@service router;
constructor() {
super(...arguments);
this.setupRouteTracking();
}
setupRouteTracking() {
this.router.on('routeDidChange', () => {
this.trackPageview(this.router.currentURL);
});
}
track(event, data) {
if (window.zenovay) {
window.zenovay('track', event, data);
}
}
trackPageview() {
if (window.zenovay) {
window.zenovay('page');
}
}
identify(userId, properties) {
if (window.zenovay) {
window.zenovay('identify', userId, properties);
}
}
}
Integración con Alpine.js
<div x-data="{ analytics: $store.analytics }">
<button @click="analytics.track('click', { button: 'cta' })">
Haga clic aquí
</button>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('analytics', {
track(event, data) {
if (window.zenovay) {
window.zenovay('track', event, data);
}
},
identify(userId, properties) {
if (window.zenovay) {
window.zenovay('identify', userId, properties);
}
}
});
});
</script>
Integración con jQuery
// Inicializar el asistente de rastreo
$.zenovay = {
track: function(event, data) {
if (window.zenovay) {
window.zenovay('track', event, data);
}
},
identify: function(userId, properties) {
if (window.zenovay) {
window.zenovay('identify', userId, properties);
}
}
};
// Uso
$(document).ready(function() {
$('#signup-btn').click(function() {
$.zenovay.track('signup_click', {
button: $(this).data('name')
});
});
});
Web Components
// analytics-tracker.js
class AnalyticsTracker extends HTMLElement {
connectedCallback() {
this.addEventListener('click', this.handleClick.bind(this));
}
handleClick() {
const event = this.getAttribute('data-event');
const dataAttrs = {};
for (const attr of this.attributes) {
if (attr.name.startsWith('data-prop-')) {
const key = attr.name.replace('data-prop-', '');
dataAttrs[key] = attr.value;
}
}
if (window.zenovay && event) {
window.zenovay('track', event, dataAttrs);
}
}
}
customElements.define('analytics-tracker', AnalyticsTracker);
Uso:
<analytics-tracker
data-event="cta_click"
data-prop-button="hero"
data-prop-page="home"
>
<button>Comenzar</button>
</analytics-tracker>
Patrones para aplicaciones de una sola página (SPA)
Rastreo con la History API
// Rastrear cambios en el historial
(function() {
const pushState = history.pushState;
const replaceState = history.replaceState;
history.pushState = function() {
pushState.apply(history, arguments);
trackPageChange();
};
history.replaceState = function() {
replaceState.apply(history, arguments);
trackPageChange();
};
window.addEventListener('popstate', trackPageChange);
function trackPageChange() {
if (window.zenovay) {
// Pequeño retraso para asegurarse de que el DOM esté actualizado
setTimeout(() => {
window.zenovay('page');
}, 100);
}
}
})();
Enrutamiento basado en hash
window.addEventListener('hashchange', function() {
if (window.zenovay) {
window.zenovay('page');
}
});
Definiciones de TypeScript
// types/zenovay.d.ts
interface ZenovayEventData {
[key: string]: string | number | boolean | undefined;
}
interface ZenovayRevenueData {
order_id: string;
value: number;
currency?: string;
items?: Array<{
id: string;
name: string;
price: number;
quantity: number;
}>;
}
interface Zenovay {
(command: 'track', event: string, data?: ZenovayEventData): void;
(command: 'page'): void;
(command: 'goal', name: string, data?: { value?: number }): void;
(command: 'revenue', amount: number, currency: string, meta?: Record<string, unknown>): void;
(command: 'identify', userId: string, properties?: ZenovayEventData): void;
}
declare global {
interface Window {
zenovay?: Zenovay;
}
}
export {};
Patrón de biblioteca envoltorio
Cree un envoltorio reutilizable:
// lib/analytics.ts
class Analytics {
private queue: Array<() => void> = [];
private ready = false;
constructor() {
this.waitForScript();
}
private waitForScript() {
const check = () => {
if (window.zenovay) {
this.ready = true;
this.processQueue();
} else {
requestAnimationFrame(check);
}
};
check();
}
private processQueue() {
this.queue.forEach(fn => fn());
this.queue = [];
}
private execute(fn: () => void) {
if (this.ready) {
fn();
} else {
this.queue.push(fn);
}
}
track(event: string, data?: Record<string, any>) {
this.execute(() => (window.zenovay as any)('track', event, data));
}
pageview() {
this.execute(() => (window.zenovay as any)('page'));
}
identify(userId: string, properties?: Record<string, any>) {
this.execute(() => (window.zenovay as any)('identify', userId, properties));
}
goal(name: string, value?: number) {
this.execute(() => (window.zenovay as any)('goal', name, { value }));
}
revenue(amount: number, currency: string, meta?: Record<string, any>) {
this.execute(() => (window.zenovay as any)('revenue', amount, currency, meta));
}
}
export const analytics = new Analytics();
Verificación de su integración
Modo de depuración
Active el registro de depuración para ver la actividad del rastreador en la consola del navegador. Hay tres formas de activarlo:
<!-- 1. Agregue el atributo data-debug a la etiqueta de script -->
<script
defer
data-tracking-code="YOUR_TRACKING_CODE"
data-debug="true"
src="https://api.zenovay.com/z.js"
></script>
2. Agregue ?zenovay_debug=true a cualquier URL de página (útil para producción).
3. El registro de depuración está activado automáticamente cuando se ejecuta en localhost.
Con la depuración activada, el rastreador registra cada evento que envía en la consola.
Pasos de verificación
- Abra las DevTools del navegador
- Vaya a la pestaña Red (Network)
- Filtre por "zenovay" o "analytics"
- Realice acciones
- Verifique que las solicitudes se envíen
Evento de prueba
// Prueba rápida
if (window.zenovay) {
window.zenovay('track', 'test_event', {
test: true,
timestamp: Date.now()
});
console.log('Evento de prueba enviado');
} else {
console.error('Zenovay no está cargado');
}
Solución de problemas
El script no carga
Verifique:
- Que la URL del script sea correcta
- Que no haya interferencia de bloqueadores de anuncios
- Que el ID del sitio web sea válido
- Que las solicitudes de red sean visibles
Los eventos no se registran
Confirme:
- Que
window.zenovayexista - Que el formato de los datos sea correcto
- Que no haya errores de JavaScript
- Que el dominio esté permitido
Problemas de navegación en SPA
Asegúrese de:
- Que los cambios de ruta se detecten
- Que se llame a
trackPageviewen la navegación - Que no haya rastreo duplicado