React hooks for Pulsora Analytics - Privacy-first analytics tracking
npm install @pulsora/reactReact hooks for Pulsora Analytics. Privacy-first analytics tracking with idiomatic React integration.
``bash`
npm install @pulsora/react @pulsora/core
`tsx
import { PulsoraProvider, usePageview, useEvent } from '@pulsora/react';
function App() {
return (
);
}
function MyPage() {
usePageview(); // Automatic pageview tracking
const trackEvent = useEvent();
return (
);
}
`
Context provider that initializes Pulsora and makes it available to child components.
#### Props
`typescript
interface PulsoraProviderProps {
config: PulsoraConfig;
children: ReactNode;
}
interface PulsoraConfig {
apiToken: string;
endpoint?: string; // Default: https://api.pulsora.co/api/ingest
debug?: boolean; // Default: false
autoPageviews?: boolean; // Default: true
maxRetries?: number; // Default: 10
retryBackoff?: number; // Default: 1000
}
`
#### Example
`tsx
import { PulsoraProvider } from '@pulsora/react';
function App() {
return (
apiToken: process.env.PULSORA_TOKEN,
debug: process.env.NODE_ENV === 'development',
}}
>
);
}
`
Access the Pulsora instance directly for advanced use cases.
#### Returns
PulsoraCore - The Pulsora tracker instance
#### Example
`tsx
import { usePulsora } from '@pulsora/react';
function AdvancedComponent() {
const pulsora = usePulsora();
const handleAction = async () => {
const fingerprint = await pulsora.getVisitorFingerprint();
const sessionId = pulsora.getSessionId();
// Use these values as needed
console.log({ fingerprint, sessionId });
};
return ;
}
`
Automatically track pageviews.
#### Options
`typescript`
interface UsePageviewOptions {
trigger?: any; // Value that triggers pageview when it changes
disabled?: boolean; // Disable tracking
}
#### Example - Basic Usage
`tsx
import { usePageview } from '@pulsora/react';
function Page() {
usePageview(); // Tracks on mount
return
#### Example - React Router
`tsx
import { useLocation } from 'react-router-dom';
import { usePageview } from '@pulsora/react';function App() {
const location = useLocation();
// Track pageview on route changes
usePageview({ trigger: location.pathname });
return (
} />
} />
);
}
`#### Example - Next.js App Router
`tsx
'use client';import { usePathname } from 'next/navigation';
import { usePageview } from '@pulsora/react';
export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
usePageview({ trigger: pathname });
return <>{children}>;
}
`#### Example - Next.js Pages Router
`tsx
import { useRouter } from 'next/router';
import { usePageview } from '@pulsora/react';function MyApp({ Component, pageProps }) {
const router = useRouter();
usePageview({ trigger: router.asPath });
return ;
}
`#### Example - Remix
`tsx
import { useLocation } from '@remix-run/react';
import { usePageview } from '@pulsora/react';export function Root() {
const location = useLocation();
usePageview({ trigger: location.pathname });
return (
$3
Track custom events.
#### Returns
TrackEventFunction - Function to track events`typescript
type TrackEventFunction = (
eventName: string,
eventData?: Record,
) => Promise;
`#### Example
`tsx
import { useEvent } from '@pulsora/react';function ProductCard({ product }) {
const trackEvent = useEvent();
const handleAddToCart = () => {
trackEvent('add_to_cart', {
product_id: product.id,
product_name: product.name,
price: product.price,
category: product.category,
});
};
const handleViewDetails = () => {
trackEvent('view_product_details', {
product_id: product.id,
});
};
return (
{product.name}
);
}
`#### Example - Form Tracking
`tsx
import { useEvent } from '@pulsora/react';function ContactForm() {
const trackEvent = useEvent();
const handleSubmit = (e) => {
e.preventDefault();
trackEvent('form_submit', {
form_id: 'contact',
fields: ['name', 'email', 'message'],
});
// Submit form...
};
const handleFieldFocus = (field) => {
trackEvent('form_field_focus', { field });
};
return (
);
}
`$3
Identify users and manage identification state.
#### Returns
`typescript
interface UseIdentifyReturn {
identify: (customerId: string) => Promise;
isIdentified: boolean;
reset: () => void;
}
`#### Example - User Login
`tsx
import { useIdentify } from '@pulsora/react';function LoginForm() {
const { identify, isIdentified } = useIdentify();
const handleLogin = async (email, password) => {
// Perform login logic...
const user = await api.login(email, password);
// Identify user for analytics
await identify(user.id);
};
return (
{isIdentified ? (
Welcome back!
) : (
)}
);
}
`#### Example - User Logout
`tsx
import { useIdentify } from '@pulsora/react';function LogoutButton() {
const { reset } = useIdentify();
const handleLogout = () => {
// Perform logout logic...
api.logout();
// Reset analytics identification
reset();
};
return ;
}
`#### Example - Auto-identify from Auth Context
`tsx
import { useEffect } from 'react';
import { useAuth } from './auth-context';
import { useIdentify } from '@pulsora/react';function AutoIdentify() {
const { user } = useAuth();
const { identify, isIdentified } = useIdentify();
useEffect(() => {
if (user && !isIdentified) {
identify(user.id);
}
}, [user, isIdentified, identify]);
return null;
}
// Use in your app:
function App() {
return (
);
}
`Complete Examples
$3
`tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { PulsoraProvider, usePageview, useEvent } from '@pulsora/react';function Home() {
usePageview();
const trackEvent = useEvent();
return (
Welcome
);
}function App() {
return (
);
}
ReactDOM.createRoot(document.getElementById('root')!).render( );
`$3
`tsx
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
import { PulsoraProvider, usePageview, useEvent } from '@pulsora/react';function Analytics() {
const location = useLocation();
usePageview({ trigger: location.pathname });
return null;
}
function App() {
return (
} />
} />
} />
);
}
`$3
`tsx
// app/providers.tsx
'use client';import { PulsoraProvider } from '@pulsora/react';
import { usePathname } from 'next/navigation';
import { usePageview } from '@pulsora/react';
import { useEffect } from 'react';
function PageviewTracker() {
const pathname = usePathname();
usePageview({ trigger: pathname });
return null;
}
export function Providers({ children }: { children: React.ReactNode }) {
return (
config={{
apiToken: process.env.NEXT_PUBLIC_PULSORA_TOKEN!,
}}
>
{children}
);
}
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return (
{children}
);
}
`TypeScript Support
Full TypeScript support with exported types:
`tsx
import type {
PulsoraConfig,
PulsoraCore,
EventData,
UsePageviewOptions,
TrackEventFunction,
UseIdentifyReturn,
} from '@pulsora/react';
`SSR Compatibility
The package is safe for server-side rendering. The Pulsora instance will only initialize in the browser.
Testing
Each package has its own test suite. Run tests from the package directory:
`bash
cd pulsora-packages/react
npm test
`Bundle Size
- ESM: ~2KB (uncompressed, excluding peer deps)
- Gzipped: ~800 bytes (excluding peer deps)
Peer dependencies (
@pulsora/core and react) are not included in the bundle.Best Practices
$3
Only use one
at the root of your app:`tsx
// ✅ Good
// ❌ Bad - don't nest providers
`$3
For SPAs, use
usePageview with a trigger at the router level, not in individual pages:`tsx
// ✅ Good - track at router level
function App() {
const location = useLocation();
usePageview({ trigger: location.pathname }); return ... ;
}
// ❌ Inefficient - tracking in each page
function Page1() {
usePageview(); // Don't do this in every page
return
Page 1;
}
`$3
Use clear, consistent event names:
`tsx
// ✅ Good
trackEvent('button_click', { button_id: 'cta' });
trackEvent('form_submit', { form_id: 'contact' });
trackEvent('add_to_cart', { product_id: 123 });// ❌ Bad - vague names
trackEvent('click');
trackEvent('action');
`$3
Identify users as soon as they log in:
`tsx
function LoginPage() {
const { identify } = useIdentify(); const handleLogin = async (credentials) => {
const user = await api.login(credentials);
await identify(user.id); // Identify immediately
};
return ;
}
`Troubleshooting
$3
If you see
usePulsora must be used within a PulsoraProvider, make sure:1. You have
wrapping your app
2. The hook is called inside a component that's a child of the provider$3
If pageviews aren't being tracked:
1. Check that
autoPageviews is not disabled in config
2. If using usePageview with a trigger, verify the trigger value changes
3. Check browser console for errors (enable debug: true)$3
If you get TypeScript errors about missing types:
`bash
npm install --save-dev @types/react
``MIT
- Documentation: https://pulsora.co/docs
- Issues: https://github.com/pulsora/pulsora/issues
- Email: support@pulsora.co