React Examples
Use these recipes to wire Pulsora into production-ready React apps.
Global Provider + Hooks
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { PulsoraProvider } from '@pulsora/react';
import { App } from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<PulsoraProvider config={{ apiToken: import.meta.env.VITE_PULSORA_TOKEN }}>
<App />
</PulsoraProvider>
</React.StrictMode>,
);
// src/App.tsx
import { Routes, Route, useLocation } from 'react-router-dom';
import { useEvent, usePageview } from '@pulsora/react';
function AnalyticsBridge() {
const location = useLocation();
usePageview({ trigger: location.pathname });
return null;
}
function Pricing() {
const trackEvent = useEvent();
return (
<button onClick={() => trackEvent('cta_click', { plan: 'pro' })}>
Get Started
</button>
);
}
export function App() {
return (
<>
<AnalyticsBridge />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/pricing" element={<Pricing />} />
</Routes>
</>
);
}
Capturing Checkout Metadata
import { useEvent, usePulsora } from '@pulsora/react';
function CheckoutButton({ priceId }: { priceId: string }) {
const trackEvent = useEvent();
const pulsora = usePulsora();
const handleCheckout = async () => {
const fingerprint = await pulsora?.getVisitorFingerprint();
const sessionId = pulsora?.getSessionId();
await fetch('/api/checkout/session', {
method: 'POST',
body: JSON.stringify({
priceId,
visitor_fingerprint: fingerprint,
session_id: sessionId,
}),
});
trackEvent('checkout_start', { priceId });
};
return <button onClick={handleCheckout}>Buy Now</button>;
}
Conditional Event Tracking
import { useEvent } from '@pulsora/react';
function TrialSignupForm() {
const trackEvent = useEvent();
const [email, setEmail] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// Only track valid submissions
if (email.includes('@')) {
await trackEvent('trial_signup', { email_domain: email.split('@')[1] });
}
// ...submit to backend
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<input
className="input"
placeholder="Work email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button className="btn btn-primary" type="submit">
Start trial
</button>
</form>
);
}
Next.js Layout Pattern
// app/layout.tsx
import './globals.css';
import { Providers } from './providers';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
See the SSR guide for the full implementation.
Need deeper explanations? Head back to the hooks reference →