React Integration
The React integration provides a provider, hooks, and drop-in components for placement rendering and entitlement checks.
RevTurbineProvider
Section titled “RevTurbineProvider”Wrap your app (or a subtree) with the provider:
import { RevTurbineProvider } from '@revturbine/sdk';import exportedConfig from './exported_config.json';import { useMemo } from 'react';
export default function App() { const options = useMemo(() => ({ localRuntime: { exportedConfig }, user: { id: 'user_123', context: { plan_handle: 'starter' }, }, }), []);
return ( <RevTurbineProvider options={options}> <Dashboard /> </RevTurbineProvider> );}| Prop | Type | Description |
|---|---|---|
options | RevTurbineInitOptions | SDK initialization options (see Configuration Reference) |
bootstrapPlacements | BootstrapPlacementInput[] | Placements to preload on mount |
children | ReactNode | Your app |
Bootstrap Placements
Section titled “Bootstrap Placements”Preload placement decisions during initialization to eliminate loading flicker:
<RevTurbineProvider options={options} bootstrapPlacements={[ { placement: { name: 'hero_banner' }, userId: 'user_123' }, { placement: { name: 'nav_cta' }, userId: 'user_123' }, ]}>useRevTurbine
Section titled “useRevTurbine”Access the SDK instance and provider state:
import { useRevTurbine } from '@revturbine/sdk';
function StatusBar() { const { sdk, isReady, error, setContext } = useRevTurbine();
if (!isReady) return <span>Loading SDK…</span>; if (error) return <span>SDK error: {error}</span>;
return <span>SDK ready</span>;}Returns:
| Field | Type | Description |
|---|---|---|
sdk | RevTurbineCustomerSdk | null | SDK instance (null until ready) |
isReady | boolean | Whether the SDK has initialized |
error | string | Error message if initialization failed |
setContext | (ctx: RevTurbineUserContext) => void | Update user context dynamically |
usePlacement
Section titled “usePlacement”Resolve a placement for a surface slot:
import { usePlacement } from '@revturbine/sdk';
function UpgradeBanner() { const { visible, content, isLoading, dismiss, ctaClick, } = usePlacement({ surfaceSlot: { id: 'dashboard_banner', surfaceTemplateIds: ['banner_placement'] }, });
if (!visible) return null;
return ( <div> <h3>{content?.header}</h3> <p>{content?.body}</p> <button onClick={() => ctaClick()}>{content?.cta_label}</button> <button onClick={() => dismiss()}>✕</button> </div> );}Options:
| Field | Type | Default | Description |
|---|---|---|---|
surfaceSlot | RevTurbineSurfaceSlotConfig | — | Slot configuration (id, surfaceTemplateIds) |
userId | string | — | Override user ID |
contextMode | 'auto' | 'override' | 'auto' | Context resolution mode |
traits | Record<string, string | number | boolean> | — | Additional targeting traits |
ttlMs | number | 300000 | Cache TTL in milliseconds |
autoLoad | boolean | true | Load placement on mount |
Returns:
| Field | Type | Description |
|---|---|---|
isLoading | boolean | Whether the placement is being resolved |
error | string | Error message if resolution failed |
visible | boolean | Whether the placement should be shown |
decision | RevTurbinePlacementDecision | null | Full decision object |
content | object | null | Resolved content (header, body, cta_label, etc.) |
refresh | () => Promise<void> | Re-resolve the placement |
dismiss | (cooldownMs?) => Promise<void> | Dismiss and suppress |
snooze | (seconds?) => Promise<void> | Temporarily suppress |
remindMeLater | (seconds?) => Promise<void> | Alias for snooze |
ctaClick | (target?) => Promise<void> | Record CTA click |
ctaComplete | (target?) => Promise<void> | Record CTA completion |
useEntitlement
Section titled “useEntitlement”Check whether a user has access to a feature:
import { useEntitlement } from '@revturbine/sdk';
function ExportButton() { const { allowed, denied, gatedPlacement, recheck } = useEntitlement({ handle: 'data_export', autoGate: true, // auto-resolve upgrade placement if denied });
if (denied && gatedPlacement) { return <UpgradePrompt placement={gatedPlacement} />; }
return <button disabled={!allowed}>Export Video</button>;}Options:
| Field | Type | Default | Description |
|---|---|---|---|
handle | string | — | Entitlement handle (required) |
autoCheck | boolean | true | Check on mount |
autoGate | boolean | false | Auto-resolve gated placement if denied |
gatePlacementRequest | object | — | Placement config for the gate |
Returns:
| Field | Type | Description |
|---|---|---|
isLoading | boolean | Whether the check is in progress |
error | string | null | Error message |
result | EntitlementResult | null | Full result |
allowed | boolean | Access granted |
limited | boolean | Approaching limit |
denied | boolean | Access denied |
gatedPlacement | PlacementOutput | null | Upgrade placement (if autoGate: true) |
recheck | () => Promise<void> | Re-check entitlement |
useUsageSnapshot
Section titled “useUsageSnapshot”Get current usage balances:
import { useUsageSnapshot } from '@revturbine/sdk';
function UsagePanel() { const { usage, refresh } = useUsageSnapshot();
return ( <div> <p>API calls: {usage.api_calls?.current} / {usage.api_calls?.limit}</p> <button onClick={refresh}>Refresh</button> </div> );}useRevTurbineTheme
Section titled “useRevTurbineTheme”Access the resolved theme:
import { useRevTurbineTheme } from '@revturbine/sdk';
function ThemedCard({ children }) { const theme = useRevTurbineTheme();
return ( <div style={{ background: theme.colors.surface, borderRadius: theme.shape.borderRadius, color: theme.colors.text, }}> {children} </div> );}Drop-In Components
Section titled “Drop-In Components”For the simplest integration, use <Slot> — it resolves the placement and renders the matching built-in slot:
import { Slot } from '@revturbine/sdk';
// Banner<Slot id="hero_banner" surfaceType="banner" />
// Modal gate<Slot id="export_gate" surfaceType="modal" />
// Inline card<Slot id="pricing_card" surfaceType="in_page" />See the Component Gallery for interactive demos of every built-in slot component.
Dynamic Context Updates
Section titled “Dynamic Context Updates”Update the user context after login, plan change, or navigation:
const { setContext } = useRevTurbine();
// After loginsetContext({ id: user.id, plan: { id: user.planId }, traits: { role: user.role },});All active placements and entitlement checks re-evaluate automatically when context changes.
Next Steps
Section titled “Next Steps”- Entitlements Guide — feature gates, usage limits, and credits
- Placements Guide — slot-based and entitlement-based patterns
- Theming Guide — customize slot component appearance
- Interactive Playground — try live editable SDK scenarios