openpanel
openpanel copied to clipboard
Adding @openpanel/react sdk + docs
OpenPanel React Provider
A React context provider for OpenPanel analytics built on @openpanel/sdk.
This follows the same architecture as the official React Native SDK and is designed to be contributed back to the OpenPanel project.
Inspiration
We needed this component for https://startupkit.com, as we're bundling both Posthog and OpenPanel by default with new client installations.
Installation
npm install @openpanel/react
# or
pnpm add @openpanel/react
# or
yarn add @openpanel/react
Peer Dependencies:
This package requires React 18+ or React 19+:
{
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
}
}
Usage
Basic Setup (Next.js App Router)
Wrap your app with the OpenPanelProvider in your root layout:
// app/layout.tsx
import { OpenPanelProvider } from '@openpanel/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<OpenPanelProvider clientId="your-client-id">
{children}
</OpenPanelProvider>
</body>
</html>
);
}
Basic Setup (Next.js Pages Router)
// pages/_app.tsx
import { OpenPanelProvider } from '@openpanel/react';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<OpenPanelProvider clientId="your-client-id">
<Component {...pageProps} />
</OpenPanelProvider>
);
}
Using Environment Variables
The provider automatically reads from environment variables if no clientId prop is provided:
<OpenPanelProvider>
{children}
</OpenPanelProvider>
It will check for (in order):
NEXT_PUBLIC_OPENPANEL_CLIENT_ID(Next.js client-side)OPENPANEL_CLIENT_ID(server-side or other environments)
Example .env.local:
NEXT_PUBLIC_OPENPANEL_CLIENT_ID=your_client_id_here
Configuration Options
The provider accepts all options from OpenPanelOptions:
<OpenPanelProvider
clientId="your-client-id"
trackScreenViews={false}
trackOutgoingLinks={true}
trackAttributes={true}
apiUrl="https://api.openpanel.dev"
// ... any other OpenPanelOptions
>
{children}
</OpenPanelProvider>
Using the Hook
Access the OpenPanel client in any component using the useOpenPanel() hook:
'use client';
import { useOpenPanel } from '@openpanel/react';
export function SubscribeButton() {
const openpanel = useOpenPanel();
const handleClick = () => {
openpanel?.track('button_clicked', {
button_name: 'subscribe',
page: 'homepage'
});
};
return <button onClick={handleClick}>Subscribe</button>;
}
API Methods
The hook returns the OpenPanel client instance with all SDK methods:
Track Events
const openpanel = useOpenPanel();
// Track a simple event
openpanel?.track('button_clicked');
// Track with properties
openpanel?.track('purchase', {
product_id: 'prod-123',
amount: 99.99,
currency: 'USD'
});
Identify Users
// Identify a user
openpanel?.identify({
profileId: 'user-123',
email: '[email protected]',
name: 'John Doe',
// ... any custom properties
});
Set Properties
// Set profile properties
openpanel?.setProfile({
plan: 'premium',
company: 'Acme Inc'
});
// Increment a property
openpanel?.increment('page_views', 1);
// Decrement a property
openpanel?.decrement('credits', 5);
Clear/Reset
// Clear the current user (logout)
openpanel?.clear();
TypeScript Support
All types from @openpanel/sdk are re-exported for your convenience:
import {
OpenPanelProvider,
useOpenPanel,
type OpenPanelOptions,
type TrackProperties
} from '@openpanel/react';
// Typed event tracking
const properties: TrackProperties = {
product_id: 'prod-123',
amount: 99.99
};
openpanel?.track('purchase', properties);
Server-Side Rendering (SSR)
The provider is client-side only ('use client' directive) and safely handles SSR environments:
- ✅ Works with Next.js App Router and Pages Router
- ✅ OpenPanel client only initializes in the browser (
typeof window !== 'undefined') - ✅ No hydration errors
- ✅ Safe to use in Server Components (wrap client components that use the hook)
Example with Server Component:
// app/page.tsx (Server Component)
import { AnalyticsButton } from './analytics-button';
export default function Page() {
return (
<div>
<h1>My Page</h1>
<AnalyticsButton />
</div>
);
}
// app/analytics-button.tsx (Client Component)
'use client';
import { useOpenPanel } from '@openpanel/react';
export function AnalyticsButton() {
const openpanel = useOpenPanel();
return (
<button onClick={() => openpanel?.track('button_click')}>
Click Me
</button>
);
}
Advanced Usage
Custom Client Instance
You can extend the OpenPanel class for custom behavior:
import { OpenPanel as OpenPanelBase, type OpenPanelOptions } from '@openpanel/react';
class CustomOpenPanel extends OpenPanelBase {
constructor(options: OpenPanelOptions) {
super(options);
// Add custom initialization
this.track('app_initialized');
}
// Add custom methods
trackPageView(pageName: string) {
this.track('page_view', { page: pageName });
}
}
Error Handling
The useOpenPanel() hook throws an error if used outside the provider:
try {
const openpanel = useOpenPanel();
} catch (error) {
console.error('OpenPanel not available:', error);
}
Always ensure components using the hook are wrapped in <OpenPanelProvider>.
Summary by CodeRabbit
-
New Features
- Released official React SDK with provider-based integration pattern and hooks support for seamless event tracking and user identification.
-
Documentation
- Added comprehensive React SDK documentation covering installation, usage patterns, environment configuration, and TypeScript support.
@ian is attempting to deploy a commit to the Coderax's projects Team on Vercel.
A member of the Team first needs to authorize it.
Walkthrough
A new React SDK package is introduced with a provider-based architecture, TypeScript configuration, build tooling, and comprehensive documentation. The implementation includes React context, custom hooks, and a provider component for client-side initialization using environment variables or explicit configuration.
Changes
| Cohort / File(s) | Summary |
|---|---|
React SDK Core Implementation packages/sdks/react/index.tsx |
Introduces OpenPanel class extending OpenPanelBase with React defaults (sdk: 'react', sdkVersion: '19.0.0'), useOpenPanel hook for accessing context-bound instance, and OpenPanelProvider component for lazy client-side initialization with environment variable support. Re-exports all base SDK exports. |
Build & Package Configuration packages/sdks/react/package.json, packages/sdks/react/tsconfig.json, packages/sdks/react/tsup.config.ts |
Adds package metadata, TypeScript configuration, and tsup build setup for the React SDK. Declares @openpanel/sdk dependency, React/React-DOM peer dependencies (16.8–19.x), and build output targeting CommonJS and ESM formats with declaration generation. |
React SDK Documentation apps/public/content/docs/sdks/react.mdx |
Expands minimal React doc stub into comprehensive guide covering About, Installation, Usage patterns (Client Components, Tracking Events, User Identification, Property Types, SSR), Environment Variables, Advanced Usage, and TypeScript support with code examples. |
Sequence Diagram
sequenceDiagram
participant App as React App
participant Provider as OpenPanelProvider
participant Ctx as OpenPanel Context
participant Hook as useOpenPanel Hook
participant Client as OpenPanel Instance
Note over Provider: Component mounts (client-side only)
Provider->>Provider: Read clientId or env vars
Provider->>Client: Lazy initialize OpenPanel
Provider->>Ctx: Store instance in context
App->>Hook: Call useOpenPanel()
Hook->>Ctx: Access context value
Ctx-->>Hook: Return OpenPanel instance
Hook-->>App: Provide instance for use
Note over App,Client: Consumer can track events, identify users, etc.
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~22 minutes
- packages/sdks/react/index.tsx: Review React context/provider pattern implementation, hook error handling, lazy initialization logic, and environment variable precedence
- Documentation expansion: Verify accuracy of code examples, completeness of usage patterns, and consistency with SDK behavior
- Configuration files: Standard setup but verify dependency versions, tsup build output targets, and TypeScript configuration alignment with workspace
Poem
🐰 A React SDK hops into view, With hooks and providers brand new! Context flows through your component tree, Tracking events with providers so free. Environment whispers guide the way— OpenPanel thrives in React today! 🎉
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title Check | ✅ Passed | The PR title "Adding @openpanel/react sdk + docs" accurately and concisely captures the main changes introduced in this pull request. The changeset implements a new React SDK package (@openpanel/react) with a provider pattern, hooks, and comprehensive MDX documentation, all of which are clearly reflected in the title. The title is specific, uses clear language, avoids vague terms, and would allow developers scanning git history to immediately understand the primary purpose of the changes. |
| Docstring Coverage | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.