Table of Contents
  1. Language Selection
    1. Translator
    2. Text Direction
    3. Material & Cupertino
    4. Package
    5. Final Language Selection
  2. Translation Preparation
    1. Flutter Translation Preparation
    2. iOS Translation Preparation
    3. Store Translation Preparation
  3. Problems Encountered in Translation
    1. Screenshot Capture
    2. Text Line Breaks
    3. Translation Exclusion
    4. Translation Check
    5. Decrease Productivity
  4. Finish

Share the story of adding 72 languages to a Flutter project.
👉 한국어 버전

✔︎ Part 1. Flutter Multilingual Support - Ready
Part 2. Flutter Multilingual Support - Tool Making


I am running the VoCat - My Own Vocabulary app service using Flutter. Support Korean and English, but occasionally receive requests from foreign users to support other languages.

I love five stars ☺️I love five stars ☺️

At the same time, the Draw My Today - AI Picture Diary team, which was created as a side project, also talked about supporting more languages, so I started supporting multiple languages.

At this time, I didn't know it would take 3 months..🫠At this time, I didn't know it would take 3 months..🫠

Language Selection

First, let’s select a list of languages ​​to support.

Translator

Using a translator, you can easily support many languages ​​at a low cost, and in this project, Google Translate API supports 133 languages Let’s use.

Google Translate DeepL Papago
Support Languages 133 34 16

Text Direction

Languages ​​can be divided into LTR and RTL depending on the reading direction.

  • LTR(Left To Right) : Read from left to right, such as English
  • RTL(Right To Left) : Read from right to left, such as Arabic

In Flutter, you can check whether a specific language is RTL by using the isRtlLanguage method of the Intl package, and is supported by Google Translate. Based on the languages ​​spoken, there are 10 RTL languages(Arabic, Dhivehi, Hebrew, Pashto, Persian, Sindhi, Urdu, Uyghur, Yiddish, and Sorani).

<b>RTL</b> language <b>Kurdish(Sonari)</b> language seems to be returning an incorrect value, so I <a href=https://github.com/dart-lang/i18n/issues/827>reported</a>.RTL language Kurdish(Sonari) language seems to be returning an incorrect value, so I reported.

If you want to support an RTL language, you need to not only change the text direction, but also flip the overall UI itself left and right. If you pass the RTL language Locale to MaterialApp, the left and right sides will be automatically reversed, but the direction of the icon cannot be changed. A lot of effort is needed, including revising and fixing all constraints designed based on LTR.

<b>LTR</b> & <b>RTL</b> UI - <a href=https://m2.material.io/design/usability/bidirectionality.html#mirroring-layout>material.io</a>LTR & RTL UI - material.io

Material & Cupertino

Texts embedded in the Material and Cupertino widgets can support localization through the Flutter Localizations package.

Text embedded in Material3 DatePicker<br><a href=https://m2.material.io/design/usability/bidirectionality.html#mirroring-layout>material.io</a>Text embedded in Material3 DatePicker
material.io

Flutter Localization supports 79 languages for Material and 78 languages for Cupertino. If your project is using the built-in theme widget, consideration should be given when selecting a supported language.

If you want to add a language that is not supported by the package, you can inherit and implement the MaterialLocalizations and CupertinoLocalizations classes and pass them to the MaterialApp as the localizationsDelegates attribute.

Package

Multilingual support packages or packages with text embedded will need to be reviewed.

This project uses the Intl package to help with localization, such as date and plural. The Intl package supports 119 languages, but there is no way to add an unsupported language.

Final Language Selection

The above considerations can be summarized as follows.

Google Translate LTR & RTL Material & Cupertino Package
133 LTR(123)
RTL(10)
Material(79)
Cupertino(78)
Intl(119)

In order to support as many languages ​​as possible with minimal effort, I excluded RTL languages, found the intersection of each supported language, and selected the following 72 languages.

Afrikaans Albanian Amharic Armenian
Assamese Azerbaijani Basque Belarusian
Bengali Bosnian Bulgarian Burmese
Catalan Chinese (Simplified) Chinese (Traditional) Croatian
Czech Danish Dutch English
Estonian Finnish French Galician
Georgian German Greek Gujarati
Hindi Hungarian Icelandic Indonesian
Italian Japanese Kannada Kazakh
Khmer Korean Kyrgyz Lao
Latvian Lithuanian Macedonian Malay
Malayalam Marathi Mongolian Nepali
Norwegian Oriya Polish Portuguese
Punjabi Romanian Russian Serbian
Slovak Slovenian Spanish Sri Lankan
Swahili Swedish Tagalog Tamil
Telugu Thai Turkic Ukrainian
Uzbek Vietnamese Welsh Zulu

I’ve selected 72 languages, so let’s start supporting multiple languages.


Translation Preparation

Based on the Flutter app service, the scope of translation is as follows.

  1. In-app Translation
    • Flutter text
    • iOS permissions text
  2. Play Store & App Store Trnslation
    • Metadata
    • Changelog
    • Screenshot

