@probat/react
v0.1.5
Published
React library for Probat A/B testing and experimentation
Readme
@probat/react
React library for Probat A/B testing and experimentation. This package provides a clean, reusable way to integrate Probat into your React applications without copying entire files into your repository.
Installation
npm install @probat/react
# or
yarn add @probat/react
# or
pnpm add @probat/reactQuick Start
1. Wrap your app with ProbatProvider
import { ProbatProvider } from '@probat/react';
function App() {
return (
<ProbatProvider clientKey="your-client-key" environment="dev">
<YourApp />
</ProbatProvider>
);
}2. Use experiments in your components
Option A: Using the useExperiment hook
import { useExperiment } from '@probat/react';
function MyComponent() {
const { variantLabel, isLoading, trackClick } = useExperiment('proposal-id');
if (isLoading) return <div>Loading...</div>;
return (
<div onClick={trackClick}>
{variantLabel === 'control' ? (
<ControlVariant />
) : (
<ExperimentVariant />
)}
</div>
);
}Option B: Using the withExperiment HOC (backward compatible)
import { withExperiment } from '@probat/react';
const ControlComponent = () => <div>Control</div>;
const VariantA = () => <div>Variant A</div>;
const VariantB = () => <div>Variant B</div>;
const ExperimentedComponent = withExperiment(ControlComponent, {
proposalId: 'proposal-id',
registry: {
'variant-a': VariantA,
'variant-b': VariantB,
},
});3. Track metrics
import { useProbatMetrics } from '@probat/react';
function Button() {
const { trackClick, trackMetric } = useProbatMetrics();
return (
<button
onClick={(e) => {
trackClick(e, {
proposalId: 'proposal-id',
variantLabel: 'control',
});
}}
>
Click me
</button>
);
}API Reference
<ProbatProvider>
Wraps your app and provides Probat configuration to all child components.
Props
apiBaseUrl?: string- The base URL for the Probat API. If not provided, will try to read from:VITE_PROBAT_API(Vite)NEXT_PUBLIC_PROBAT_API(Next.js)window.__PROBAT_API- Default:
"https://gushi.onrender.com"
clientKey?: string- Client key for identification (optional)environment?: "dev" | "prod"- Explicitly set environment. If not provided, will auto-detect based on hostname.children: React.ReactNode- Your app components
Example
<ProbatProvider
apiBaseUrl="https://api.probat.com"
clientKey="your-key"
environment="prod"
>
<App />
</ProbatProvider>useExperiment(proposalId, options?)
Hook for fetching and applying experiment variants.
Parameters
proposalId: string- The proposal ID for the experimentoptions?: { autoTrackImpression?: boolean }- Optional configurationautoTrackImpression- Automatically track impression when variant is loaded (default:true)
Returns
variantLabel: string- The current variant label (e.g., "control", "variant-a")experimentId: string | null- The experiment IDisLoading: boolean- Whether the experiment decision is still loadingerror: Error | null- Any error that occurred while fetching the experimenttrackClick: (event?: React.MouseEvent | null) => void- Manually track a click for this experiment
Example
const { variantLabel, isLoading, trackClick } = useExperiment('proposal-id', {
autoTrackImpression: true,
});useProbatMetrics()
Hook for tracking Probat metrics (clicks, impressions, custom metrics).
Returns
trackClick(event?, options?)- Track a click eventevent?: React.MouseEvent- Optional React mouse event (will extract metadata automatically)options?: { force?: boolean; proposalId?: string; variantLabel?: string; dimensions?: Record<string, any> }
trackMetric(metricName, proposalId, variantLabel?, dimensions?)- Track a custom metrictrackImpression(proposalId, variantLabel?, experimentId?)- Track an impression/view
Example
const { trackClick, trackMetric, trackImpression } = useProbatMetrics();
// Track click
<button onClick={(e) => trackClick(e, { proposalId: 'id', variantLabel: 'control' })}>
Click
</button>
// Track custom metric
trackMetric('purchase', 'proposal-id', 'variant-a', { amount: 100 });
// Track impression
trackImpression('proposal-id', 'control', 'experiment-id');withExperiment(Control, options)
Higher-Order Component for wrapping components with experiment variants (backward compatible with old injection pattern).
Parameters
Control: React.ComponentType- The control/default componentoptions: { proposalId: string; registry: Record<string, React.ComponentType> }proposalId- The proposal IDregistry- Map of variant labels to component types
Returns
A wrapped component that automatically selects and renders the correct variant.
Example
const ExperimentedComponent = withExperiment(ControlComponent, {
proposalId: 'proposal-id',
registry: {
'variant-a': VariantA,
'variant-b': VariantB,
},
});Environment Detection
The library automatically detects whether you're running in development or production based on the hostname:
- Development:
localhost,127.0.0.1, or local IP addresses (192.168.x.x, 10.x.x.x, 172.16-31.x.x) - Production: Everything else
You can override this by passing the environment prop to ProbatProvider.
Configuration
Environment Variables
You can configure the API base URL using environment variables:
- Vite:
VITE_PROBAT_API=https://api.probat.com - Next.js:
NEXT_PUBLIC_PROBAT_API=https://api.probat.com - Browser:
window.__PROBAT_API = 'https://api.probat.com'
TypeScript
The package includes TypeScript definitions. No additional @types package needed.
Testing Locally
Build the package:
cd packages/probat-react npm run buildLink it locally (optional, for testing in other projects):
npm linkIn your test project:
npm link @probat/react
Migration from Injected Files
If you're currently using the injected file pattern, you can migrate gradually:
- Install the package:
npm install @probat/react - Wrap your app with
<ProbatProvider> - Replace
withExperimentimports:// Old import { withExperiment } from '../../probat/runtime'; // New import { withExperiment } from '@probat/react'; - Remove the
probat/directory from your repo - Update your component exports to use the new import
Next.js Support
The package is fully compatible with Next.js 13+ App Router and Pages Router. See NEXTJS_GUIDE.md for detailed Next.js integration instructions.
Quick Next.js Example
// app/layout.tsx (App Router)
import { ProbatProvider } from '@probat/react';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ProbatProvider clientKey="..." environment="dev">
{children}
</ProbatProvider>
</body>
</html>
);
}License
MIT
