Integrations
Cross-Platform Integration
langctl writes Flutter ARB files and the JSON that React Native apps load with i18next.
Flutter Integration
Pull ARB Files
# once per repo: writes langctl.json
langctl init --project my-app --format arb
# then, whenever translations change
langctl pull
# + lib/l10n/app_en.arb created
# + lib/l10n/app_es.arb created
# + lib/l10n/app_pt_BR.arb created The default path is lib/l10n/app_{lang_}.arb, so pt-BR becomes app_pt_BR.arb. Message ids become Dart identifiers (home.welcome → homeWelcome), {{name}} placeholders become {name} and are declared in the @homeWelcome metadata, and key descriptions are written as description.
Configure Flutter
# pubspec.yaml
flutter:
generate: true
dependencies:
flutter_localizations:
sdk: flutter
intl: any
# l10n.yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
nullable-getter: false Use Translations
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.homeWelcome)),
body: Text(l10n.homeSubtitle),
);
}
} React Native Integration
React Native apps use the regular json format — there is no separate React Native format:
npm install i18next react-i18next
langctl init --project my-app --format json --output "src/locales/{lang}.json"
langctl pull // i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './locales/en.json';
import es from './locales/es.json';
i18n
.use(initReactI18next)
.init({
resources: {
en: { translation: en },
es: { translation: es }
},
lng: 'en',
fallbackLng: 'en',
compatibilityJSON: 'v3'
});
export default i18n;
// App.tsx
import { useTranslation } from 'react-i18next';
import './i18n';
export default function App() {
const { t, i18n } = useTranslation();
return (
<View>
<Text>{t('home.welcome', { username: 'John' })}</Text>
<Button title="Español" onPress={() => i18n.changeLanguage('es')} />
</View>
);
} CI/CD
name: Flutter Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- uses: subosito/flutter-action@v2
- name: Pull Translations
env:
LANGCTL_API_KEY: ${{ secrets.LANGCTL_API_KEY }}
run: npx langctl@0 pull # uses langctl.json
- name: Build
run: flutter build apk Tip
Flutter automatically generates type-safe localization code from ARB files. Run `flutter gen-l10n` to regenerate after updating translations.
Next Steps
- Mobile Integration - Native iOS/Android
- Web Integration - Web frameworks
- CI/CD - Automated workflows