kewa-react-native
v1.0.0
Published
Kewa Mobile SDK for tracking events in mobile app
Maintainers
Readme
kewa-react-native
Package: kewa-react-native v1.0.0
Author: Topchunks Solutions Pvt Ltd
Table of Contents
- Overview
- Requirements
- Installation
- Initialization
- SDK API
- Use Cases
- React Integration
- Auto Tracking
- Automatic Events
- Offline Queue
- Troubleshooting
- License
Overview
Kewa Analytics SDK for React Native enables tracking in mobile apps. It captures user behavior, sends events to your Kewa backend, manages contact identity, and queues events when the device is offline.
Key capabilities:
- Custom and predefined events (
trackEvent, screen views, errors, button presses) - User lifecycle tracking (login, registration, logout, properties)
- Automatic app lifecycle events (
app_launch,app_foreground,app_background) - Offline event queue with automatic retry
- React hooks (
KewaProvider,useKewa,useAutoTracker) - Full TypeScript support
Requirements
| Dependency | Version |
| -------------- | ----------- |
| react | >= 16.8.0 |
| react-native | >= 0.60.0 |
Bundled dependencies (installed automatically with the package):
@react-native-async-storage/async-storage@react-native-community/netinforeact-native-device-info
Platform support:
- Bare / core React Native — fully supported
- Expo development build — supported (
expo prebuild+expo run:ios/expo run:android) - Expo Go — not supported (
react-native-device-inforequires native code)
Installation
1. Install the package
npm install kewa-react-native
# or
yarn add kewa-react-native2. iOS
Native dependencies are linked automatically (React Native 0.60+). Install CocoaPods after adding the package:
cd ios
pod install
cd ..Then build and run:
npx react-native run-ios3. Android
Autolinking handles native modules. Sync Gradle and run:
npx react-native run-androidIf you use a custom Gradle setup, ensure your settings.gradle includes autolinked native modules (default in RN 0.60+).
4. Expo (development build)
npx expo prebuild
npx expo run:ios
# or
npx expo run:androidLocal development
npm install /path/to/kewa-react-nativeThe package runs npm run build automatically via the prepare script.
Initialization
Wrap your app in KewaProvider (recommended) or call Kewa.init() once at startup. Do not use both.
Configuration options
interface KewaConfig {
appUrl: string; // Required — base URL of your Kewa instance
apiKey: string; // Required — sent as `secret` header
projectId?: string; // Required when tracking is enabled
disableTracking?: boolean; // Default: false — master switch; all SDK methods no-op
disableEventTracking?: boolean; // Default: false — blocks trackEvent and wrappers
disableAppStateTracking?: boolean; // Default: false — blocks app_foreground / app_background
disableScreenViewTracking?: boolean; // Default: false — blocks auto screen_view from navigation
batchSize?: number; // Default: 10 (reserved for future batch API)
maxQueueSize?: number; // Default: 100 — max offline queued events
enableDebugLogging?: boolean; // Default: false — log payloads to Metro console
}| Flag | Default | Effect |
| --------------------------- | ------- | ----------------------------------------------------------------------------------- |
| disableTracking | false | Master switch. No network, no listeners, all methods no-op |
| disableEventTracking | false | Blocks events via trackEvent and wrappers (trackLogin, trackScreenView, etc.) |
| disableAppStateTracking | false | Blocks only app_foreground and app_background |
| disableScreenViewTracking | false | Blocks automatic screen_view from React Navigation integration |
disableTracking overrides all other disable flags. Trailing slashes on appUrl are stripped automatically.
Option 1: KewaProvider (recommended)
import React, { useRef } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { KewaProvider, KewaAutoTracker } from 'kewa-react-native';
export default function App() {
const navigationRef = useRef(null);
const { onReady, onStateChange } = KewaAutoTracker.setupNavigationTracking(navigationRef);
return (
<KewaProvider
config={{
appUrl: 'https://your-kewa-instance.com',
projectId: '39r48kjbddkj',
apiKey: 'your-api-key',
enableDebugLogging: __DEV__,
}}
>
<NavigationContainer
ref={navigationRef}
onReady={onReady}
onStateChange={onStateChange}
>
{/* screens */}
</NavigationContainer>
</KewaProvider>
);
}KewaProvider calls init() on mount and cleanup() on unmount.
Option 2: Imperative init
import Kewa from 'kewa-react-native';
await Kewa.init({
appUrl: 'https://your-kewa-instance.com',
projectId: '39r48kjbddkj',
apiKey: 'your-api-key',
maxQueueSize: 100,
enableDebugLogging: __DEV__,
});
// Optional — when tearing down
Kewa.cleanup();On init, the SDK collects device info, sets up app-state listeners, drains the offline queue, and sends app_launch (unless event tracking is disabled).
SDK API
All methods are available on the default Kewa singleton and via useKewa() inside KewaProvider.
init(config: KewaConfig): Promise<void>
Initializes the SDK. See Initialization.
trackEvent(eventName, eventData?, contactData?): Promise<void>
Track any custom event. Every event automatically includes user properties in the contact fields.
await Kewa.trackEvent('product_viewed', {
productId: 'abc123',
category: 'electronics',
price: 299.99,
});
// Attach contact fields to a single event
await Kewa.trackEvent(
'newsletter_signup',
{ source: 'home_banner' },
{ email: '[email protected]', firstname: 'Jane' },
);setUserProperties(properties): Promise<void>
Merges properties into local storage and updates in Kewa Backend automatically. All fields are optional.
await Kewa.setUserProperties({
email: '[email protected]',
firstname: 'Jane',
plan: 'premium',
});trackLogin(userData): Promise<void>
Sends a user_login event. Default loginMethod is 'custom'.
await Kewa.trackLogin({
userId: 'user123',
email: '[email protected]',
loginMethod: 'google', // 'email' | 'google' | 'facebook' | 'apple' | 'phone' | 'custom'
});trackRegistration(userData): Promise<void>
Sends a user_registration event. Default registrationMethod is 'email'.
await Kewa.trackRegistration({
userId: 'user123',
email: '[email protected]',
registrationMethod: 'google', // 'email' | 'google' | 'facebook' | 'apple' | 'phone'
});trackLogout(): Promise<void>
Sends a user_logout event, then clears all the tracking data including any user properties set earlier.
await Kewa.trackLogout();trackScreenView(screenName, additionalData?): Promise<void>
Sends a screen_view event.
await Kewa.trackScreenView('ProductDetail', {
previousScreen: 'Home',
screenClass: 'ProductDetailScreen',
loadTime: 320,
params: { productId: 'abc123' },
});trackError(error, context?, isFatal?): Promise<void>
Sends an error event with message, stack trace, name, and optional context.
try {
await riskyOperation();
} catch (error) {
await Kewa.trackError(error as Error, { screen: 'Checkout' }, false);
}reset(): Promise<void>
Clears tracking data, and stored user properties locally without sending a logout event. Use when you need to wipe identity silently (e.g. account deletion flow).
await Kewa.reset();Getters
| Method | Returns | Description |
| --------------------- | ------------------------ | ------------------------------------ |
| getKtcId() | Promise<string | null> | Locally stored contact ID |
| getDeviceId() | Promise<string | null> | Kewa-assigned device ID |
| getUserProperties() | Promise<ContactData> | Merged contact properties in storage |
| isSDKInitialized() | boolean | Whether init() completed |
const contactId = await Kewa.getKtcId();
const deviceId = await Kewa.getDeviceId();
const props = await Kewa.getUserProperties();
const ready = Kewa.isSDKInitialized();cleanup(): void
Removes the AppState listener and network monitor. Called automatically by KewaProvider on unmount.
Kewa.cleanup();Package exports
import Kewa from 'kewa-react-native';
import { KewaProvider, useKewa, useAutoTracker } from 'kewa-react-native';
import { KewaTracker, KewaAutoTracker } from 'kewa-react-native';
import { KEWA_CONSTANTS, DeviceInfoCollector } from 'kewa-react-native';
import type { KewaConfig, ContactData, KewaEvent, KewaResponse } from 'kewa-react-native';Use Cases
App login
After the user authenticates in your app, call trackLogin to record the login event and attach user identity to subsequent events.
import { useKewa } from 'kewa-react-native';
function LoginScreen() {
const { trackLogin, setUserProperties } = useKewa();
const handleLogin = async () => {
const user = await authenticateWithYourBackend();
await trackLogin({
userId: user.id,
email: user.email,
loginMethod: 'email',
});
// Optionally sync profile fields immediately
await setUserProperties({
email: user.email,
firstname: user.firstName,
lastname: user.lastName,
});
navigation.navigate('Home');
};
return <Button title="Log in" onPress={handleLogin} />;
}The backend may return a ktc_id and device_id which the SDK stores automatically for future events.
App register
Call trackRegistration when a new account is created.
import { useKewa } from 'kewa-react-native';
function RegisterScreen() {
const { trackRegistration, setUserProperties } = useKewa();
const handleRegister = async () => {
const user = await createAccountOnYourBackend();
await trackRegistration({
userId: user.id,
email: user.email,
registrationMethod: 'email',
});
await setUserProperties({
email: user.email,
firstname: user.firstName,
lastname: user.lastName,
});
navigation.navigate('Onboarding');
};
return <Button title="Create account" onPress={handleRegister} />;
}Set user properties
Update contact/profile fields at any time — after login, on profile edit, or after a purchase. Properties are merged locally and synced to the backend.
import Kewa from 'kewa-react-native';
// After profile update
await Kewa.setUserProperties({
plan: 'premium',
company: 'Acme Inc',
preferred_locale: 'en-US',
});
// After purchase
await Kewa.setUserProperties({
plan: 'premium',
subscriptionDate: new Date().toISOString(),
totalPurchases: 3,
});Supported fields include id, email, firstname, lastname, mobile, company, address fields, social profiles, and any custom keys via the ContactData index signature.
App logout (clears everything)
Call trackLogout when the user signs out. This sends a user_logout event and clears all local identity — ktc_id, device_id, and user properties — so the next session starts anonymous.
import { useKewa } from 'kewa-react-native';
function ProfileScreen() {
const { trackLogout } = useKewa();
const handleLogout = async () => {
await signOutFromYourBackend();
await trackLogout(); // sends user_logout + clears ktc_id, device_id, user properties
navigation.reset({ index: 0, routes: [{ name: 'Login' }] });
};
return <Button title="Log out" onPress={handleLogout} />;
}React Integration
useKewa()
Returns the full SDK API. Must be used inside KewaProvider.
function CheckoutScreen() {
const {
trackEvent,
trackLogin,
trackLogout,
trackRegistration,
trackScreenView,
trackError,
setUserProperties,
reset,
getKtcId,
getDeviceId,
getUserProperties,
isSDKInitialized,
} = useKewa();
}useAutoTracker()
UI-focused helpers bound to the provider instance.
function HomeScreen() {
const { trackButtonPress, trackFormSubmission, trackError } = useAutoTracker();
return (
<>
<Button onPress={trackButtonPress('subscribe', { plan: 'premium' })} />
<Button onPress={trackFormSubmission('newsletter', { source: 'home' })} />
</>
);
}Auto Tracking
KewaTracker / KewaAutoTracker are static utilities that use the shared Kewa singleton.
React Navigation screen tracking
const navigationRef = useRef(null);
const { onReady, onStateChange } = KewaAutoTracker.setupNavigationTracking(navigationRef);
<NavigationContainer ref={navigationRef} onReady={onReady} onStateChange={onStateChange}>Disabled when disableTracking, disableEventTracking, or disableScreenViewTracking is true.
Button and form tracking
<Button onPress={KewaTracker.trackButtonPress('cta_signup', { variant: 'hero' })} />
<Button onPress={KewaTracker.trackFormSubmission('contact_form', { fields: 3 })} />Error tracking
KewaAutoTracker.trackError(error, { component: 'PaymentForm' });Automatic Events
| Event | Trigger | Disabled when |
| ---------------- | --------------------------- | ------------------------------------------------------------------------- |
| app_launch | SDK init completes | disableTracking or disableEventTracking |
| app_foreground | App returns from background | disableTracking or disableAppStateTracking |
| app_background | App moves to background | disableTracking or disableAppStateTracking |
| screen_view | Navigation route change | disableTracking, disableEventTracking, or disableScreenViewTracking |
Predefined event name constants are available on KEWA_CONSTANTS.EVENTS.
Offline Queue
- If the device is offline or a send fails, the event is saved to AsyncStorage.
- Queue is capped at
maxQueueSize(default 100); oldest events are dropped when full. - Queue is processed on SDK init and when the app returns to foreground.
- Events are sent one at a time.
Troubleshooting
| Issue | Solution |
| ----------------------------------- | ---------------------------------------------------------------- |
| Events not sending | Verify appUrl, projectId, apiKey, and network connectivity |
| projectId is required error | Pass projectId or set disableTracking: true |
| ktc_id not updating | Confirm backend returns id in the response |
| NativeModule.RNDeviceInfo is null | Not running in Expo Go — use a dev build or bare RN |
| Queue growing | Check backend availability; adjust maxQueueSize if needed |
| Duplicate init | Use either KewaProvider or manual Kewa.init(), not both |
| SDK not initialized warning | Call init() via provider or manually before tracking |
Verify the endpoint manually
curl -X POST 'https://your-kewa-instance.com/t/39r48kjbddkj/mtc/event/track' \
-H 'Content-Type: application/json' \
-H 'secret: YOUR_API_KEY' \
-d '{
"event": "test_event",
"timestamp": "2026-06-09T00:00:00.000Z",
"data": {},
"contact": {},
"kewa_device_id": null,
"device": { "platform": "ios", "appVersion": "1.0.0" }
}'License
MIT — see LICENSE.
