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

# Mobile Apps

> Native UserBoost integration for React Native and Flutter mobile applications

## When to Use Mobile Apps Integration

**Perfect for mobile applications:**

* React Native iOS/Android apps
* Flutter cross-platform apps
* Native iOS/Android apps (using REST API)
* Mobile-specific user journey tracking
* Offline-first mobile experiences

**Key benefits:**

* ✅ Native mobile optimization
* ✅ Platform-specific features and performance
* ✅ Automatic device and app context
* ✅ Works offline with intelligent queueing
* ✅ Seamless cross-platform development

***

## Quick Setup (5 minutes)

<Steps>
  <Step title="Get your API key">
    1. Sign up at [userboo.st](https://userboo.st)
    2. Go to **Settings** → **API Keys**
    3. Copy your **Client-side API key** (starts with `ub_live_`)

    <Note>
      Use the **client-side** API key for mobile apps, not the server-side key.
    </Note>
  </Step>

  <Step title="Choose your platform">
    <Tabs>
      <Tab title="React Native">
        **Install the React Native SDK**

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

        **Initialize in your App.js**

        ```javascript theme={null}
        import UserBoost from '@userboost/react-native';

        // Initialize once at app startup
        UserBoost.init({
          apiKey: 'ub_live_your_client_key_here',
          debug: __DEV__, // Enable in development
        });

        export default function App() {
          // Your app code
        }
        ```
      </Tab>

      <Tab title="Flutter">
        **Add to pubspec.yaml**

        ```yaml theme={null}
        dependencies:
          userboost: ^1.0.0
        ```

        ```bash theme={null}
        flutter pub get
        ```

        **Initialize in main.dart**

        ```dart theme={null}
        import 'package:userboost/userboost.dart';

        void main() async {
          WidgetsFlutterBinding.ensureInitialized();

          await UserBoost.init(
            apiKey: 'ub_live_your_client_key_here',
            debug: kDebugMode,
          );

          runApp(MyApp());
        }
        ```
      </Tab>

      <Tab title="REST API">
        **For native iOS/Android or other frameworks**

        Use the universal REST API approach:

        ```bash theme={null}
        curl -X POST https://api.userboo.st/v1/event \
          -H "Authorization: Bearer ub_live_your_client_key_here" \
          -H "Content-Type: application/json" \
          -d '{
            "event": "app_opened",
            "user": {
              "id": "user_123"
            },
            "context": {
              "platform": "ios",
              "app_version": "1.2.0"
            }
          }'
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Track your first event">
    <Tabs>
      <Tab title="React Native">
        ```javascript theme={null}
        import UserBoost from '@userboost/react-native';
        import { Platform } from 'react-native';

        // Track app launch
        UserBoost.event('app_opened', {
          user: {
            id: 'user_123',
            email: 'john@example.com'
          },
          properties: {
            app_version: '1.2.0',
            platform: Platform.OS
          }
        });

        // Track screen views
        UserBoost.event('screen_viewed', {
          user: { id: 'user_123' },
          properties: {
            screen_name: 'dashboard',
            previous_screen: 'onboarding'
          }
        });
        ```
      </Tab>

      <Tab title="Flutter">
        ```dart theme={null}
        import 'dart:io' show Platform;
        import 'package:userboost/userboost.dart';

        // Track app launch
        UserBoost.event('app_opened', {
          'user': {
            'id': 'user_123',
            'email': 'john@example.com'
          },
          'properties': {
            'app_version': '1.2.0',
            'platform': Platform.operatingSystem
          }
        });

        // Track screen navigation
        UserBoost.event('screen_viewed', {
          'user': {'id': 'user_123'},
          'properties': {
            'screen_name': 'dashboard',
            'previous_screen': 'onboarding'
          }
        });
        ```
      </Tab>

      <Tab title="REST API">
        ```javascript theme={null}
        // iOS Swift example
        func trackEvent(_ event: String, userId: String, properties: [String: Any] = [:]) {
            let url = URL(string: "https://api.userboo.st/v1/event")!
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.setValue("Bearer ub_live_your_client_key_here", forHTTPHeaderField: "Authorization")
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")

            let data: [String: Any] = [
                "event": event,
                "user": ["id": userId],
                "properties": properties
            ]

            request.httpBody = try? JSONSerialization.data(withJSONObject: data)

            URLSession.shared.dataTask(with: request).resume()
        }

        // Usage
        trackEvent("app_opened", userId: "user_123", properties: [
            "app_version": "1.2.0",
            "platform": "ios"
        ])
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Verify it's working">
    1. Go to your [UserBoost dashboard](https://userboo.st/dashboard)
    2. Navigate to **Events** → **Live Stream**
    3. Open your mobile app and trigger some events
    4. Events should appear in the dashboard within 30 seconds

    <Note>
      Use debug mode during development to see events in your mobile app's logs.
    </Note>
  </Step>
</Steps>

***

## Common Mobile Event Patterns

Track these key mobile-specific events to understand your user journey:

### App Lifecycle Events

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    import { AppState } from 'react-native';
    import UserBoost from '@userboost/react-native';

    class App extends Component {
      componentDidMount() {
        AppState.addEventListener('change', this.handleAppStateChange);
      }

      handleAppStateChange = (nextAppState) => {
        if (nextAppState === 'active') {
          UserBoost.event('app_opened', {
            user: { id: this.getCurrentUserId() },
            properties: {
              session_start: new Date().toISOString()
            }
          });
        } else if (nextAppState === 'background') {
          UserBoost.event('app_backgrounded', {
            user: { id: this.getCurrentUserId() },
            properties: {
              session_duration: this.getSessionDuration()
            }
          });
        }
      };
    }
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addObserver(this);
      }

      @override
      void didChangeAppLifecycleState(AppLifecycleState state) {
        if (state == AppLifecycleState.resumed) {
          UserBoost.event('app_opened', {
            'user': {'id': getCurrentUserId()},
            'properties': {
              'session_start': DateTime.now().toIso8601String()
            }
          });
        } else if (state == AppLifecycleState.paused) {
          UserBoost.event('app_backgrounded', {
            'user': {'id': getCurrentUserId()},
            'properties': {
              'session_duration': getSessionDuration()
            }
          });
        }
      }
    }
    ```
  </Tab>
</Tabs>

### Screen Navigation

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // With React Navigation
    import { NavigationContainer } from '@react-navigation/native';

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

      return (
        <NavigationContainer
          ref={navigationRef}
          onReady={() => {
            routeNameRef.current = navigationRef.getCurrentRoute().name;
          }}
          onStateChange={async () => {
            const previousRouteName = routeNameRef.current;
            const currentRouteName = navigationRef.getCurrentRoute().name;

            if (previousRouteName !== currentRouteName) {
              UserBoost.event('screen_viewed', {
                user: { id: getCurrentUserId() },
                properties: {
                  screen_name: currentRouteName,
                  previous_screen: previousRouteName,
                  timestamp: new Date().toISOString()
                }
              });
            }

            routeNameRef.current = currentRouteName;
          }}
        >
          {/* Your navigation stack */}
        </NavigationContainer>
      );
    }
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    class RouteObserver extends NavigatorObserver {
      @override
      void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
        if (route.settings.name != null) {
          UserBoost.event('screen_viewed', {
            'user': {'id': getCurrentUserId()},
            'properties': {
              'screen_name': route.settings.name,
              'previous_screen': previousRoute?.settings.name,
              'timestamp': DateTime.now().toIso8601String()
            }
          });
        }
      }
    }

    // Add to your MaterialApp
    MaterialApp(
      navigatorObservers: [RouteObserver()],
      // ... rest of your app
    )
    ```
  </Tab>
</Tabs>

### User Interactions

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // Button taps
    const handleButtonPress = (buttonName) => {
      UserBoost.event('button_tapped', {
        user: { id: getCurrentUserId() },
        properties: {
          button_name: buttonName,
          screen: getCurrentScreen(),
          timestamp: new Date().toISOString()
        }
      });
    };

    // Form submissions
    const handleFormSubmit = (formData) => {
      UserBoost.event('form_submitted', {
        user: { id: getCurrentUserId() },
        properties: {
          form_type: 'profile_update',
          fields_completed: Object.keys(formData).length,
          screen: 'profile_edit'
        }
      });
    };
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    // Button taps
    void handleButtonPress(String buttonName) {
      UserBoost.event('button_tapped', {
        'user': {'id': getCurrentUserId()},
        'properties': {
          'button_name': buttonName,
          'screen': getCurrentScreen(),
          'timestamp': DateTime.now().toIso8601String()
        }
      });
    }

    // Form submissions
    void handleFormSubmit(Map<String, dynamic> formData) {
      UserBoost.event('form_submitted', {
        'user': {'id': getCurrentUserId()},
        'properties': {
          'form_type': 'profile_update',
          'fields_completed': formData.keys.length,
          'screen': 'profile_edit'
        }
      });
    }
    ```
  </Tab>
</Tabs>

***

## Mobile-Specific Features

### Automatic Context Collection

Mobile SDKs automatically collect device and app context:

```javascript theme={null}
// This context is automatically added to all events:
{
  "context": {
    "platform": "ios",           // or "android"
    "app_version": "1.2.0",
    "device_model": "iPhone 14",
    "os_version": "16.2",
    "screen_size": "390x844",
    "network_type": "wifi",      // or "cellular", "none"
    "timezone": "America/New_York",
    "locale": "en-US"
  }
}
```

### Offline Support

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

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // Events are automatically queued offline
    UserBoost.event('offline_action', {
      user: { id: 'user_123' },
      properties: { action: 'create_draft' }
    });

    // Check queue status
    UserBoost.getQueueLength().then(count => {
      console.log(`${count} events queued`);
    });

    // Force flush when back online
    UserBoost.flush();
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    // Events are automatically queued offline
    UserBoost.event('offline_action', {
      'user': {'id': 'user_123'},
      'properties': {'action': 'create_draft'}
    });

    // Check queue status
    int queueLength = await UserBoost.getQueueLength();
    print('$queueLength events queued');

    // Force flush when back online
    UserBoost.flush();
    ```
  </Tab>
