@engagetrack/react
v1.5.0
Published
Enterprise-grade React tracking SDK with session management, WebSocket support, and comprehensive user activity monitoring
Maintainers
Readme
@engagetrack/react
Enterprise-grade React tracking SDK with session management, WebSocket support, and comprehensive user activity monitoring.
🚀 Features
- ✅ Session Management - Automatic session tracking with timeout handling
- ✅ Real-time WebSocket - Live communication with tracking server
- ✅ Referral Tracking - Comprehensive UTM and referral parameter tracking
- ✅ Link Click Tracking - Automatic tracking with external navigation detection
- ✅ Activity Monitoring - Idle timeout detection and user engagement tracking
- ✅ Cookie-based Identity - Persistent user and session identification
- ✅ React Hooks - Easy-to-use hooks for all tracking functionality
- ✅ TypeScript Support - Full TypeScript definitions included
- ✅ Zero Dependencies - Lightweight with no external dependencies (except React)
📦 Installation
npm install @engagetrack/reactor with yarn:
yarn add @engagetrack/reactor with pnpm:
pnpm add @engagetrack/react🔧 Quick Start
1. Wrap Your App with EngageTrackProvider
import React from 'react';
import { EngageTrackProvider } from '@engagetrack/react';
import App from './App';
function Root() {
return (
<EngageTrackProvider
config={{
siteId: 'your-site-id',
domain: 'yourdomain.com',
serverUrl: 'https://api.engagetrack.net/api/track', // Optional
debug: true, // Enable console logging (optional)
}}
>
<App />
</EngageTrackProvider>
);
}
export default Root;2. Use Tracking Hooks in Your Components
import React from 'react';
import { useEngageTrack, usePageView } from '@engagetrack/react';
function HomePage() {
const { track } = useEngageTrack();
// Automatically track page view
usePageView();
const handleSignUp = () => {
track('signup_click', {
button: 'hero',
timestamp: Date.now(),
});
// Your sign up logic
};
return (
<div>
<h1>Welcome!</h1>
<button onClick={handleSignUp}>Sign Up</button>
</div>
);
}
export default HomePage;📚 API Reference
EngageTrackProvider
The provider component that wraps your application and provides tracking functionality.
Props:
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| config | EngageTrackConfig | Yes | Configuration object |
| children | ReactNode | Yes | Your app components |
Configuration Options:
interface EngageTrackConfig {
siteId: string; // Required: Your site identifier
domain: string; // Required: Domain for cookie management
serverUrl?: string; // Optional: Custom tracking server URL
idleTimeout?: number; // Optional: Idle timeout in ms (default: 30000)
checkInterval?: number; // Optional: Activity check interval (default: 1000)
sessionTimeoutDuration?: number; // Optional: Session timeout (default: 1800000)
heartbeatIntervalMs?: number; // Optional: WebSocket heartbeat (default: 30000)
maxReconnectAttempts?: number; // Optional: Max reconnection attempts (default: 5)
referralExpiryDays?: number; // Optional: Referral cookie expiry (default: 30)
debug?: boolean; // Optional: Enable debug logging (default: false)
disabled?: boolean; // Optional: Disable tracking (default: false)
}Hooks
useEngageTrack()
Main hook for accessing tracking functionality.
const {
track,
trackReferralConversion,
getSessionState,
isEnabled,
isInitialized
} = useEngageTrack();Returns:
track(eventType: string, data?: Record<string, unknown>)- Track custom eventstrackReferralConversion(data?: Record<string, unknown>)- Track referral conversionsgetSessionState()- Get current session stateisEnabled: boolean- Whether tracking is enabledisInitialized: boolean- Whether SDK is initialized
Example:
function ProductPage({ productId }) {
const { track } = useEngageTrack();
const handleAddToCart = () => {
track('add_to_cart', {
productId,
price: 29.99,
quantity: 1,
});
};
return <button onClick={handleAddToCart}>Add to Cart</button>;
}usePageView(path?, additionalData?)
Automatically track page views when component mounts.
usePageView('/custom-path', { category: 'products' });Parameters:
path?: string- Optional custom path (defaults to current pathname)additionalData?: Record<string, unknown>- Additional data to track
Example:
function BlogPost({ postId, title }) {
usePageView(`/blog/${postId}`, {
postId,
title,
category: 'blog'
});
return <article>...</article>;
}useTrackEvent(eventType, baseData?)
Create a memoized tracking function for specific events.
const trackClick = useTrackEvent('button_click', { button: 'header' });Parameters:
eventType: string- Type of event to trackbaseData?: Record<string, unknown>- Base data included with every call
Returns: (additionalData?: Record<string, unknown>) => void
Example:
function NewsletterForm() {
const trackSubmit = useTrackEvent('newsletter_signup', {
form: 'footer'
});
const handleSubmit = (email) => {
trackSubmit({ email, timestamp: Date.now() });
// Submit form
};
return <form onSubmit={handleSubmit}>...</form>;
}useSessionState()
Access and subscribe to session state changes (updates every second).
const session = useSessionState();Returns:
interface SessionState {
sessionId: string | null; // Current session ID
userId: string | null; // Current user ID
dbSessionId: string | null; // Database session ID
startTime: number; // Session start timestamp
lastActivityTime: number; // Last activity timestamp
pageViewCount: number; // Number of page views
isActive: boolean; // Whether session is active
isConnected: boolean; // Whether WebSocket is connected
}Example:
function SessionDebug() {
const session = useSessionState();
return (
<div>
<p>Session ID: {session.sessionId}</p>
<p>Page Views: {session.pageViewCount}</p>
<p>Active: {session.isActive ? '✅' : '❌'}</p>
<p>Connected: {session.isConnected ? '🟢' : '🔴'}</p>
</div>
);
}🎯 Common Use Cases
Track Button Clicks
function CTAButton() {
const { track } = useEngageTrack();
return (
<button
onClick={() => track('cta_click', {
location: 'hero',
variant: 'primary'
})}
>
Get Started
</button>
);
}Track Form Submissions
function ContactForm() {
const trackSubmit = useTrackEvent('contact_form_submit');
const handleSubmit = async (formData) => {
trackSubmit({
fields: Object.keys(formData),
timestamp: Date.now(),
});
await submitForm(formData);
};
return <form onSubmit={handleSubmit}>...</form>;
}Track Referral Conversions
function CheckoutComplete({ orderId, amount }) {
const { trackReferralConversion } = useEngageTrack();
useEffect(() => {
// Track conversion after successful purchase
trackReferralConversion({
orderId,
amount,
currency: 'USD',
conversionType: 'purchase',
});
}, [orderId, amount, trackReferralConversion]);
return <div>Thank you for your purchase!</div>;
}Track Video Playback
function VideoPlayer({ videoId, title }) {
const { track } = useEngageTrack();
return (
<video
onPlay={() => track('video_play', { videoId, title })}
onPause={() => track('video_pause', { videoId, title })}
onEnded={() => track('video_complete', { videoId, title })}
>
<source src={`/videos/${videoId}.mp4`} />
</video>
);
}Track User Engagement
function ArticlePage({ articleId }) {
const { track } = useEngageTrack();
const [readProgress, setReadProgress] = useState(0);
useEffect(() => {
if (readProgress >= 50 && readProgress < 51) {
track('article_half_read', { articleId });
} else if (readProgress >= 100) {
track('article_complete', { articleId });
}
}, [readProgress, articleId, track]);
return <article>...</article>;
}🔒 Privacy & Compliance
Disable Tracking
You can disable tracking in several ways:
1. Via Config:
<EngageTrackProvider
config={{
siteId: 'your-site-id',
domain: 'yourdomain.com',
disabled: true, // Disable all tracking
}}
>
<App />
</EngageTrackProvider>2. Via localStorage:
// Users can disable tracking by setting this flag
localStorage.setItem('engageTrackDisabled', 'true');3. Conditionally Based on User Consent:
function Root() {
const [hasConsent, setHasConsent] = useState(false);
return (
<EngageTrackProvider
config={{
siteId: 'your-site-id',
domain: 'yourdomain.com',
disabled: !hasConsent,
}}
>
{!hasConsent && (
<CookieConsent onAccept={() => setHasConsent(true)} />
)}
<App />
</EngageTrackProvider>
);
}🌐 Framework Integration
Next.js (App Router)
// app/providers.tsx
'use client';
import { EngageTrackProvider } from '@engagetrack/react';
export function Providers({ children }) {
return (
<EngageTrackProvider
config={{
siteId: process.env.NEXT_PUBLIC_SITE_ID!,
domain: process.env.NEXT_PUBLIC_DOMAIN!,
}}
>
{children}
</EngageTrackProvider>
);
}
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Next.js (Pages Router)
// pages/_app.tsx
import { EngageTrackProvider } from '@engagetrack/react';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<EngageTrackProvider
config={{
siteId: process.env.NEXT_PUBLIC_SITE_ID!,
domain: process.env.NEXT_PUBLIC_DOMAIN!,
}}
>
<Component {...pageProps} />
</EngageTrackProvider>
);
}React Router
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { EngageTrackProvider, usePageView } from '@engagetrack/react';
function PageWrapper({ children }) {
usePageView(); // Track page view on route change
return children;
}
function App() {
return (
<EngageTrackProvider
config={{
siteId: 'your-site-id',
domain: 'yourdomain.com',
}}
>
<BrowserRouter>
<Routes>
<Route path="/" element={<PageWrapper><Home /></PageWrapper>} />
<Route path="/about" element={<PageWrapper><About /></PageWrapper>} />
</Routes>
</BrowserRouter>
</EngageTrackProvider>
);
}Vite + React
// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { EngageTrackProvider } from '@engagetrack/react';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<EngageTrackProvider
config={{
siteId: import.meta.env.VITE_SITE_ID,
domain: import.meta.env.VITE_DOMAIN,
}}
>
<App />
</EngageTrackProvider>
</React.StrictMode>
);🛠️ Advanced Usage
Custom Event Types
// Define your custom event types
type CustomEvents =
| 'product_view'
| 'add_to_cart'
| 'checkout_start'
| 'purchase_complete';
function ProductPage() {
const { track } = useEngageTrack();
const trackEvent = (event: CustomEvents, data?: Record<string, unknown>) => {
track(event, data);
};
return (
<button onClick={() => trackEvent('add_to_cart', { productId: '123' })}>
Add to Cart
</button>
);
}Session End Callback
import { EngageTrackService } from '@engagetrack/react';
const service = new EngageTrackService({
siteId: 'your-site-id',
domain: 'yourdomain.com',
});
service.onSessionEnd(() => {
console.log('Session has ended');
// Perform cleanup or save data
});Manual Referral Data Access
import { getReferralData } from '@engagetrack/react';
function ReferralInfo() {
const referralData = getReferralData();
if (!referralData) {
return <div>No referral detected</div>;
}
return (
<div>
<p>Source: {referralData.source?.source}</p>
<p>UTM Campaign: {referralData.urlParams.utm_campaign}</p>
</div>
);
}📊 Event Types
The SDK automatically tracks these events:
PAGE_LOAD- Page loadsPAGE_HIDDEN- Page becomes hiddenSESSION_END- Session endsSESSION_TIMEOUT- Session times out due to inactivityIDLE_TIMEOUT- User becomes idleUSER_CLICK- Link clicksREFERRAL_CONVERSION- Automatic referral trackingREFERRAL_CONVERSION_MANUAL- Manual referral tracking
You can also track custom events with any name.
🐛 Debugging
Enable debug mode to see console logs:
<EngageTrackProvider
config={{
siteId: 'your-site-id',
domain: 'yourdomain.com',
debug: true, // Enable debug logging
}}
>
<App />
</EngageTrackProvider>🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT License - see LICENSE file for details
🔗 Links
💬 Support
For support, email [email protected] or open an issue on GitHub.
Made with ❤️ by the EngageTrack Team
