npm package: @solomon-tech/events-react-native
Description: Solomon Analytics SDK for React Native - Track e-commerce funnel events in mobile apps
Author: Solomon Tech
Latest version: 1.0.1

# @solomon-tech/events-react-native

Solomon Analytics SDK for React Native — track e-commerce funnel events in mobile apps with the same backend contract as the web SDK.

## Installation

```bash
npm install @solomon-tech/events-react-native @react-native-async-storage/async-storage
```

### Required Peer Dependencies

| Package | Purpose |
|---------|---------|
| `@react-native-async-storage/async-storage` | Persistent storage for session/user IDs and UTMs |

### Optional Peer Dependencies

| Package | Purpose | Fallback |
|---------|---------|----------|
| `react-native-device-info` | Device ID (IDFV/ANDROID_ID), model, app version | `"unknown"` |
| `@react-native-community/netinfo` | Connection type (wifi/4g/5g) | `"unknown"` |
| `react-native-install-referrer` | Install campaign UTMs (Android only) | `null` |

```bash
# Optional — install for full device telemetry
npm install react-native-device-info @react-native-community/netinfo react-native-install-referrer
```

For **Expo managed workflow**, add the config plugins to `app.json`:

```json
{
  "expo": {
    "plugins": [
      "react-native-device-info"
    ]
  }
}
```

## Quick Start

```typescript
import { SolomonSDK } from '@solomon-tech/events-react-native';

const sdk = new SolomonSDK({
  companyId: 'YOUR_COMPANY_ID',
  debug: true,
  useTouchpoint: true,
  appIdentifier: 'com.yourapp.bundle',
});

// Set screen name before tracking
sdk.setScreenName('HomeScreen');

// Track events
await sdk.track('VIEW_PAGE');

await sdk.track('CONTENT_VIEW', {
  id: 'product-123',
  title: 'Blue T-Shirt',
  price: 49.90,
  variant: 'M',
});

await sdk.track('ADD_TO_CART', {
  item_id: 'product-123',
  item_quantity: 2,
});

await sdk.track('CHECKOUT_COMPLETED', {
  items: [{ item_id: 'product-123', item_quantity: 2 }],
}, {
  email: 'customer@example.com',
  order_id: 'ORD-456',
});
```

## API Reference

### `new SolomonSDK(config: SDKConfig)`

| Config | Type | Required | Description |
|--------|------|----------|-------------|
| `companyId` | `string` | Yes | Your Solomon company ID |
| `debug` | `boolean` | No | Log events to console |
| `useTouchpoint` | `boolean` | No | Send touchpoint/attribution events |
| `appIdentifier` | `string` | No | App bundle ID for `current_domain` field |
| `storage` | `StorageAdapter` | No | Custom storage adapter (default: AsyncStorage) |

### `sdk.track(event, payload?, aliases?)`

Tracks a funnel event. Sends to both endpoints when `useTouchpoint` is enabled.

**Events:**

| Event | Payload |
|-------|---------|
| `VIEW_PAGE` | `null` |
| `CONTENT_VIEW` | `{ id, variant?, title?, price? }` |
| `ADD_TO_CART` | `{ item_id, item_quantity }` |
| `INITIATE_CHECKOUT` | `{ items: [{ item_id, item_quantity }] }` |
| `ADD_SHIPPING_INFO` | `{ items: [{ item_id, item_quantity }] }` |
| `ADD_CUSTOMER_INFO` | `{ items: [{ item_id, item_quantity }] }` |
| `ADD_PAYMENT_INFO` | `{ items: [{ item_id, item_quantity }] }` |
| `CHECKOUT_COMPLETED` | `{ items: [{ item_id, item_quantity }] }` |

**Custom Aliases (optional 3rd param):**

```typescript
{
  email?: string;
  phone?: string;
  user_id?: string;
  customer_id?: string;
  cart_token?: string;
  order_id?: string;
}
```

### `sdk.setScreenName(name: string)`

Sets the current screen name, used as `page_path` in events.

### `sdk.handleDeepLink(url: string)`

Extracts and stores UTM parameters from a deep link URL.

### `sdk.flush()`

No-op in v1 (events are sent immediately). Reserved for future queue-based delivery.

### `sdk.destroy()`

Removes app lifecycle listeners. Call when unmounting.

## Deep Link Integration

### Manual

```typescript
import { Linking } from 'react-native';

// On app start
Linking.getInitialURL().then(url => {
  if (url) sdk.handleDeepLink(url);
});

// While app is running
Linking.addEventListener('url', event => {
  sdk.handleDeepLink(event.url);
});
```

### Automatic (Hook)

```typescript
import { useSolomonDeepLinks } from '@solomon-tech/events-react-native/hooks';

function App() {
  useSolomonDeepLinks(sdk);
  // ...
}
```

## React Navigation Integration

### Manual

```typescript
const onStateChange = (state) => {
  const routeName = getActiveRouteName(state);
  sdk.setScreenName(routeName);
};

<NavigationContainer onStateChange={onStateChange}>
```

### Automatic (Hook)

```typescript
import { useSolomonScreenTracking } from '@solomon-tech/events-react-native/hooks';

function App() {
  const navigationRef = useNavigationContainerRef();
  const onStateChange = useSolomonScreenTracking(sdk, navigationRef);

  return (
    <NavigationContainer ref={navigationRef} onStateChange={onStateChange}>
      {/* screens */}
    </NavigationContainer>
  );
}
```

## Custom Storage Adapter

Replace AsyncStorage with MMKV or any other storage:

```typescript
import { MMKV } from 'react-native-mmkv';

const mmkv = new MMKV();

const sdk = new SolomonSDK({
  companyId: 'YOUR_ID',
  storage: {
    getItem: (key) => Promise.resolve(mmkv.getString(key) ?? null),
    setItem: (key, value) => { mmkv.set(key, value); return Promise.resolve(); },
    removeItem: (key) => { mmkv.delete(key); return Promise.resolve(); },
  },
});
```

## Migration from Web SDK

| Web SDK | React Native SDK | Notes |
|---------|-----------------|-------|
| `new SolomonSDK({ companyId })` | Same | Add `appIdentifier` for mobile |
| `sdk.track('VIEW_PAGE')` | Same | Call `setScreenName()` first |
| `sdk.track('ADD_TO_CART', payload)` | Same | Identical API |
| Auto UTM from URL | `sdk.handleDeepLink(url)` | Manual or via hook |
| Auto page path from `window.location` | `sdk.setScreenName(name)` | Manual or via hook |

## License

MIT