> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datalyr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native/Expo

> Add DATALYR tracking to your React Native or Expo app

Add DATALYR to your React Native or Expo app to track users, conversions, and revenue with full attribution support.

## Use Cases

**Cross-Platform Apps**
Track iOS and Android users with a single SDK. See which ads drive installs and conversions on both platforms.

**E-commerce Apps**
Monitor purchases, cart additions, and product views with revenue attribution back to ad campaigns.

**SaaS Mobile Apps**
Track feature usage, user engagement, and subscription conversions with cross-device attribution.

**Expo Apps**
Full support for Expo managed and bare workflows with minimal setup.

## Before You Start

* [ ] You have a DATALYR account
* [ ] You've created a workspace
* [ ] You have a React Native or Expo project
* [ ] React Native 0.60+
* [ ] iOS 13.0+ and Android 5.0+ (API 21+)

## Step 1: Get Your API Key

1. Log in to your DATALYR dashboard
2. Go to **Settings → API Keys**
3. Create a new API key or copy an existing one
4. Your API key will start with `dk_`

## Step 2: Install the SDK

```bash theme={null}
npm install @datalyr/react-native
# or
yarn add @datalyr/react-native
```

### iOS Setup (React Native CLI)

```bash theme={null}
cd ios && pod install && cd ..
```

### Expo Users

No additional configuration needed. The package works with both managed and bare workflows.

## Step 3: Initialize the SDK

Add initialization to your app entry point:

**`App.tsx`** or **`App.js`**

```typescript theme={null}
import React, { useEffect } from 'react';
import { Datalyr } from '@datalyr/react-native';

export default function App() {
  useEffect(() => {
    // Initialize DATALYR
    Datalyr.initialize({
      apiKey: 'dk_your_api_key', // Replace with your API key
      debug: true, // Enable debug logs in development
      enableAutoEvents: true, // Track sessions, screen views, app lifecycle
      enableAttribution: true, // Track attribution data from ads
    });
  }, []);

  return (
    // Your app content
  );
}
```

## Step 4: Track Your First Event

Test that tracking works:

```typescript theme={null}
import { Datalyr } from '@datalyr/react-native';

// Track a custom event
await Datalyr.track('Button Clicked', {
  button_name: 'Sign Up',
  screen: 'Home',
});
```

## Step 5: Verify Tracking

1. Run your app on a simulator/emulator or device
2. Go to your DATALYR dashboard
3. Click **Events** in the sidebar
4. You should see events within 10 seconds

If you see events, you're done!

## What Gets Tracked Automatically

When `enableAutoEvents` is enabled (default: true):

* `app_install` - First app open
* `app_open` - App launches
* `app_background` - App enters background
* `app_foreground` - App returns to foreground
* `app_update` - App version changes
* `session_start` - New session begins
* `session_end` - Session expires

## Track Custom Events

Track any custom event with optional properties:

```typescript theme={null}
import { Datalyr } from '@datalyr/react-native';

// Simple event
await Datalyr.track('Button Clicked');

// Event with properties
await Datalyr.track('Product Viewed', {
  product_id: 'SKU123',
  product_name: 'Premium Subscription',
  price: 49.99,
  currency: 'USD',
  category: 'Subscriptions',
});
```

## Track Purchases

Track purchase events with revenue:

```typescript theme={null}
// Simple purchase (automatically updates SKAdNetwork conversion value on iOS)
await Datalyr.trackPurchase(99.99, 'USD', 'premium_subscription');

// Detailed purchase event
await Datalyr.track('Purchase Completed', {
  order_id: 'ORDER123',
  amount: 149.99,
  currency: 'USD',
  products: [
    { id: 'SKU1', name: 'Product 1', price: 99.99 },
    { id: 'SKU2', name: 'Product 2', price: 50.00 },
  ],
  tax: 12.50,
  shipping: 5.00,
});
```

## Track Subscriptions

Track subscription events for in-app subscriptions:

```typescript theme={null}
await Datalyr.trackSubscription(9.99, 'USD', 'monthly_pro');
```

## Identify Users

Identify users after signup or login for cross-device attribution:

```typescript theme={null}
await Datalyr.identify('user_123', {
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'premium',
  created_at: '2025-09-29',
});
```

## Track Screen Views

Track screen views with React Navigation:

```typescript theme={null}
import { useNavigationContainerRef } from '@react-navigation/native';
import { Datalyr } from '@datalyr/react-native';

function App() {
  const navigationRef = useNavigationContainerRef();

  return (
    <NavigationContainer
      ref={navigationRef}
      onStateChange={async () => {
        const currentRouteName = navigationRef.current?.getCurrentRoute()?.name;
        if (currentRouteName) {
          await Datalyr.screen(currentRouteName);
        }
      }}
    >
      {/* Your navigation */}
    </NavigationContainer>
  );
}
```

Or track manually:

```typescript theme={null}
import { Datalyr } from '@datalyr/react-native';
import { useEffect } from 'react';

function ProductScreen({ route }) {
  useEffect(() => {
    Datalyr.screen('Product Details', {
      product_id: route.params.productId,
      category: 'Electronics',
    });
  }, []);

  return (
    // Your screen content
  );
}
```

## SKAdNetwork Support (iOS 14+)

Enable SKAdNetwork conversion value tracking:

```typescript theme={null}
await Datalyr.initialize({
  apiKey: 'dk_your_api_key',
  skadTemplate: 'ecommerce', // or 'gaming', 'subscription'
});

// Events automatically update conversion values
await Datalyr.trackPurchase(99.99, 'USD');

// Check conversion value (for testing)
const value = Datalyr.getConversionValue('purchase', { revenue: 50 });
console.log('Conversion value:', value); // 0-63
```

### SKAdNetwork Templates

Choose a template based on your business model:

* **ecommerce**: Purchase events, revenue ranges
* **gaming**: Level completion, in-app purchases, retention
* **subscription**: Trial starts, conversions, renewals

## Identity Resolution

The SDK includes persistent anonymous IDs for complete user journey tracking:

```typescript theme={null}
// Get anonymous ID (persists across app sessions)
const anonymousId = Datalyr.getAnonymousId();

// Pass to your backend for attribution preservation
await fetch('/api/purchase', {
  method: 'POST',
  body: JSON.stringify({
    items: cart,
    anonymous_id: anonymousId, // Links server events to mobile events
  }),
});

// Identity is automatically linked when you identify a user
await Datalyr.identify('user_123', {
  email: 'user@example.com',
});
```

This creates a link between your mobile app events and server-side events, preserving attribution from ad click to purchase.

## Attribution Tracking

The SDK automatically tracks:

* Deep links and Universal Links
* UTM parameters
* Platform click IDs (fbclid, gclid, ttclid)
* Install referrer
* Campaign data

Get attribution data:

```typescript theme={null}
const attribution = Datalyr.getAttributionData();
console.log(attribution.campaign);
console.log(attribution.source);
console.log(attribution.medium);
```

Set custom attribution:

```typescript theme={null}
await Datalyr.setAttributionData({
  campaign: 'email_campaign',
  source: 'newsletter',
  medium: 'email',
});
```

## Session Management

Sessions are automatically tracked with a 30-minute timeout:

```typescript theme={null}
// Get current session
const session = Datalyr.getCurrentSession();

// Manually end session
await Datalyr.endSession();

// Reset user (logout)
await Datalyr.reset();
```

## Deep Link Handling

Track deep link opens with React Navigation:

```typescript theme={null}
import { Linking } from 'react-native';
import { Datalyr } from '@datalyr/react-native';

// Listen for deep links
useEffect(() => {
  const handleDeepLink = async ({ url }: { url: string }) => {
    await Datalyr.track('Deep Link Opened', {
      url: url,
    });
  };

  // Handle initial URL
  Linking.getInitialURL().then((url) => {
    if (url) {
      handleDeepLink({ url });
    }
  });

  // Listen for URL changes
  const subscription = Linking.addEventListener('url', handleDeepLink);

  return () => {
    subscription.remove();
  };
}, []);
```

## Offline Support

Events are automatically queued when offline and sent when connection is restored:

```typescript theme={null}
// Manually flush queue
await Datalyr.flush();

// Get queue status
const status = Datalyr.getStatus();
console.log('Queue size:', status.queueStats.queueSize);
```

## Debug Mode

Enable debug logging during development:

```typescript theme={null}
await Datalyr.initialize({
  apiKey: 'dk_your_api_key',
  debug: true, // Enable console logs
});
```

Debug output includes:

* Event tracking logs
* Network requests
* Queue operations
* Attribution updates
* Error messages

## TypeScript Support

Full TypeScript support with type definitions:

```typescript theme={null}
import {
  Datalyr,
  DatalyrConfig,
  EventData,
  UserProperties,
  AttributionData,
} from '@datalyr/react-native';

// Type-safe event tracking
const properties: EventData = {
  product_id: 'SKU123',
  price: 49.99,
};

await Datalyr.track('Product Viewed', properties);
```

## Expo Configuration

Works with Expo managed and bare workflows with no additional configuration:

```typescript theme={null}
// app.json or app.config.js
{
  "expo": {
    "name": "My App",
    "plugins": [
      // No additional plugins needed
    ]
  }
}
```

## Configuration Options

```typescript theme={null}
interface DatalyrConfig {
  apiKey: string;              // Required - Your API key
  debug?: boolean;             // Enable debug logging
  enableAutoEvents?: boolean;  // Track lifecycle events
  enableAttribution?: boolean; // Track attribution data
  skadTemplate?: 'ecommerce' | 'gaming' | 'subscription'; // SKAdNetwork
  maxQueueSize?: number;       // Default: 100
  flushInterval?: number;      // Default: 30000ms (30 seconds)
  endpoint?: string;           // Custom API endpoint
  useServerTracking?: boolean; // Default: true
}
```

## Troubleshooting

**Events not appearing?**

1. Check your API key is correct (starts with `dk_`)
2. Enable debug mode to see logs
3. Verify network connectivity
4. Check `getStatus()` for queue information
5. Call `flush()` to force send events

**Authentication errors?**

* Ensure API key starts with `dk_`
* Get your API key from: [https://datalyr.com/settings/api-keys](https://datalyr.com/settings/api-keys)
* Verify key is active

**Build errors?**

```bash theme={null}
# Clear caches
npx react-native clean-project

# iOS specific
cd ios && pod install && cd ..

# Android specific
cd android && ./gradlew clean && cd ..
```

**iOS pod install fails?**

```bash theme={null}
cd ios
pod deintegrate
pod install
cd ..
```

**TypeScript errors?**

The package includes TypeScript definitions. Make sure you're using TypeScript 4.0+ and have `@types/react-native` installed.

## Next Steps

<CardGroup cols={2}>
  <Card title="Verify Tracking" icon="check" href="/getting-started/installation/verify-tracking">
    Confirm events are coming through
  </Card>

  <Card title="Track Custom Events" icon="code" href="/sdks/mobile/react-native-sdk">
    Learn the full event tracking API
  </Card>

  <Card title="Connect Integrations" icon="plug" href="/integrations/overview">
    Link Meta, Google, TikTok Ads
  </Card>

  <Card title="View Dashboard" icon="chart-line" href="/features/dashboard">
    See your tracking data
  </Card>
</CardGroup>

## Need Help?

Having issues with React Native tracking? Check our [troubleshooting guide](/troubleshooting/tracking-not-working) or contact support.