</Tabs>

### Push Notifications Integration

Track push notification engagement:

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // Track notification received
    UserBoost.event('push_notification_received', {
      user: { id: getCurrentUserId() },
      properties: {
        campaign_id: notification.campaignId,
        message: notification.message,
        received_at: new Date().toISOString()
      }
    });

    // Track notification tapped
    UserBoost.event('push_notification_tapped', {
      user: { id: getCurrentUserId() },
      properties: {
        campaign_id: notification.campaignId,
        action: 'open_app'
      }
    });
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    // Track notification received
    UserBoost.event('push_notification_received', {
      'user': {'id': getCurrentUserId()},
      'properties': {
        'campaign_id': notification.campaignId,
        'message': notification.message,
        'received_at': DateTime.now().toIso8601String()
      }
    });

    // Track notification tapped
    UserBoost.event('push_notification_tapped', {
      'user': {'id': getCurrentUserId()},
      'properties': {
        'campaign_id': notification.campaignId,
        'action': 'open_app'
      }
    });
    ```
  </Tab>
</Tabs>

***

## Environment Setup

Configure your API keys for different environments:

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // config/index.js
    const config = {
      development: {
        USERBOOST_API_KEY: 'ub_live_your_dev_key_here',
      },
      production: {
        USERBOOST_API_KEY: 'ub_live_your_prod_key_here',
      }
    };

    export default config[process.env.NODE_ENV || 'development'];
    ```

    ```javascript theme={null}
    // App.js
    import config from './config';
    import UserBoost from '@userboost/react-native';

    UserBoost.init({
      apiKey: config.USERBOOST_API_KEY,
      debug: __DEV__,
    });
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    // lib/config.dart
    class Config {
      static const String apiKey = String.fromEnvironment(
        'USERBOOST_API_KEY',
        defaultValue: 'ub_live_your_dev_key_here'
      );

      static const bool debug = bool.fromEnvironment('DEBUG', defaultValue: true);
    }
    ```

    ```dart theme={null}
    // main.dart
    import 'config.dart';

    await UserBoost.init(
      apiKey: Config.apiKey,
      debug: Config.debug,
    );
    ```
  </Tab>
</Tabs>

***

## Testing & Debugging

### Debug Mode

Enable debug mode to see detailed logs:

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    UserBoost.init({
      apiKey: 'your_key',
      debug: true, // or __DEV__
    });

    // Enable verbose logging
    UserBoost.setLogLevel('verbose');
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    await UserBoost.init(
      apiKey: 'your_key',
      debug: true, // or kDebugMode
    );

    // Enable verbose logging
    UserBoost.setLogLevel(LogLevel.verbose);
    ```
  </Tab>
</Tabs>

### Test Events

Send test events to verify your integration:

<Tabs>
  <Tab title="React Native">
    ```javascript theme={null}
    // Send test event
    UserBoost.event('mobile_integration_test', {
      user: { id: `test_user_${Date.now()}` },
      properties: {
        test: true,
        platform: Platform.OS,
        timestamp: new Date().toISOString()
      }
    });
    ```
  </Tab>

  <Tab title="Flutter">
    ```dart theme={null}
    // Send test event
    UserBoost.event('mobile_integration_test', {
      'user': {'id': 'test_user_${DateTime.now().millisecondsSinceEpoch}'},
      'properties': {
        'test': true,
        'platform': Platform.operatingSystem,
        'timestamp': DateTime.now().toIso8601String()
      }
    });
    ```
  </Tab>
</Tabs>

***

## Common Issues

<AccordionGroup>
  <Accordion title="Events not appearing in dashboard" icon="exclamation-triangle">
    **Check these common causes:**

    * Using server-side API key instead of client-side key
    * Missing required `user.id` field
    * Network connectivity issues
    * App is in background (some events may be queued)

    **Enable debug mode to see detailed error messages.**
  </Accordion>

  <Accordion title="SDK installation issues" icon="package">
    **React Native:**

    ```bash theme={null}
    # Clear cache and reinstall
    npx react-native clean
    rm -rf node_modules
    npm install

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

    **Flutter:**

    ```bash theme={null}
    # Clear cache and reinstall
    flutter clean
    flutter pub get
    ```
  </Accordion>

  <Accordion title="Events queued but not sending" icon="wifi">
    * Check internet connectivity
    * Verify API key is correct
    * Force flush the queue: `UserBoost.flush()`
    * Check if app has background execution permissions
  </Accordion>
</AccordionGroup>

***

## What's Next?

<CardGroup cols={2}>
  <Card title="Track Events" icon="activity" href="/tracking/events">
    Learn mobile-specific event tracking patterns and best practices.
  </Card>

  <Card title="API Reference" icon="book" href="/api/rest-examples">
    Complete API documentation for REST integration.
  </Card>
</CardGroup>

Your mobile app is now tracking user events! UserBoost will automatically build user journey funnels and help you identify where users get stuck in your mobile onboarding flow.
