Slang as Localization

Today, it has become a must for widely-used applications to have some basic features like dark mode, different localizations and many more. That is why, most experienced engineers always start the application with architecting these basic features, leaving room for further implementation. There are many choices out there to implement localization in Flutter application. In this article, let's talk about the way I like to implement one using Slang.
Firstly, let's create a sample project:
flutter create slang_project

Now, let's create packages directory to hold private packages of the app and create app_localization package in it.
cd packages && flutter create --template=package app_localization

It is time to add slang packages in pubspec.yaml.
name: app_localization
description: This package contains app localization.
environment:
sdk: ">=3.0.0 <4.0.0"
dependencies:
slang: ^4.4.0
slang_flutter: ^4.4.0
dev_dependencies:
build_runner: ^2.4.14
slang_build_runner: ^4.4.0
pubspec.yaml
Now, let's add the build_runner configuration for the slang in build.yaml file. For more custom configuration, please refer here.
targets:
$default:
builders:
slang_build_runner:
options:
base_locale: en
fallback_strategy: base_locale
input_directory: lib
input_file_pattern: .i18n.json
output_directory: lib
output_file_pattern: .g.dart
translate_var: tr
build.yaml
We can add create json files for translations in lib directory and populate them.
{
"welcomeMessage": "Welcome to the application!",
"changeLocale": "Change locale here"
}
string_en.i18n.json
{
"welcomeMessage": "Добро пожаловать в приложение!",
"changeLocale": "Измените локализацию здесь"
}
string_ru.i18n.json
Now, go to app_localization directory and run slang build runner as below and it will generate necessary classes to use in the app.
cd app_localization && dart run slang

It is time to import the private app_localization package into our main app, for this in main app's pubspec.yaml file import as below and run flutter pub get:
...
dependencies:
flutter:
sdk: flutter
flutter_localizations: // add this
sdk: flutter
cupertino_icons: ^1.0.8
app_localization: // add this
path: packages/app_localization
...
pubspec.yaml
In main.dart, wrap MyApp() with TranslationProvider and add recommended necessary import path:
import 'package:app_localization/strings.g.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(
TranslationProvider(
child: const MyApp(),
),
);
}
main.dart
And add locale lines in MaterialApp as below:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
locale: TranslationProvider.of(context).flutterLocale,
supportedLocales: AppLocaleUtils.supportedLocales,
localizationsDelegates: GlobalMaterialLocalizations.delegates,
home: const MyHomePage(title: 'Slang Demo'),
);
}
}
Add the supported locales to your Info.plist file.
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>ru</string>
</array>
ios/Runner/Info.plist
From now on, our app supports en and ru localizations, and this list can be further expanded by adding new localized json files in the app_localization directory and that's it. We change the locale using the method:
LocaleSettings.setLocale(AppLocale.en);
MyHomePage widget would look like this:
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
context.tr.welcomeMessage,
),
const SizedBox(height: 32),
InkWell(
onTap: () {
if (LocaleSettings.currentLocale == AppLocale.en) {
LocaleSettings.setLocale(AppLocale.ru);
} else {
LocaleSettings.setLocale(AppLocale.en);
}
},
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.circular(16),
),
child: Text(context.tr.changeLocale),
),
),
],
),
),
);
}
}
Output:
What is left is to add logic to save the selected locale in local storage and set it at the beginning of the application. I leave it for you...
For more features and configuration, please go through the documentation:

Full example is at the link below: