@truxl/react-native-sdk
v0.2.0
Published
Truxl analytics SDK for React Native
Maintainers
Readme
@truxl/react-native-sdk
Truxl analytics SDK for React Native. Works with both Expo and bare React Native projects.
Installation
npm install @truxl/react-native-sdk @react-native-async-storage/async-storageAsyncStorage is a required peer dependency. If you are using Expo, it is included by default.
Optional dependencies
Install these for enhanced functionality:
# Device model detection
npm install react-native-device-info
# Network-aware event delivery
npm install @react-native-community/netinfo
# React Navigation screen tracking
npm install @react-navigation/nativeQuick Start
import { TruxlClient } from '@truxl/react-native-sdk';
import AsyncStorage from '@react-native-async-storage/async-storage';
const client = await TruxlClient.init({
projectToken: 'your-project-token',
clientSecret: 'your-client-secret',
apiEndpoint: 'https://ingestion.api.truxl.com',
// Inject native modules statically — Metro/Expo-Go safe.
// See "Injecting native modules" below for the why.
modules: { asyncStorage: AsyncStorage },
});
// Track an event
client.track('button_click', { label: 'Buy Now' });
// Identify a user
client.identify('user-123', { email: '[email protected]', plan: 'pro' });
// Flush events immediately
client.flush();
// Reset identity on logout
client.reset();Staging: The SDK defaults to
https://ingestion.api.truxl.com(production). For staging, setapiEndpointtohttps://ingestion.api.stage.truxl.com.
Injecting native modules (Metro / Expo Go safe)
React Native's bundler (Metro) only resolves dependencies it can see in your app's own code at bundle time. SDKs that try to require() native deps at runtime can fail in Expo Go or under custom Metro configs with Requiring unknown module ....
The clean fix: import each native module in your app and pass it to init({ modules }). The SDK uses whatever you inject and never tries to load it itself.
import { TruxlClient } from '@truxl/react-native-sdk';
import AsyncStorage from '@react-native-async-storage/async-storage';
import NetInfo from '@react-native-community/netinfo'; // optional
import DeviceInfo from 'react-native-device-info'; // optional
const client = await TruxlClient.init({
projectToken: '...',
clientSecret: '...',
apiEndpoint: '...',
modules: {
asyncStorage: AsyncStorage, // required
netInfo: NetInfo, // optional — enables offline-aware sends
deviceInfo: DeviceInfo, // optional — enriches events with device model/type
},
});If a module is not injected, the SDK falls back to a literal require() (for back-compat). That fallback works in standard React Native projects, but injection is recommended for Expo Go, monorepos with hoisted dependencies, or any non-default Metro config.
React Integration
Wrap your app with TruxlProvider and use hooks to access the client:
import { TruxlProvider, useTruxl, useTrackScreen } from '@truxl/react-native-sdk';
function App() {
const [client, setClient] = useState(null);
useEffect(() => {
TruxlClient.init({
projectToken: 'your-project-token',
clientSecret: 'your-client-secret',
apiEndpoint: 'https://ingestion.api.truxl.com',
}).then(setClient);
}, []);
if (!client) return null;
return (
<TruxlProvider client={client}>
<Navigation />
</TruxlProvider>
);
}
function ProductScreen() {
useTrackScreen('ProductScreen');
const truxl = useTruxl();
return (
<Button onPress={() => truxl.track('add_to_cart', { productId: '123' })}>
Add to Cart
</Button>
);
}Screen Tracking with React Navigation
Wire up automatic screen tracking with React Navigation:
import { createNavigationContainerRef, NavigationContainer } from '@react-navigation/native';
import { createNavigationTracker } from '@truxl/react-native-sdk';
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onStateChange={createNavigationTracker(client, navigationRef)}
>
{/* your navigators */}
</NavigationContainer>
);
}HMAC Signing
HMAC signing is optional and requires a crypto provider since React Native does not include Web Crypto. Pass a cryptoProvider to init():
With react-native-quick-crypto
npm install react-native-quick-cryptoimport QuickCrypto from 'react-native-quick-crypto';
const client = await TruxlClient.init({
projectToken: 'your-project-token',
clientSecret: 'your-client-secret',
apiEndpoint: 'https://ingestion.api.truxl.com',
cryptoProvider: {
async hmacSHA256(data: string, key: string): Promise<string> {
const hmac = QuickCrypto.createHmac('sha256', key);
hmac.update(data);
return hmac.digest('hex');
},
},
});With expo-crypto
npx expo install expo-cryptoimport * as ExpoCrypto from 'expo-crypto';
const client = await TruxlClient.init({
projectToken: 'your-project-token',
clientSecret: 'your-client-secret',
apiEndpoint: 'https://ingestion.api.truxl.com',
cryptoProvider: {
async hmacSHA256(data: string, key: string): Promise<string> {
const digest = await ExpoCrypto.digestStringAsync(
ExpoCrypto.CryptoDigestAlgorithm.SHA256,
key + data,
);
return digest;
},
},
});Configuration
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| projectToken | string | required | Project token from the Truxl dashboard |
| clientSecret | string | required | Client secret for HMAC signing |
| apiEndpoint | string | required | Ingestion API base URL |
| batchSize | number | 20 | Max events per batch request |
| flushInterval | number | 5000 | Auto-flush interval in ms |
| maxQueueSize | number | 10000 | Max events in the in-memory queue |
| sessionTimeoutMs | number | 1800000 | Session inactivity timeout (30 min) |
| flushOnBackground | boolean | true | Flush when app backgrounds |
| trackAppLifecycle | boolean | false | Auto-track $app_opened / $app_backgrounded |
| useNetInfo | boolean | true | Use NetInfo for connectivity awareness |
| debug | boolean | false | Enable verbose console logging |
| cryptoProvider | CryptoProvider | undefined | HMAC signing provider |
API Reference
TruxlClient.init(config)
Create and initialize a client. Returns a Promise<TruxlClient>.
TruxlClient.getInstance()
Return the singleton instance from the last init() call, or null.
client.track(eventName, properties?)
Track a named event with optional properties.
client.identify(distinctId, traits?)
Associate a user identity with all subsequent events.
client.alias(newId, originalId)
Link an anonymous device ID to a known user ID.
client.reset()
Clear identity and session state (call on logout).
client.flush()
Immediately send all queued events.
client.destroy()
Tear down the client, stop timers, and remove listeners.
<TruxlProvider client={client}>
React context provider.
useTruxl()
Hook to access the client inside a TruxlProvider.
useTrackScreen(screenName, params?)
Hook to track a screen view on mount.
trackScreenView(client, routeName, params?)
Imperative screen view tracking.
createNavigationTracker(client, navigationRef)
Create an onStateChange handler for React Navigation.
License
MIT
