Managing arb Files for Flutter App's Multilingual Support in yaml Format
Introduction
I have incorporated multilingual support in my personal subscription management app subskun developed with Flutter.
The multilingual support was implemented according to the official Flutter documentation. However, as the app’s features increased, the arb file for multilingual settings became large and less readable. Despite implementing measures like prefixing, managing became cumbersome.
Hence, I decided to split the multilingual configuration file by feature.
About the Package Used
Upon research, the slang
package seemed usable.
It’s a feature-rich package. Not only does it support file splitting, but it also allows you to write multilingual configuration files in json, yaml, and csv formats.
Originally, with arb files, I couldn’t write comments. So, I chose to create using yaml, which supports in-file commenting. However, upon reflection, if splitting by feature eliminates the need for comments, the simpler json format might also suffice.
Setup
The official README is comprehensive, which should suffice for most needs. In this article, I will write about my own experience with splitting files by feature into yaml format.
Install the Package
When using Flutter, the slang_flutter
package is also required. The latest version at the moment is 3.7.0
.
dependencies:
slang: 3.7.0
slang_flutter: 3.7.0
Create yaml Files by Feature
Naming convention for files is as follows. The <namespace>
part must be in camel case.
<namespace>_<locale?>.<extension>
I created files in the following manner, but various directory structures seem possible.
lib/i18n/
└── feature1/
└── feature1_en.yaml
└── feature1_ja.yaml
└── feature2/
└── feature2_en.yaml
└── feature2_ja.yaml
# This is also OK.
lib/i18n/
└── feature1_en.yaml
└── feature1_ja.yaml
└── feature2_en.yaml
└── feature2_ja.yaml
# This is also OK.
lib/i18n/
└── en/
└── feature1.yaml
└── feature2.yaml
└── ja/
└── feature1.yaml
└── feature2.yaml
In this example, the content of the yaml file is as follows. By embedding in the form of ${}
, variables can be handled similarly to Dart string variables.
# Contents of feature1_en.yaml
header: Header
content: This is ${content}
# Contents of feature1_ja.yaml
header: ヘッダー
content: これは${content}
Note that changing the embedded variable format is possible by adjusting settings. Details can be found at:
Create a Configuration File for slang
Additional settings are required to enable file splitting and the use of yaml format. Place slang.yaml
or build.yaml
directly under the project. Below is an example of the slang.yaml
setup.
namespaces: true # Enables file splitting
input_directory: lib/i18n
input_file_pattern: .yaml # The default is json, so if you're using another format, you need to specify it
output_directory: lib/i18n
output_file_name: translations.g.dart
Setup Inside the Code
Lastly, configure the code to use slang.
// Entry point
void main() {
WidgetsFlutterBinding.ensureInitialized();
LocaleSettings.useDeviceLocale();
runApp(TranslationProvider(child: MyApp()));
}
// Where MaterialApp is used
MaterialApp(
locale: TranslationProvider.of(context).flutterLocale,
supportedLocales: LocaleSettings.supportedLocales,
localizationsDelegates: GlobalMaterialLocalizations.delegates,
child: FirstScreen(),
)
Build
Now, you can build using the following command:
flutter pub run slang
This generates a file named lib/i18n/translations.g.dart
. Output destination and file name can be changed in the settings.
Using it
You can import the generated file and use it as shown below. You can also use directory names split by function as namespaces and pass arguments.
import 'package:hoge/i18n/translations.g.dart';
final header = t.feature1.header;
final content = t.feature1.content(content: 'content');
This seems much easier to use than the original AppLocalizations
, as it doesn’t require context
.
This t
variable can also be changed in settings. There’s a plethora of features and settings, so I recommend reading the README.
Conclusion
In conclusion, slang
allowed me to split multilingual setting files by feature, which has greatly improved manageability and readability. The decision to choose yaml also provides the flexibility of adding comments, which can be beneficial for understanding complex texts.
Managing translations can be daunting, but packages like slang
can simplify the process, especially for larger projects.
If you want to introduce multilingual support to your Flutter apps, consider the slang
package for its versatile features.