Provider
Configure the BetterI18nProvider for your application
Basic Usage
With Vite Plugin (zero config)
When using @better-i18n/vite, the provider reads everything from the injected <script> tag — no props needed:
import { BetterI18nProvider } from '@better-i18n/use-intl'
function App() {
return (
<BetterI18nProvider>
<YourApp />
</BetterI18nProvider>
)
}Without Plugin (manual config)
import { BetterI18nProvider } from '@better-i18n/use-intl'
function App() {
return (
<BetterI18nProvider
project="your-org/your-project"
locale="en"
>
<YourApp />
</BetterI18nProvider>
)
}Props
| Prop | Type | Required | Description |
|---|---|---|---|
project | string | With plugin: auto | Project identifier in org/project format |
locale | string | With plugin: auto | Current locale code (e.g., "en", "tr") |
messages | Messages | Pre-loaded messages (for SSR) | |
localePrefix | "always" | "as-needed" | URL prefix strategy (default: "as-needed") | |
timeZone | string | Timezone for date formatting | |
now | Date | Current time (for SSR hydration) | |
localeCookie | boolean | string | Persist locale to cookie. true = "locale", string = custom name | |
onLocaleChange | (locale: string) => void | Callback when locale changes | |
onError | (error: IntlError) => void | Error handler for missing translations | |
cdnBaseUrl | string | Custom CDN URL | |
debug | boolean | Enable debug logging | |
logLevel | LogLevel | Logging verbosity |
When using the @better-i18n/vite plugin, project, locale, messages, and languages are all injected automatically via a <script> tag. You only need to pass props that you want to override.
Client-Side Rendering
For CSR apps, messages are fetched automatically:
function App() {
const [locale, setLocale] = useState('en')
return (
<BetterI18nProvider
project="org/project"
locale={locale}
onLocaleChange={setLocale}
>
<YourApp />
</BetterI18nProvider>
)
}Without pre-loaded messages, children won't render until messages are fetched from the CDN.
Server-Side Rendering
For SSR, pre-load messages to prevent flash of untranslated content:
import { getMessages } from '@better-i18n/use-intl/server'
// In your loader
const messages = await getMessages({
project: 'org/project',
locale: 'en',
})
// In your component
<BetterI18nProvider
project="org/project"
locale="en"
messages={messages}
timeZone="UTC"
>
<YourApp />
</BetterI18nProvider>Timezone Requirement: For SSR, always set timeZone to prevent hydration mismatches. Use "UTC" as a safe default.
Locale Persistence
Use the localeCookie prop to persist the user's language choice across page refreshes:
<BetterI18nProvider
project="org/project"
localeCookie
>
<App />
</BetterI18nProvider>This does two things:
- Writes a cookie on every locale change (including initial mount)
- Reads the cookie on initialization as a fallback (for SPA/static builds)
Options
| Value | Cookie Name | Use Case |
|---|---|---|
true | "locale" | Most apps — simple default |
"preferred-locale" | "preferred-locale" | Custom name to match your server |
false (default) | — | SSR apps with middleware (cookie handled server-side) |
Server-side pairing
Use the same cookie name on both client and server:
<BetterI18nProvider localeCookie="preferred-locale" />createBetterAuthProvider(i18n, { localeCookie: "preferred-locale" })betterI18n({ localeCookie: "preferred-locale" })The cookie name must match across client and server. When using localeCookie (boolean true), the default name is "locale".
Non-React contexts
Read the cookie outside React (auth clients, analytics, fetch wrappers):
import { getLocaleCookie } from "@better-i18n/core";
const locale = getLocaleCookie("locale"); // → "tr" | nullSee Better Auth integration for the full pattern.
## Error Handling
Handle missing translations gracefully:
```tsx
<BetterI18nProvider
project="org/project"
locale="en"
onError={(error) => {
if (process.env.NODE_ENV === 'development') {
console.warn(`Missing translation: ${error.message}`)
}
// In production, you might want to report to error tracking
}}
>
<YourApp />
</BetterI18nProvider>Debug Mode
Enable debug logging during development:
<BetterI18nProvider
project="org/project"
locale="en"
debug={process.env.NODE_ENV === 'development'}
logLevel="debug"
>
<YourApp />
</BetterI18nProvider>This logs:
- CDN requests and responses
- Cache hits and misses
- Locale changes
- Message loading states
Custom CDN
For enterprise or self-hosted deployments:
<BetterI18nProvider
project="org/project"
locale="en"
cdnBaseUrl="https://cdn.your-company.com"
>
<YourApp />
</BetterI18nProvider>Types
interface BetterI18nProviderConfig {
project: string
locale: string
messages?: Messages
timeZone?: string
now?: Date
onLocaleChange?: (locale: string) => void
onError?: (error: IntlError) => void
cdnBaseUrl?: string
debug?: boolean
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent'
}
type Messages = {
[namespace: string]: {
[key: string]: string | Messages
}
}Related
- Locale Management - Access locale from context
- Server Utilities - Pre-load messages for SSR
- Translations - Access translations in components