Skip to main content
Shipnative includes comprehensive monitoring with PostHog for analytics and Sentry for error tracking. All utilities are pre-built and ready to use.

Setup

yarn setup
The wizard prompts for your PostHog API key and host URL. Or manually add to apps/app/.env:
EXPO_PUBLIC_POSTHOG_API_KEY=your_api_key
EXPO_PUBLIC_POSTHOG_HOST=https://app.posthog.com
Without keys: Mock mode logs events to console. Connect real PostHog early to capture usage data.

Usage

useAnalytics Hook

import { useAnalytics } from '@/hooks/useAnalytics'

function MyComponent() {
  const { trackEvent, trackScreen, isFeatureEnabled } = useAnalytics()

  // Track events
  trackEvent('button_clicked', { button: 'submit' })

  // Track screens
  trackScreen('HomeScreen')

  // Feature flags
  if (isFeatureEnabled('new-feature')) {
    // Show feature
  }
}

Utility Functions

For use outside React components:
import {
  trackEvent,
  trackScreen,
  identifyUser,
  clearUser,
} from '@/utils/analytics'

trackEvent('purchase_completed', { amount: 9.99 })
trackScreen('ProductScreen', { product_id: '123' })
identifyUser('user-123', { email: 'user@example.com' })
clearUser()  // on logout

Direct Client Access

import { posthog } from '@/services/posthog'

posthog.track('event_name', { property: 'value' })
posthog.identify('user-id', { email: 'user@example.com' })

Feature Flags

const { isFeatureEnabled, getFeatureFlag } = useAnalytics()

// Boolean flag
if (isFeatureEnabled('dark-mode-v2')) {
  // Use new dark mode
}

// Multivariate flag
const variant = getFeatureFlag('pricing-test')  // 'control' | 'variant-a'
Create flags in PostHog Dashboard → Feature Flags. See PostHog Feature Flags.

Pre-built Event Helpers

import { trackAuth, trackSubscription } from '@/utils/analytics'

// Auth events
trackAuth.signupCompleted('user-123', { method: 'email' })
trackAuth.loginCompleted('user-123', { method: 'google' })
trackAuth.logout()

// Subscription events
trackSubscription.started({ plan: 'pro_monthly' })
trackSubscription.completed({ plan: 'pro_monthly', price: 9.99 })

Testing

Mock mode: Events logged to console as [MockPostHog] Event: ... Real PostHog:
  1. Add API key and host to .env
  2. Trigger events in app
  3. View in PostHog Dashboard → Events / Persons

Troubleshooting

Events not showing in PostHog?
  • Verify API key and host are correct
  • Allow a few minutes for events to process
  • Check console for PostHog errors
Still in mock mode?
  • Verify apps/app/.env has correct keys
  • Restart Metro: yarn start --clear
For more, see PostHog React Native SDK.

Error Tracking with Sentry

Sentry automatically captures JavaScript errors, native crashes, and performance issues. It’s configured to work seamlessly with your app.

Setup

Run the setup wizard:
yarn setup
The wizard will prompt for your Sentry DSN. Or manually add to apps/app/.env:
SENTRY_DSN=your_sentry_dsn
Without DSN: Mock mode logs errors to console. Connect real Sentry early to catch production issues.

Automatic Error Capture

Sentry automatically captures:
  • JavaScript errors - Unhandled exceptions and promise rejections
  • Native crashes - iOS and Android native errors
  • React errors - Component render errors via Error Boundaries
  • Performance issues - Slow screens and network requests
No additional code needed - errors are automatically reported.

Manual Error Reporting

Capture errors manually with context:
import * as Sentry from '@sentry/react-native'

try {
  processPayment(data)
} catch (error) {
  Sentry.captureException(error, {
    level: 'error',
    tags: { section: 'payments' },
    extra: { userId: user.id, amount: 9.99 },
  })
}
Add breadcrumbs for debugging context:
import * as Sentry from '@sentry/react-native'

Sentry.addBreadcrumb({
  category: 'navigation',
  message: 'User navigated to Profile',
  level: 'info',
  data: {
    from: 'Home',
    to: 'Profile',
  },
})

User Context

Associate errors with users:
import * as Sentry from '@sentry/react-native'

// Set user (on login)
Sentry.setUser({
  id: user.id,
  email: user.email,
  username: user.name,
})

// Clear user (on logout)
Sentry.setUser(null)

Performance Monitoring

Track custom operations:
import * as Sentry from '@sentry/react-native'

// Track async operation
await Sentry.startSpan(
  {
    name: 'fetch-user-data',
    op: 'http.client',
  },
  async (span) => {
    const response = await fetch('https://api.example.com/users')
    const data = await response.json()

    span?.setAttribute('http.status_code', response.status)
    span?.setAttribute('user.count', data.length)

    return data
  }
)

Utility Functions

Pre-built helpers in utils/crashReporting.ts:
import { logError, logWarning, logInfo } from '@/utils/crashReporting'

logError('Payment failed', { userId: '123', amount: 9.99 })
logWarning('Slow network detected', { latency: 5000 })
logInfo('Feature flag evaluated', { flag: 'new-ui', value: true })

Testing Sentry

Trigger a test error:
import * as Sentry from '@sentry/react-native'

// Capture test error
Sentry.captureMessage('Test error from app', {
  level: 'error',
  tags: { test: true },
})

// Or throw error
throw new Error('Test native crash')
View errors in Sentry Dashboard → Issues.

Filtering Errors

Configure what gets reported in services/sentry.ts:
Sentry.init({
  beforeSend: (event, hint) => {
    // Filter out specific errors
    if (event.exception?.values?.[0]?.value?.includes('Network request failed')) {
      return null  // Don't send
    }

    // Remove sensitive data
    if (event.user) {
      delete event.user.email
    }

    return event
  },
})

Production Best Practices

  1. Environment tagging - Automatically set via EXPO_PUBLIC_ENV
  2. Release tracking - Set release version for tracking issues across versions
  3. Source maps - Uploaded automatically for readable stack traces
  4. User privacy - Avoid sending PII (personally identifiable information)
For more, see Sentry React Native SDK.