Better I18NBetter I18N

Expo

Content analytics for React Native and Expo, with AppState-aware flushing

The Expo adapter wraps the React Native API and flushes pending events when the app goes to background. It uses fetch (React Native has no sendBeacon).

Install

npx expo install @better-i18n/content
bun add @better-i18n/content
pnpm add @better-i18n/content
yarn add @better-i18n/content

Configure

Add your Project ID and API key to app.config.ts (or app.json). Find both in the dashboard under Settings → General and Settings → API Keys.

app.config.ts
export default {
  extra: {
    betterI18nProjectId: 'your-org/your-project',
    betterI18nKey: process.env.BETTER_I18N_KEY,
  },
}

Setup

App.tsx
import { ContentProvider } from '@better-i18n/content/adapters/expo'
import Constants from 'expo-constants'

export default function App() {
  return (
    <ContentProvider
      config={{
        projectId: Constants.expoConfig?.extra?.betterI18nProjectId,
        apiKey: Constants.expoConfig?.extra?.betterI18nKey,
      }}
    >
      <Navigation />
    </ContentProvider>
  )
}

Track a view

screens/BlogPost.tsx
import { useTrackView } from '@better-i18n/content/adapters/expo'

export function BlogPostScreen({ post }) {
  useTrackView('content.view', {
    entryId: post.id,
    contentModel: 'blog',
    entrySlug: post.slug,
    language: post.locale,
  })

  return <View>...</View>
}

AppState flushing

When the app transitions to background or inactive, the SDK flushes any pending events via AppState.addEventListener. You don't need to wire this up — ContentProvider handles it.

Next steps

On this page