Fig 9.0 · 7 min
Localising a Flutter app into Hindi without letting the two languages drift
How we generated every string of a bilingual app from one source, what Hindi did to our layouts, and why the review sheet mattered more than the translation.
- Flutter
- Localisation
- Hindi
Most localisation projects fail quietly. The translation is done, the app ships, and six months later the Hindi screens say something slightly different from the English ones because someone fixed a string in one place and not the other. We set out to make that drift impossible.
One source, four outputs
Every word the app and the server say to a user lives in one list. From that list a build script generates four files: a CSV for people and diffs, a JSON file the Flutter bundle and the PHP message store are generated from, and two review sheets (HTML and Word) for the product owner and the client.
Nobody edits the generated files by hand. A hand edit is lost on the next build, and worse, it silently splits the sheet humans read from the JSON the code reads. Corrections go back into the source and the build is re-run.
The build refuses to finish if:
- a key has no Hindi,
- a
${…}placeholder is added, dropped or altered between languages, - two strings that must share wording stop matching, or
- a rich-text sentence no longer reassembles from its pieces.
That last one matters more than it sounds. Sentences with bold or linked fragments are stored as pieces, and Hindi word order is not English word order. The build checks that the pieces still make the sentence.
What Hindi did to the layout
The folk wisdom is that translations grow by thirty per cent. For Hindi, against our English, the median string was narrower: about 0.83 times the width, with only around a fifth of strings growing. What grew was predictable: short English labels where the Hindi needed a full phrase. We found those by rendering every screen in both languages on an emulator and reading the overflow warnings, not by guessing.
Hindi also inflects where English does not. "Item" versus "items" is one branch in English and a different branch in Hindi, with the noun changing form. We added a plural branch per language instead of forcing one template on both.
Deliberately untranslated
Some strings stay in English on purpose: brand names, blood groups, the exact SMS body registered with the telecom regulator, and a few strings that turned out not to be user-visible at all. Each one carries a note saying why, so the next person does not "fix" it.
The review sheet was the product
The translation itself was the smaller job. The thing that made the owner comfortable shipping was a review sheet that showed, for every string, the English, the Hindi, where it is said in the app and both earlier glossaries. Reviewers corrected wording in the sheet; we fed corrections back into the source; the build regenerated everything.
Data that users type in, such as doctor specialities and product names, remained in English. A Hindi-only user still sees some English in search results. That is the honest state of the work, and we tell clients so.
If you are about to do this
- Put every user-facing string in one source, including server messages.
- Generate the code's bundles from it. Never copy by hand.
- Make the build fail on missing translations and placeholder mismatches.
- Render every screen in both languages and look at it.
- Give the owner a sheet they can correct, and close the loop.
Written by the engineers at Software Muskets. Questions or corrections: contact@softwaremuskets.com.