Flutter: i18n Made Easy

Tien Do Nam
The Startup
Published in
2 min readJul 27, 2020

--

At the time of writing, the “basic” i18n approach in Flutter is complicated and heavyweight. That’s why I decided to start my own library: slang

Step 1: Add dependencies

Add slang and slang_flutter to your dependencies:

dependencies:
slang: 3.25.0
slang_flutter: 3.25.0

Step 2: Write JSON files

Now lets add some strings. Just make sure that they are inside the lib directory and all in one common package like lib/i18n/strings.i18n.json

Default Locale

File: strings.i18n.json{
"hello": "Hello $name",
"save": "Save",
"login": {
"success": "Logged in successfully",
"fail": "Logged in failed"
}
}

German Locale

File: strings_de.i18n.json{
"hello": "Hallo $name",
"save": "Speichern",
"login": {
"success": "Login erfolgreich",
"fail": "Login fehlgeschlagen"
}
}

Step 3: Generate the dart code

This will translate the .json files into .dart files.

dart run slang

Step 4: Initialize the right language

Users expect that your app shows the right language at the start of the app.

There are 2 methods to set the locale: LocaleSettings.useDeviceLocale() and LocaleSettings.setLocaleRaw(String locale) . It is up to you how you implement it.

a) use device locale

void main() {
WidgetsFlutterBinding.ensureInitialized();
LocaleSettings.useDeviceLocale();
runApp(MyApp());
}

b) use specific locale

@override
void initState() {
super.initState();
String storedLocale = loadFromStorage(); // your logic here
LocaleSettings.setLocaleRaw(storedLocale);
}

Step 4b: iOS-only

There is one small change needed for iOS users:

File: ios/Runner/Info.plist<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>de</string>
</array>

Step 5: Finally use your translations!

That’s all! In the generated dart file you will see the famous t variable.

While most libraries goes for the t('somekey.anotherKey.blabla') solution with a plain string, the approach of slang is 100% safe, and it has nice autocompletion. Let’s try this out:

import 'package:my_app/i18n/strings.g.dart'; // import

String a = t.login.success; // plain
String b = t.hello(name: 'Tom'); // with argument
String c = t.step[3]; // with index (for arrays)
String d = t.type['WARNING']; // with key (for maps)

// advanced
TranslationProvider(child: MyApp()); // wrap your app
// [...]
final t = Translations.of(context); // get translation instance
String translateAdvanced = t.hello(name: 'Tom');

Supported Features

  • String Interpolation, e.g. t.hello(name: 'Tom')
  • Pluralization, e.g. t.apples(count: 3)
  • Gender, e. t.greet(context: Gender.male)
  • Arrays, e.g. t.step[2]
  • Maps, e.g. t.group['LEADER']
  • Fully Dynamic, e.g. t['homeScreen.title']

More info at

https://pub.dev/packages/slang

--

--