Integre o analytics do Zenovay em sua aplicação React com rastreamento automático de páginas, eventos personalizados e um hook personalizado para a função global window.zenovay.
Instalação
Adicione o script de rastreamento do Zenovay ao seu index.html:
<script
defer
data-tracking-code="YOUR_TRACKING_CODE"
src="https://api.zenovay.com/z.js"
></script>
Nenhum pacote npm é necessário. O script rastreia automaticamente as visualizações de página e fornece a função global window.zenovay para rastreamento personalizado.
Configuração Básica
Crie um Hook useZenovay
Crie um hook personalizado para encapsular a função global window.zenovay:
// hooks/useZenovay.js
export function useZenovay() {
const trackEvent = (name, properties) => {
if (window.zenovay) {
window.zenovay('track', name, properties);
}
};
const trackGoal = (name, properties) => {
if (window.zenovay) {
window.zenovay('goal', name, properties);
}
};
const trackPageview = () => {
if (window.zenovay) {
window.zenovay('page');
}
};
const trackRevenue = (amount, currency, meta) => {
if (window.zenovay) {
window.zenovay('revenue', amount, currency, meta);
}
};
const identify = (userId, properties) => {
if (window.zenovay) {
window.zenovay('identify', userId, properties);
}
};
return { trackEvent, trackGoal, trackPageview, trackRevenue, identify };
}
Rastreamento Automático de Páginas
Com React Router
O script do Zenovay rastreia automaticamente o carregamento inicial da página. Para mudanças de rota em SPA com React Router, rastreie as visualizações de página na mudança de rota:
import { BrowserRouter, useLocation } from 'react-router-dom';
import { useEffect } from 'react';
function PageTracker() {
const location = useLocation();
useEffect(() => {
if (window.zenovay) {
window.zenovay('page');
}
}, [location.pathname]);
return null;
}
function App() {
return (
<BrowserRouter>
<PageTracker />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/pricing" element={<Pricing />} />
</Routes>
</BrowserRouter>
);
}
As visualizações de página são rastreadas automaticamente nas mudanças de rota.
Eventos Personalizados
Hook useZenovay
import { useZenovay } from './hooks/useZenovay';
function SignupButton() {
const { trackEvent } = useZenovay();
const handleSignup = () => {
// Rastrear o clique no botão de cadastro
trackEvent('signup_click', {
plan: 'pro',
source: 'pricing_page'
});
// Continuar com a lógica de cadastro
performSignup();
};
return (
<button onClick={handleSignup}>
Começar Gratuitamente
</button>
);
}
Função Track Event
const { trackEvent } = useZenovay();
// Evento simples
trackEvent('button_click');
// Com propriedades
trackEvent('purchase', {
product_id: 'SKU-001',
value: 99.99,
currency: 'USD'
});
// Com valor
trackEvent('download', { file: 'guide.pdf' });
Rastreamento de Metas
Rastrear Conclusão de Meta
import { useZenovay } from './hooks/useZenovay';
import { useEffect } from 'react';
function CheckoutSuccess({ order }) {
const { trackGoal } = useZenovay();
useEffect(() => {
trackGoal('purchase', {
value: order.total,
order_id: order.id,
products: order.items
});
}, [order]);
return <div>Obrigado pelo seu pedido!</div>;
}
Identificação de Usuário
Identificar Usuários
import { useZenovay } from './hooks/useZenovay';
import { useAuth } from './auth';
import { useEffect } from 'react';
function UserIdentifier() {
const { user, isAuthenticated } = useAuth();
const { identify } = useZenovay();
useEffect(() => {
if (isAuthenticated && user) {
identify(user.id, {
email: user.email,
name: user.name,
plan: user.subscription
});
}
}, [user, isAuthenticated]);
return null;
}
No Fluxo de Autenticação
async function handleLogin(credentials) {
const user = await login(credentials);
// Identificar após o login
if (window.zenovay) {
window.zenovay('identify', user.id, {
email: user.email
});
}
navigate('/dashboard');
}
Rastreamento de Receita
Rastrear Receita
import { useZenovay } from './hooks/useZenovay';
import { useEffect } from 'react';
function OrderConfirmation({ order }) {
const { trackRevenue } = useZenovay();
useEffect(() => {
trackRevenue(order.total, 'USD', {
order_id: order.id,
items: order.items.map(item => ({
id: item.sku,
name: item.name,
price: item.price,
quantity: item.quantity
}))
});
}, [order]);
return (
<div>
<h1>Pedido Confirmado!</h1>
<p>Pedido #{order.id}</p>
</div>
);
}
Componentes de Rastreamento de Eventos
Botão com Rastreamento
import { useZenovay } from './hooks/useZenovay';
function TrackableButton({ event, eventData, children, ...props }) {
const { trackEvent } = useZenovay();
const handleClick = (e) => {
trackEvent(event, eventData);
props.onClick?.(e);
};
return (
<button {...props} onClick={handleClick}>
{children}
</button>
);
}
// Uso
<TrackableButton
event="cta_click"
eventData={{ location: 'hero' }}
onClick={handleSignup}
>
Começar
</TrackableButton>
Rastrear ao Montar
import { useZenovay } from './hooks/useZenovay';
import { useEffect } from 'react';
function TrackOnMount({ event, eventData }) {
const { trackEvent } = useZenovay();
useEffect(() => {
trackEvent(event, eventData);
}, []);
return null;
}
// Uso
<TrackOnMount
event="pricing_viewed"
eventData={{ referrer: document.referrer }}
/>
Suporte a TypeScript
Tipos
// types/zenovay.d.ts
interface ZenovayFunction {
(command: 'track', name: string, properties?: Record<string, unknown>): void;
(command: 'identify', userId: string, traits?: Record<string, unknown>): void;
(command: 'goal', name: string, properties?: Record<string, unknown>): void;
(command: 'page'): void;
(command: 'revenue', amount: number, currency: string, meta?: Record<string, unknown>): void;
}
declare global {
interface Window {
zenovay: ZenovayFunction;
}
}
export {};
Hook Tipado
// hooks/useZenovay.ts
export function useZenovay() {
const trackEvent = (name: string, properties?: Record<string, unknown>) => {
if (window.zenovay) {
window.zenovay('track', name, properties);
}
};
const trackGoal = (name: string, properties?: Record<string, unknown>) => {
if (window.zenovay) {
window.zenovay('goal', name, properties);
}
};
const identify = (userId: string, properties?: Record<string, unknown>) => {
if (window.zenovay) {
window.zenovay('identify', userId, properties);
}
};
return { trackEvent, trackGoal, identify };
}
Renderização no Lado do Servidor
Prevenir Problemas com SSR
A função window.zenovay está disponível apenas no navegador. Sempre verifique antes de usar:
import { useEffect, useState } from 'react';
function ZenovayWrapper({ children }) {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
// Rastrear apenas após a montagem do componente (lado do cliente)
if (!mounted) {
return children;
}
return children;
}
Testes
Mock do Hook
// test-utils.jsx
import { vi } from 'vitest';
export const mockZenovay = {
trackEvent: vi.fn(),
trackGoal: vi.fn(),
identify: vi.fn(),
trackPageview: vi.fn(),
trackRevenue: vi.fn()
};
vi.mock('./hooks/useZenovay', () => ({
useZenovay: () => mockZenovay
}));
Exemplo de Teste
import { render, fireEvent, screen } from '@testing-library/react';
import { mockZenovay } from './test-utils';
import SignupButton from './SignupButton';
test('rastreia clique no cadastro', () => {
render(<SignupButton />);
fireEvent.click(screen.getByText('Começar Gratuitamente'));
expect(mockZenovay.trackEvent).toHaveBeenCalledWith('signup_click', expect.any(Object));
});
Padrões Comuns
Rastreamento em E-commerce
import { useZenovay } from './hooks/useZenovay';
import { useEffect } from 'react';
function ProductPage({ product }) {
const { trackEvent } = useZenovay();
useEffect(() => {
trackEvent('product_viewed', {
product_id: product.id,
product_name: product.name,
price: product.price,
category: product.category
});
}, [product.id]);
const handleAddToCart = () => {
trackEvent('add_to_cart', {
product_id: product.id,
price: product.price,
quantity: 1
});
};
return (
<div>
<h1>{product.name}</h1>
<button onClick={handleAddToCart}>Adicionar ao Carrinho</button>
</div>
);
}
Rastreamento de Formulário
import { useZenovay } from './hooks/useZenovay';
function ContactForm() {
const { trackEvent, trackGoal } = useZenovay();
const handleSubmit = async (data) => {
trackEvent('form_submitted', {
form_name: 'contact',
has_phone: !!data.phone
});
await submitForm(data);
trackGoal('contact_form');
};
return (
<form onSubmit={handleSubmit}>
{/* campos do formulário */}
</form>
);
}
Solução de Problemas
Eventos Não Rastreando
Verifique:
- Se a tag de script está no seu index.html
- Se o tracking code está correto
- Se não está sendo bloqueado por um bloqueador de anúncios
- O console para erros
Visualizações de Página Faltando
Verifique:
- Se o componente PageTracker está montado
- Se o React Router está configurado corretamente
- Se as rotas são renderizadas dentro do router
Rastreamento Duplo
Evite:
- Múltiplas tags de script
- Rastreamento manual + automático
- StrictMode causando efeitos duplos