React
Good to know
Keep in mind that all tracking here happens on the client!
For React SPAs, you can use @openpanel/web directly - no need for a separate React SDK. Simply create an OpenPanel instance and use it throughout your application.
Installation
Step 1: Install
npm install @openpanel/webStep 2: Initialize
Create a shared OpenPanel instance in your project:
import { OpenPanel } from '@openpanel/web';
export const op = new OpenPanel({
clientId: 'YOUR_CLIENT_ID',
trackScreenViews: true,
trackOutgoingLinks: true,
trackAttributes: true,
});Options
Common options
apiUrl- The url of the openpanel API or your self-hosted instanceclientId- The client id of your applicationclientSecret- The client secret of your application (only required for server-side events)filter- A function that will be called before sending an event. If it returns false, the event will not be sentdisabled- If true, the library will not send any events
Web options
trackScreenViews- If true, the library will automatically track screen views (default: false)trackOutgoingLinks- If true, the library will automatically track outgoing links (default: false)trackAttributes- If true, you can trigger events by using html attributes (<button type="button" data-track="your_event" />) (default: false)
clientId- Your OpenPanel client ID (required)apiUrl- The API URL to send events to (default:https://api.openpanel.dev)trackScreenViews- Automatically track screen views (default:true)trackOutgoingLinks- Automatically track outgoing links (default:true)trackAttributes- Automatically track elements withdata-trackattributes (default:true)trackHashChanges- Track hash changes in URL (default:false)disabled- Disable tracking (default:false)
Step 3: Usage
Import and use the instance in your React components:
import { op } from '@/openpanel';
function MyComponent() {
const handleClick = () => {
op.track('button_click', { button: 'signup' });
};
return <button onClick={handleClick}>Trigger event</button>;
}Usage
Tracking Events
You can track events with two different methods: by calling the op.track() method directly or by adding data-track attributes to your HTML elements.
import { op } from '@/openpanel';
function MyComponent() {
useEffect(() => {
op.track('my_event', { foo: 'bar' });
}, []);
return <div>My Component</div>;
}Identifying Users
To identify a user, call the op.identify() method with a unique identifier.
import { op } from '@/openpanel';
function LoginComponent() {
const handleLogin = (user: User) => {
op.identify({
profileId: user.id, // Required
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
properties: {
tier: 'premium',
},
});
};
return <button onClick={() => handleLogin(user)}>Login</button>;
}Setting Global Properties
To set properties that will be sent with every event:
import { op } from '@/openpanel';
function App() {
useEffect(() => {
op.setGlobalProperties({
app_version: '1.0.2',
environment: 'production',
});
}, []);
return <div>App</div>;
}Incrementing Properties
To increment a numeric property on a user profile.
valueis the amount to increment the property by. If not provided, the property will be incremented by 1.
import { op } from '@/openpanel';
function MyComponent() {
const handleAction = () => {
op.increment({
profileId: '1',
property: 'visits',
value: 1, // optional
});
};
return <button onClick={handleAction}>Increment</button>;
}Decrementing Properties
To decrement a numeric property on a user profile.
valueis the amount to decrement the property by. If not provided, the property will be decremented by 1.
import { op } from '@/openpanel';
function MyComponent() {
const handleAction = () => {
op.decrement({
profileId: '1',
property: 'visits',
value: 1, // optional
});
};
return <button onClick={handleAction}>Decrement</button>;
}Clearing User Data
To clear the current user's data:
import { op } from '@/openpanel';
function LogoutComponent() {
const handleLogout = () => {
op.clear();
// ... logout logic
};
return <button onClick={handleLogout}>Logout</button>;
}Revenue Tracking
Track revenue events:
import { op } from '@/openpanel';
function CheckoutComponent() {
const handlePurchase = async () => {
// Track revenue immediately
await op.revenue(29.99, { currency: 'USD' });
// Or accumulate revenue and flush later
op.pendingRevenue(29.99, { currency: 'USD' });
op.pendingRevenue(19.99, { currency: 'USD' });
await op.flushRevenue(); // Sends both revenue events
// Clear pending revenue
op.clearRevenue();
};
return <button onClick={handlePurchase}>Purchase</button>;
}Optional: Create a Hook
If you prefer using a React hook pattern, you can create your own wrapper:
import { op } from '@/openpanel';
export function useOpenPanel() {
return op;
}Then use it in your components:
import { useOpenPanel } from '@/hooks/useOpenPanel';
function MyComponent() {
const op = useOpenPanel();
useEffect(() => {
op.track('my_event', { foo: 'bar' });
}, []);
return <div>My Component</div>;
}