Before proceeding with the translation, let’s set up a multilingual development environment.

Flutter Translation Preparation

You can create a Flutter text multilingual development environment by referring to the official Flutter document or utilizing the Flutter Intl extension(VSCode / Android Studio).

Once you have built a Flutter multilingual development environment, you will manage the text in each language in the form of an Application Resource Bundle (ARB) file.

iOS Translation Preparation

The iOS permission request text is managed by the iOS project, so multilingual support is possible only when you set up iOS Localization.

Run Xcode, add a language from RunnerInfoLocalizations, and add the Strings File under the Runner folder named InfoPlist.strings.

+ Press the button and add the language.+ Press the button and add the language.

Open the InfoPlist.strings file and select the language you want to translate in the Localization section on the right. This will create an InfoPlist.strings file under the ios/Runner/<language>.lproj folder and write the iOS permission request text for each language on that file.

Store Translation Preparation

Here’s what needs translation in Play Store and App Store. (Tablet and iPad screenshots can be omitted if not supported.)

Play Store App Store
Supported languages 87 39
Metadata title
short_description
full_description
name
subtitle
keywords
description
promotional_text
Changelogs build_version.txt release_notes.txt
Screenshots Grapic (1024x500)
Mobile (1242x2208)
Tablet 7-inch (2048x2732)
Tablet 10-inch (2048x2732)
iPhone 5.5 (1242x2208)
iPhone 6.5 (1284x2778)
iPad 12.9 2Gen (2048x2732)
iPad 12.9 3Gen (2048x2732)

In this project, Play Store supported 79 languages except for eight RTL languages and Romansh which are not supported by Google Translation, and App Store supported 37 languages except two RTL languages.

In addition, I have established a deployment automation environment using Fastlane’s upload_to_play_store and upload_to_app_store commands to easily upload store registration information.


Problems Encountered in Translation

As you proceed with translation work, you will encounter many problems.

Screenshot Capture

The VoCat service uses 8 images per device and supports tablets, so a total of 3,080 images(Play Store 1,896 + App Store 1,184) images are required.

Fastlane has the ability to automatically take screenshots from the simulator and frameit, which puts captured screenshots into device frames and puts text.

fastlane auto screenshot - <a href=https://docs.fastlane.tools/getting-started/ios/screenshots/#capture-screenshots-automatically>fastlane</a>fastlane auto screenshot - fastlane
.
fastlane device frame - <a href=https://docs.fastlane.tools/getting-started/ios/screenshots/#capture-screenshots-automatically>fastlane</a>fastlane device frame - fastlane

However, the above method takes 2 hours and 30 minutes just to take a screenshot, assuming it takes 3 seconds to capture one image, and has the problem of not being able to create a screen that does not exist in the app.

Text Line Breaks

Basic text is made by breaking lines when a line is full.

Basic text line breaks - <a href=https://clagnut.com/blog/2424>clagnut.com</a>Basic text line breaks - clagnut.com

On the other hand, balanced text line breaks have the effect of being more stable and readable, so you may intentionally put a line break symbol after a specific word or design it to maintain a specific number of lines.

Balanced line breaks - <a href=https://clagnut.com/blog/2424>clagnut.com</a>Balanced line breaks - clagnut.com

The problem is that the length of the text changes when translating, so the line breaks symbol (\n) is located incorrectly.

Translation Exclusion

ARB files use brackets to receive and display parameters in the form of {name}. The name of the parameter inside the brace must be the same in all 72 languages to work properly, but there is a problem with translating to the parameter name during translation.

1
2
"corpusAdded": "{word} Word added!",
"vocatFileImport": "Import VOCAT file",

In addition to parameter names, there are items that require translation exclusion, such as service names and email addresses.

Translation Check

In addition to the quality of the translation, there are items that need to be inspected.

  • Name of parameter : Whether the parameter name is the same.
  • Number of parameters : Whether the number of parameters is the same.
  • Translation exclusion: Whether to apply translation exclusion.
  • Number of parentheses: whether the number of parentheses is the same.
  • Metadata length: Whether the maximum number of metadata characters has been exceeded.
  • Changelogs length : Whether the maximum number of changelog characters has been exceeded.

If the parameter name or number is not the same, problems occur when compiling, and if Metadata or Changlog exceeds the maximum number of characters, store submission is not possible, so inspection is required.

Decrease Productivity

There are 1,200 phrases in the VoCat app, and if I support 72 languages, that’s 86,400 sentences. It takes too much time to directly check many of these sentences, and adding, modifying, and deleting phrases always has to be repeated 72 times, leading to a sharp drop in productivity.

Why are there so many problems? I didn't want to know either..🫠Why are there so many problems? I didn't want to know either..🫠

Finish

We have selected the languages ​​necessary for Flutter multilingual support and completed basic development preparations. In the next part2, I will introduce tools created to solve problems encountered during translation :)

✔︎ Part 1. Flutter Multilingual Support - Ready
Part 2. Flutter Multilingual Support - Tool Making