Phase
Get Started

Expo

llms.txt

Installation

Install the SDK

npm install phase-analytics
bun add phase-analytics
yarn add phase-analytics
pnpm add phase-analytics

Install Required Peer Dependencies

Phase Analytics requires the following Expo packages to function properly:

npx expo install @react-native-async-storage/async-storage @react-native-community/netinfo expo-application expo-device expo-localization expo-router
bunx expo install @react-native-async-storage/async-storage @react-native-community/netinfo expo-application expo-device expo-localization expo-router
yarn dlx expo install @react-native-async-storage/async-storage @react-native-community/netinfo expo-application expo-device expo-localization expo-router
pnpm dlx expo install @react-native-async-storage/async-storage @react-native-community/netinfo expo-application expo-device expo-localization expo-router

These dependencies are required for the SDK to work correctly. The SDK uses:

  • @react-native-async-storage/async-storage - Local storage for offline event queuing
  • @react-native-community/netinfo - Network state monitoring
  • expo-application - App version collection (app_version)
  • expo-device - Device information collection
  • expo-localization - Locale and timezone detection
  • expo-router - Automatic screen tracking

Get Your API Key

  1. Sign in to Phase Dashboard
  2. Create a new project or select an existing one
  3. Open API Keys tab
  4. Copy your API Key (starts with phase_)

Setup

Wrap your app with the PhaseProvider component in your root layout to initialize the SDK:

React
app/_layout.tsx
import { PhaseProvider } from 'phase-analytics/expo';

export default function RootLayout() {
  return (
    <PhaseProvider
      apiKey="phase_xxx"
    >
      <Stack />
    </PhaseProvider>
  );
}

The PhaseProvider only initializes the SDK. You must call Phase.identify() before tracking events.

Configuration

The PhaseProvider component accepts the following props:

Prop

Type

Usage

Identify User

Required: Call Phase.identify() before using any other methods. This registers the device and starts a session.

React
app/index.tsx
import { Phase } from 'phase-analytics/expo';
import { useEffect } from 'react';

export default function App() {
  useEffect(() => {
    // Initialize analytics - no PII collected by default
    Phase.identify();
  }, []);

  return <YourApp />;
}

Privacy by default:

  • No personal data is collected without explicit properties
  • Device ID is auto-generated and stored locally
  • Only technical metadata is collected (OS version, platform, locale)

Adding custom properties:

You can optionally attach user properties. Important: If you add PII (personally identifiable information), ensure you have proper user consent:

// After user login and consent
await Phase.identify({
  user_id: '123',
  plan: 'premium',
  beta_tester: true
});

// ⚠️ If adding PII, get consent first
const hasConsent = await customGetUserConsent();
if (hasConsent) {
  await Phase.identify({
    email: '[email protected]',
    name: 'John Doe'
  });
}

Properties must be primitives: string, number, boolean, or null.

Track Events

Track custom events with optional parameters. Note: Phase.identify() must be called first.

// Event without parameters
Phase.track('app_opened');

// Event with parameters
Phase.track('purchase_completed', {
  amount: 99.99,
  currency: 'USD',
  product_id: 'premium_plan'
});

Event naming rules:

  • Alphanumeric characters, underscores (_), hyphens (-), periods (.), forward slashes (/), and spaces
  • 1-256 characters
  • Examples: purchase, user.signup, payment/success, Button Clicked

Event parameters:

  • Flat primitive object only
  • Values must be string, number, boolean, or null
  • Max 32 keys
  • Key max 32 characters
  • String value max 256 characters
  • Serialized payload max 8 KB
  • Empty objects are normalized away

Automatic Screen Tracking

Enable automatic screen tracking by setting trackNavigation to true in your root layout. The SDK uses Expo Router's navigation hooks to track screen changes automatically:

React
app/_layout.tsx
import { PhaseProvider } from 'phase-analytics/expo';
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <PhaseProvider
      apiKey="phase_xxx"
      trackNavigation={true}
    >
      <Stack />
    </PhaseProvider>
  );
}

How it works:

  • Wraps any Expo Router component (Stack, Tabs, Drawer, etc.)
  • Automatically tracks screen views on route changes
  • Screen names are derived from pathname
  • Works with nested routes and dynamic segments

No additional setup required, just wrap your navigation structure with PhaseProvider.

Type Reference

DeviceProperties

Custom user/device attributes passed to Phase.identify():

Prop

Type

EventParams

Event parameters passed to Phase.track():

Prop

Type

How It Works

Offline Support

Events are queued locally using @react-native-async-storage/async-storage when offline. The queue automatically syncs when connection is restored.

Privacy

  • No personal data is collected by default
  • Device IDs are generated locally and stored persistently
  • Geolocation is resolved server-side from IP address (disable with properties)
  • All data collection is optional via configuration

Performance

  • Offline events are batched and sent asynchronously
  • Network state is monitored via @react-native-community/netinfo
  • Failed requests retry with exponential backoff
  • Maximum batch size: 1000 events