npm package: @sensorswave/react-native-sdk
Description: Sensorswave React Native data tracking SDK
Author: Sensors Wave
Latest version: 1.0.3

# Sensors Wave React Native SDK

[Sensors Wave](http://sensorswave.com/) React Native SDK is a mobile analytics tracking and AB testing library for React Native applications.
If you're new to Sensor Wave, check out our product and create an account at [sensorswave.com](http://sensorswave.com/).

## Requirements

- **React Native >= 0.74.0**
- **React >= 18.0.0**

## Installation

```bash
npm install @sensorswave/react-native-sdk
# or
yarn add @sensorswave/react-native-sdk
```

## Quick Start

### 1. Initialize SDK

```typescript
import { Sensorswave } from '@sensorswave/react-native-sdk';

// Initialize the SDK
Sensorswave.init('your-source-token', {
  debug: false,
  apiHost: 'https://your-api-host.com',
  autoCapture: true,
  enableClickTrack: true,
  enableAB: true,
});

// Set user login ID (optional)
Sensorswave.setLoginId('user_12345');
```

### 2. Wrap Your App with Provider

```tsx
import { SensorswaveProvider } from '@sensorswave/react-native-sdk';

const App = () => {
  return (
    <SensorswaveProvider>
      <NavigationContainer>
        <Stack.Navigator>
          {/* Your screens */}
        </Stack.Navigator>
      </NavigationContainer>
    </SensorswaveProvider>
  );
};
```

### 3. Track Custom Events

```typescript
import { Sensorswave } from '@sensorswave/react-native-sdk';

// Track a custom event
Sensorswave.trackEvent('ButtonClick', {
  button_name: 'submit',
  page: 'home',
});

// Or use the track method for more control
Sensorswave.track({
  event: 'PurchaseCompleted',
  properties: {
    product_id: '12345',
    amount: 99.99,
    currency: 'USD',
  },
});
```

## Configuration Options

| Option            | Type    | Default | Description                                                                              |
| ----------------- | ------- | ------- | ---------------------------------------------------------------------------------------- |
| debug             | boolean | false   | Whether to enable debug mode for logging                                                 |
| apiHost           | string  | ''      | API host address for sending events                                                      |
| autoCapture       | boolean | true    | Whether to automatically capture app events (install, start, end, page view, page leave) |
| enableClickTrack  | boolean | false   | Whether to enable automatic click tracking                                               |
| enableAB          | boolean | false   | Whether to enable A/B testing feature                                                    |
| batchSend         | boolean | true    | Whether to use batch sending (sends events in batches up to 10 events every 5 seconds)   |
| abRefreshInterval | number  | 600000  | A/B test configuration refresh interval in milliseconds                                  |

## Navigation Tracking

The SDK provides automatic page view tracking for different navigation scenarios. Choose the method that fits your navigation setup:

### Method 1: React Navigation v6 and below (Recommended)

Simply wrap your app with `SensorswaveProvider`. No additional configuration needed.

```tsx
import { SensorswaveProvider } from '@sensorswave/react-native-sdk';

const App = () => {
  return (
    <SensorswaveProvider>
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Detail" component={DetailScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </SensorswaveProvider>
  );
};
```

**How it works:** The SDK uses `useNavigationState` hook internally to track route changes automatically.

### Method 2: React Navigation v7+

For React Navigation v7+, use `createNavigationRef` to create a tracked navigation reference:

```tsx
import { SensorswaveProvider, createNavigationRef } from '@sensorswave/react-native-sdk';

const navigationRef = createNavigationRef();

const App = () => {
  return (
    <SensorswaveProvider autocapture={{ captureScreens: false }}>
      <NavigationContainer ref={navigationRef}>
        <Stack.Navigator>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Detail" component={DetailScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </SensorswaveProvider>
  );
};
```

**Why this is needed:** React Navigation v7+ changed how navigation state is accessed, requiring a ref-based approach.

### Method 3: Manual Tracking

For custom navigation solutions or when automatic tracking isn't possible:

```tsx
import { trackScreen } from '@sensorswave/react-native-sdk';

// Call this when screen changes
trackScreen('CustomScreen', {
  title: 'Custom Screen Title',
  custom_property: 'value',
});
```

### Navigation Tracking Comparison

| Navigation Type               | Method                  | Automatic | Limitations         |
| ----------------------------- | ----------------------- | --------- | ------------------- |
| React Navigation v6-          | `SensorswaveProvider`   | ✅ Yes     | None                |
| React Navigation v7+          | `createNavigationRef()` | ✅ Yes     | Requires ref setup  |
| React Native Navigation (Wix) | Manual                  | ❌ No      | Use `trackScreen()` |
| Custom Navigation             | Manual                  | ❌ No      | Use `trackScreen()` |

### Customizing Screen Names

You can customize how screen names are captured:

```tsx
<SensorswaveProvider 
  autocapture={{
    captureScreens: true,
    navigation: {
      routeToName: (name, params) => {
        // Custom logic for screen names
        if (name === 'Detail') {
          return `Product_${params?.productId}`;
        }
        return name;
      },
      routeToProperties: (name, params) => ({
        // Add custom properties to page view events
        category: params?.category || 'unknown',
      }),
    },
  }}
>
  {/* ... */}
</SensorswaveProvider>
```

### Disabling Automatic Screen Tracking

```tsx
<SensorswaveProvider autocapture={false}>
  {/* ... */}
</SensorswaveProvider>

// Or
<SensorswaveProvider autocapture={{ captureScreens: false }}>
  {/* ... */}
</SensorswaveProvider>
```

## API Methods

### Event Tracking

#### trackEvent

Manually track a custom event with properties.

```typescript
Sensorswave.trackEvent('ButtonClick', {
  button_name: 'submit',
  page: 'home',
});
```

#### track

Track an event with full control over the event structure.

```typescript
Sensorswave.track({
  event: 'PurchaseCompleted',
  properties: {
    product_id: '12345',
    amount: 99.99,
  },
});
```

### User Identification

#### identify

Set the login ID and send a binding event.

```typescript
Sensorswave.identify('user_12345');
```

#### setLoginId

Set the login ID without sending a binding event.

```typescript
Sensorswave.setLoginId('user_12345');
```

#### getLoginId

Get the current login ID.

```typescript
const loginId = Sensorswave.getLoginId();
```

#### getAnonId

Get the anonymous ID.

```typescript
const anonId = Sensorswave.getAnonId();
```

### User Profile

#### profileSet

Set user properties (overwrites existing values).

```typescript
Sensorswave.profileSet({
  name: 'John Doe',
  age: 30,
  plan: 'premium',
});
```

#### profileSetOnce

Set user properties only if they don't exist.

```typescript
Sensorswave.profileSetOnce({
  signup_date: '2024-01-15',
  initial_referrer: 'google',
});
```

#### profileIncrement

Increment numeric user properties.

```typescript
Sensorswave.profileIncrement({
  login_count: 1,
  points_earned: 100,
});
```

#### profileAppend

Append values to list properties (no deduplication).

```typescript
Sensorswave.profileAppend({
  categories_viewed: ['electronics', 'mobile_phones'],
});
```

#### profileUnion

Append values to list properties (with deduplication).

```typescript
Sensorswave.profileUnion({
  interests: ['technology', 'gaming'],
});
```

#### profileUnset

Remove specific user properties.

```typescript
Sensorswave.profileUnset(['old_plan', 'temp_id']);
```

#### profileDelete

Delete all user profile data.

```typescript
Sensorswave.profileDelete();
```

### Common Properties

#### registerCommonProperties

Register properties to be included with all events.

```typescript
Sensorswave.registerCommonProperties({
  app_version: '1.0.0',
  environment: 'production',
});
```

#### clearCommonProperties

Remove registered common properties.

```typescript
Sensorswave.clearCommonProperties(['app_version']);
```

### A/B Testing

#### checkFeatureGate

Check if a feature flag is enabled.

```typescript
const isEnabled = await Sensorswave.checkFeatureGate('new_feature');
if (isEnabled) {
  // Show new feature
}
```

#### getExperiment

Get experiment variant data.

```typescript
const experiment = await Sensorswave.getExperiment('homepage_layout');
if (experiment) {
  applyLayout(experiment.layout_type);
}
```

### Utility Methods

#### destroy

Clean up SDK resources.

```typescript
Sensorswave.destroy();
```

## Using Hooks

The SDK provides React hooks for convenient access:

### useSensorswave

Get the SDK instance via hook.

```tsx
import { useSensorswave } from '@sensorswave/react-native-sdk';

function MyComponent() {
  const Sensorswave = useSensorswave();
  
  const handlePress = () => {
    Sensorswave.trackEvent('ButtonPressed', {
      button: 'my_button',
    });
  };
  
  return <Button onPress={handlePress} title="Track Event" />;
}
```

## Automatic Events

When `autoCapture` is enabled, the SDK automatically tracks:

| Event           | Description                                         |
| --------------- | --------------------------------------------------- |
| `$AppInstall`   | Triggered on first app launch after installation    |
| `$AppStart`     | Triggered when app starts or comes to foreground    |
| `$AppEnd`       | Triggered when app goes to background               |
| `$AppPageView`  | Triggered when navigating to a new screen           |
| `$AppPageLeave` | Triggered when leaving a screen (includes duration) |

When `enableClickTrack` is enabled:

| Event       | Description                 |
| ----------- | --------------------------- |
| `$AppClick` | Triggered on element clicks |

## Click Tracking ($AppClick)

The SDK provides automatic click tracking when `enableClickTrack: true` is set during initialization.

### Automatically Tracked Components

The SDK automatically tracks clicks on the following React Native components:

| Component Type           | Examples                                | Description |
| ------------------------ | ---------------------------------------- | ----------- |
| **Touchable Components**  | TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback | Automatically tracked |
| **Pressable**               | `<Pressable>`                             | Automatically tracked |
| **Button**                  | `<Button>`                                 | Automatically tracked |

### Basic Usage

Just use components normally and the SDK will automatically track click events:

```tsx
<Pressable onPress={handleSubmit}>
  <Text>Submit</Text>
</Pressable>

<TouchableOpacity onPress={handleLogin}>
  <Text>Login</Text>
</TouchableOpacity>

<Button title="Confirm" onPress={handleConfirm} />
```

### Disabling Tracking for Specific Elements

To prevent specific elements from being tracked, add the `sw-no-capture` prop:

```tsx
<TouchableOpacity
  sw-no-capture
  onPress={handleInternalAction}
>
  <Text>Internal Action</Text>
</TouchableOpacity>
```

### Ignoring Component Types

You can configure which component types to ignore:

```tsx
<SensorswaveProvider
  autocapture={{
    clickTrack: {
      ignoreLabels: ['ScrollView', 'FlatList', 'View'],  // These won't be tracked
      allowedElementTypes: ['TouchableOpacity', 'Pressable', 'Button'],
    },
  }}
>
  <App />
</SensorswaveProvider>
```

### Custom Props Collection

Collect custom props from clicked elements:

```tsx
<SensorswaveProvider
  autocapture={{
    clickTrack: {
      propsToCapture: ['variant', 'size', 'color'],  // Custom props to include
    },
  }}
>
  <App />
</SensorswaveProvider>
```

**Result:** Custom props will be included in `$AppClick` events along with standard properties.

### Complete Example

```tsx
import React from 'react';
import { View, TouchableOpacity, Text, Pressable } from 'react-native';
import { SensorswaveProvider } from '@sensorswave/react-native-sdk';

function App() {
  return (
    <SensorswaveProvider
      autocapture={{
        clickTrack: {
          ignoreLabels: ['ScrollView', 'FlatList', 'View'],
          allowedElementTypes: ['TouchableOpacity', 'Pressable', 'Button'],
          propsToCapture: ['variant', 'color'],
        },
      }}
    >
      <MyScreen />
    </SensorswaveProvider>
  );
}

function MyScreen() {
  return (
    <View>
      {/* Automatically tracked - TouchableOpacity */}
      <TouchableOpacity
        variant="primary"
        onPress={handleSubmit}
      >
        <Text>Submit Form</Text>
      </TouchableOpacity>

      {/* Automatically tracked - Pressable */}
      <Pressable onPress={handleCancel}>
        <Text>Cancel</Text>
      </Pressable>

      {/* Not tracked - has sw-no-capture */}
      <TouchableOpacity
        sw-no-capture
        onPress={handleInternal}
      >
        <Text>Internal</Text>
      </TouchableOpacity>
    </View>
  );
}
```

### Event Data Example

When user clicks a button:

```json
{
  "event": "$AppClick",
  "properties": {
    "$screen_name": "FormScreen",
    "$element_type": "TouchableOpacity",
    "$element_content": "Submit Form",
    "$element_selector": "View > TouchableOpacity > Text [Submit Form]",
    "$element_path": "View > TouchableOpacity > Text > [Submit Form]",
    "variant": "primary"
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and provides full type definitions.

```typescript
import type { 
  SensorswaveConfig, 
  AutocaptureOptions,
  NavigationTrackerOptions,
} from '@sensorswave/react-native-sdk';
```

## Troubleshooting

### Page Views Not Tracking

1. Make sure `SensorswaveProvider` wraps your `NavigationContainer`
2. For React Navigation v7+, use `createNavigationRef()`
3. Check that `autoCapture` is not disabled

### Events Not Sending

1. Check your `apiHost` configuration
2. Enable `debug: true` to see logs

## License

Apache-2.0