Better I18NBetter I18N

React

Content analytics for vanilla React (Vite, CRA, Remix client, etc.)

The React adapter is framework-agnostic — use it with Vite, CRA, Remix client routes, or any React setup that isn't Next.js, Expo, or RSC.

Install

npm 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 .env. Find both in the dashboard under Settings → General and Settings → API Keys.

.env
VITE_BETTER_I18N_PROJECT_ID=your-org/your-project
VITE_BETTER_I18N_KEY=bi_pub_xxxxx

Setup

src/main.tsx
import { ContentProvider } from '@better-i18n/content/adapters/react'
import App from './App'

createRoot(document.getElementById('root')!).render(
  <ContentProvider
    config={{
      projectId: import.meta.env.VITE_BETTER_I18N_PROJECT_ID,
      apiKey: import.meta.env.VITE_BETTER_I18N_KEY,
    }}
  >
    <App />
  </ContentProvider>
)

Track a view

src/routes/blog-post.tsx
import { useTrackView } from '@better-i18n/content/adapters/react'

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

  return <article>{post.body}</article>
}

Imperative tracking

For non-view events (clicks, conversions), use the useTrack hook:

import { useTrack } from '@better-i18n/content/adapters/react'

function CtaButton({ entryId }: { entryId: string }) {
  const track = useTrack()
  return (
    <button onClick={() => track('content.cta_click', { entryId })}>
      Sign up
    </button>
  )
}

Next steps

On this page