Translations
Configure i18next translations in apps/mobile with package translation filters.
What It Does
apps/mobile uses @kit/i18n with i18next and a custom resolver to merge:
- app-local namespaces (
apps/mobile/locales/*), - package namespaces injected through filters (
get_translations).
When To Use
- You need multilingual UI in the mobile app.
- You need to consume translation namespaces coming from kit packages.
Prerequisites
@kit/i18ninstalled.apps/mobile/config/i18n.config.tsconfigured.I18nProvidermounted in root provider.
This feature is implemented through the shared @kit/i18n package. Mobile setup mainly wires provider + resolver + namespaces.
How To Use
Define mobile i18n config and resolver.
import { parseI18nConfig } from '@kit/i18n/config'; import { DEFAULT_LANG, SUPPORTED_LANGS } from '@kit/shared/config/defined-languages'; import { applyAsyncFilter } from '@kit/utils/filters'; import enCommon from '../locales/en/common.json'; import frCommon from '../locales/fr/common.json'; const translations = { en: { common: enCommon }, fr: { common: frCommon }, }; async function i18nResolver(language: keyof typeof translations, namespace: string) { const packageTranslations = await applyAsyncFilter('get_translations', null, { language, namespace, }); if (packageTranslations) { return packageTranslations; } const lang = language in translations ? language : 'en'; const ns = (namespace in translations[lang] ? namespace : 'common') as keyof (typeof translations)[typeof lang]; return translations[lang][ns] as Record<string, string>; } export const i18nConfig = parseI18nConfig({ defaultLanguage: DEFAULT_LANG, languages: SUPPORTED_LANGS, namespaces: ['common', 'client', 'notification', 'order', 'product'], resolver: i18nResolver as (lang: string, namespace: string) => Promise<Record<string, string>>, });
Mount provider at app root.
import { I18nProvider } from '@kit/i18n/shared/provider';
import { i18nConfig } from '~/config/i18n.config';
import { getLocales } from 'expo-localization';
const locale = getLocales()[0];
const lang = locale?.languageCode;
<I18nProvider config={i18nConfig} lang={lang ?? undefined}>
{children}
</I18nProvider>Use translations in components.
import { useTranslation } from 'react-i18next';
export function SettingsTitle() {
const { t } = useTranslation('common');
return <Text>{t('settings.title')}</Text>;
}Package Translations
applyAsyncFilter('get_translations', ...) is the integration point that lets package-level translations be resolved without duplicating JSON files in each app.
If a requested namespace is provided by a package filter, the resolver uses it first. App-local fallback runs only when package translations are not returned.
Filter API
Mobile translation composition is driven by client filters resolved through applyAsyncFilter('get_translations', ...).
| Filter | Parameters | Return | Registered By (package file) | Initialized In (app entrypoint) | Environment |
|---|---|---|---|---|---|
get_translations | { language: string; namespace: string } | Record<string, string> | null | kit/auth/src/native/filters/use-filters/use-translation-filters.tsx, kit/organization/src/native/filters/use-filters/use-translation-filters.tsx | apps/mobile/hooks/use-filters.ts (useAuthFilters, useOrgFilters) | client |
- Keep
useAuthFilters()anduseOrgFilters({ clientTrpc, orgConfig })inapps/mobile/hooks/use-filters.ts. - Keep
applyAsyncFilter('get_translations', ...)inapps/mobile/config/i18n.config.ts.
MCP Context
capability: i18n_mobile_setup entrypoints: - apps/mobile/config/i18n.config.ts - apps/mobile/components/providers/root-provider.tsx - apps/mobile/hooks/use-filters.ts - kit/auth/src/native/filters/use-filters/use-translation-filters.tsx - kit/organization/src/native/filters/use-filters/use-translation-filters.tsx - apps/mobile/locales/* inputs: - language_code - namespace outputs: - translated_mobile_ui_strings constraints: - namespace must be declared in i18nConfig.namespaces - resolver should fallback to default language/namespace for missing keys side_effects: - none
Agent Recipe
- Add/update locale JSON files under
apps/mobile/locales. - Keep resolver fallback logic and package translation filter call in
i18n.config.ts. - Ensure provider is mounted at root before translated components render.
Troubleshooting
- If all keys render raw (
foo.bar), verifyI18nProvideris mounted in root provider. - If package namespaces do not resolve, verify
get_translationsfilters are initialized. - If language fallback is wrong, verify default language and supported language list.
Related
Configure and extend the mobile onboarding flow with schema, step config, and filters.
Build native settings navigation and pages with @kit/settings in apps/mobile.
How is this guide?
Last updated on 3/27/2026