uengage-sales-funnel
v1.0.11
Published
React Native funnel tracking SDK (internal)
Readme
uengage-sales-funnel
A lightweight event tracking SDK for React Native apps, used to send predefined sales funnel events to the Uengage sales funnel backend.
- 📦 Built for React Native
>=0.68.3 - ⚛️ React
17compatible - 💾 Uses
@react-native-community/async-storagefor persistentvisitor_id - 📡 Batches events and flushes periodically + when app goes to background
- 🕒 All timestamps are captured in IST (Asia/Kolkata)
1. Installation
Peer dependencies
Your React Native app must already have:
"dependencies": {
"react": "17.0.2",
"react-native": "0.68.3",
"@react-native-community/async-storage": "^1.12.1"
}Install the SDK
npm install uengage-sales-funnel
# or
yarn add uengage-sales-funnel2. Quick Start
Initialize the tracker once (usually at app startup) and then call trackEvent wherever you need.
// App.tsx
import React, { useEffect } from "react";
import { View, Text } from "react-native";
import {
initTracker,
trackEvent
} from "uengage-sales-funnel";
const App = () => {
useEffect(() => {
initTracker({
// apiUrl is optional – defaults to Uengage production endpoint
batchSize: 10,
flushInterval: 5000,
platform: "application",
tenantToken: "<TENANT_TOKEN_FROM_BACKEND>"
});
// Example funnel event
trackEvent("visit");
}, []);
return (
<View>
<Text>Hello Funnel Tracker</Text>
</View>
);
};
export default App;3. Configuration
initTracker(config)
Call once at app startup (e.g. in App.tsx or in your root provider file).
initTracker({
batchSize?: number; // optional - default: 10
flushInterval?: number; // optional - ms, default: 5000 (5s)
platform?: string; // optional - default: "application"
tenantToken: string | null; // required in production
});Example
initTracker({
batchSize: 20,
flushInterval: 7000,
platform: "android",
tenantToken: "tenant_abc_123"
});Note: If
tenantTokenis missing, the SDK will log a warning but still try to send events.
4. Tracking Events
Supported event names
The SDK is currently built around a fixed set of funnel events:
type Events =
| "visit"
| "send_otp"
| "login_success"
| "location_selected"
| "location_popup"
| "product_viewed"
| "add_to_cart"
| "remove_from_cart"
| "add_payment_info"
| "conversion";trackEvent(eventName, options?)
Tracks a single event and pushes it into a local queue.
When the queue size reaches batchSize or when the flush interval fires, events are sent in a batch to your backend.
trackEvent(
eventName: Events, // one of the supported values above
options?: {
userId?: string | null;
metadata?: Record<string, any>;
}
): Promise<void>Basic example
trackEvent("visit");With userId and metadata
trackEvent("product_viewed", {
userId: "user_123",
metadata: {
productId: "PROD-9876",
name: "Paneer Tikka Pizza",
price: 299,
currency: "INR"
}
});Conversion example
trackEvent("conversion", {
userId: "user_123",
metadata: {
orderId: "ORD-1122",
amount: 499,
paymentMethod: "UPI"
}
});5. How events are structured
Each event sent to the backend looks like:
{
"event": "product_viewed",
"visitor_id": "v_xxxxx", // stored in AsyncStorage
"user_id": "user_123", // from options.userId
"url": null, // not applicable in React Native
"captured_at": "2025-11-17 12:34:56", // IST (Asia/Kolkata)
"platform": "application", // from config.platform
"system": "android", // Platform.OS
"metadata": { /* custom data */ }
}The full request body sent to the server:
{
"tenantToken": "tenant_abc_123",
"events": [ /* array of event objects */ ]
}6. Visitor ID
The SDK generates a persistent visitor_id and stores it using @react-native-community/async-storage.
- Key:
uengage_visitor_id - Format:
"v_" + random + timestamp
You can access it if needed:
getVisitorId()
import { getVisitorId } from "uengage-sales-funnel";
const visitorId = await getVisitorId();
console.log("Visitor ID:", visitorId);7. Flushing events
Events are flushed automatically when:
- The in-memory queue length reaches
batchSize - The flush timer ticks (
flushIntervalin ms) - The app goes to background (
AppStatechanges fromactivetobackground/inactive)
You can also trigger manual flush:
flushEvents()
import { flushEvents } from "uengage-sales-funnel";
await flushEvents();8. Shutdown / cleanup (optional)
If you need to clean up listeners and timers (e.g. during tests):
shutdownTracker()
import { shutdownTracker } from "uengage-sales-funnel";
shutdownTracker();This:
- Clears the internal interval timer
- Unsubscribes from
AppStatechanges
9. TypeScript support
The SDK is written in TypeScript and ships type declarations.
You get full typings out of the box:
import {
initTracker,
trackEvent,
flushEvents,
getVisitorId,
shutdownTracker,
type TrackerConfig,
type TrackEventOptions
} from "uengage-sales-funnel";Example of using TrackerConfig in your own abstraction:
import type { TrackerConfig } from "uengage-sales-funnel";
const config: Partial<TrackerConfig> = {
tenantToken: "tenant_abc_123"
};10. Notes & Gotchas
Call
initTrackerbeforetrackEventIf you forget, the SDK will log a warning and ignore the event.Predefined event set
eventNamemust be one of:visit,send_otp,login_success,location_selected,location_popup,product_viewed,add_to_cart,remove_from_cart,add_payment_info,conversion.No
window.locationThis is React Native, sourlis alwaysnull. If you want to track screens, pass them inmetadata:trackEvent("visit", { metadata: { screen: "HomeScreen" } });Time zone is IST (
Asia/Kolkata)captured_atis formatted asYYYY-MM-DD HH:mm:ssin IST internally using a custom date helper.Offline handling Currently, events are queued in memory and retried on flush failure by re-adding them to the queue. For full offline durability, additional storage logic can be added in a future version.
11. Example: Screen tracking helper
Here’s a small example you can add in your app (not part of the SDK) using the existing visit event:
// trackerHelpers.ts
import { trackEvent } from "uengage-sales-funnel";
export function trackScreenVisit(screenName: string, userId?: string) {
return trackEvent("visit", {
userId,
metadata: { screen: screenName }
});
}And use with React Navigation:
// Somewhere in your navigation container
trackScreenVisit("HomeScreen", currentUserId);