React SDK
@shellapps/experience-react — React-specific SDK with providers, hooks, and components.
Installation
npm install @shellapps/experience @shellapps/experience-reactSetup
Wrap your app with ExperienceProvider, ErrorBoundary, and optionally FeedbackButton:
import {
ExperienceProvider,
useTrack,
useFlag,
useTranslation,
ErrorBoundary,
FeedbackButton,
} from '@shellapps/experience-react';
function App() {
return (
<ExperienceProvider
appId="my-app"
apiKey="exp_xxxxxxxxxxxx"
profileId={user.activeProfileId}
options={{
enableHeatmaps: true,
sampleRate: 0.5, // 50% of sessions tracked (high-traffic app)
}}
>
<ErrorBoundary
fallback={<CrashPage />} // optional custom fallback
showCommentForm={true} // default true
onError={(error) => console.log(error)}
>
<MainApp />
</ErrorBoundary>
<FeedbackButton position="bottom-right" />
</ExperienceProvider>
);
}Hooks
useTrack
function CheckoutPage() {
const { track } = useTrack();
return (
<Button
trackingId="checkout-submit"
onClick={() => {
track('checkout_completed', { value: total });
submitOrder();
}}
>
Complete Purchase
</Button>
);
}See Event Tracking for the data-t system and batching details.
useFlag
const showNewCheckout = useFlag('new-checkout-ui', false);
const checkoutLimit = useFlag('checkout-limit', 100);
{showNewCheckout ? <NewCheckout /> : <OldCheckout />}See Feature Flags for rule evaluation, rollouts, and experiments.
useTranslation
const { t, locale, setLocale, locales } = useTranslation();
<h1>{t('checkout.title')}</h1>
<p>{t('checkout.item_count', { count: 3 })}</p>
{/* Language switcher */}
<select value={locale} onChange={e => setLocale(e.target.value)}>
{locales.map(l => (
<option key={l.code} value={l.code}>{l.name}</option>
))}
</select>How it works:
- On mount, fetches translations for current locale from Experience API
- Caches in memory + localStorage (offline support)
t(key, params?)looks up key, replaces{{param}}interpolationssetLocale(code)fetches new locale, updates all rendered strings- Falls back to source language if a translation is missing
See Translations for the full translation management system.
Components
<ErrorBoundary>
Catches React render errors and displays a crash UI with optional user comment form.
<ErrorBoundary
fallback={<CrashPage />}
showCommentForm={true}
onError={(error) => console.log(error)}
>
<App />
</ErrorBoundary>- Rendered by the SDK (works even when React is broken)
- Falls back to native browser
prompt()if crash UI itself fails - Styled with inline styles (no CSS dependency)
- Customisable fallback component
See Error Monitoring for the full crash flow.
<FeedbackButton>
Floating feedback widget for users to submit bugs, feature requests, comments, and praise.
<FeedbackButton position="bottom-right" />See User Feedback for the full feedback system.
Design System Integration
All interactive @shellapps/react-ui components accept a trackingId prop:
<Button trackingId="checkout-submit" variant="primary">
Complete Purchase
</Button>
// Renders: <button data-t="checkout-submit" ...>Complete Purchase</button>Also see the Vanilla JS SDK for non-React usage.