Using `language_helper` And `AI` To Localize Flutter Apps Automatically
1. Add language_helper to your project
dependencies:
language_helper: ^latest_version
dev_dependencies:
language_helper_generator: ^latest_version
2. Initialization
final languageHelper = LanguageHelper.instance;
main() async {
WidgetsFlutterBinding.ensureInitialized();
// Placeholder during development — this will be updated later.
await languageHelper.initial([]);
runApp(const App());
}
3. Wrap your app
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LanguageBuilder(
builder: (context) {
return MaterialApp(
localizationsDelegates: languageHelper.delegates,
supportedLocales: languageHelper.locales,
locale: languageHelper.locale,
home: const HomePage(),
);
}
);
}
}
4. Add .tr to your widget
// Simple translation
Text('Hello World'.tr)
// With parameters
Text('Hello @{name}'.trP({'name': 'John'}))
// With conditions
Text('You have @{count} item'.trP({'count': itemCount}))
5. Generate the data
a. Add the configurations to pubspec.yaml:
language_helper:
languages: en,vi
ignore-todo: en # Skips TODO for `en`
b. Run the generator:
dart run language_helper:generate
6. Update the initialization
- await languageHelper.initial([]);
+ await languageHelper.initial(
+ [LanguageDataProvider.lazyData(languageData)]
+ );
7. Using AI to translate
Create a new promt with the following content (at the end of the page) and execute this request
/translate-language-helper `lib/languages/data`
It’s done. The only thing left is to review the generated language data.
Read more at language_helper on pub.dev .
Prompt
You should update the prompt to ensure it matches your project and coding style.
---
name: translate-language-helper
description: translate only the *values* in a `Map<String, dynamic>` used for localization. Do **not** change keys, structure, or comments.
---
## Preflight
1. Read the entire input file to understand context before translating any entries.
2. If the target language is not English and the keys are not in English, check for an `en.dart` in the same folder and use it as a contextual reference.
## Which items to translate
3. **Translate only values that have a `TODO` comment immediately above them.** Leave all other values unchanged.
4. Preserve all comments (`//`, `///`) exactly as they are. Do not translate comments or modify their position. Do not translate nested comments.
## Keys, structure, and safety
5. Never modify keys, the map structure, or comment text/placement. Ensure indentation and syntax remain valid Dart.
6. After translating a value, remove the `TODO` note associated with that value (but keep surrounding comments intact).
## Plural handling
7. If a value represents plural text, convert it into a `LanguageConditions` object using the `param` used in the string (e.g., `count`).
8. Use this pattern for English plurals unless a language-specific rule is required:
* `0` → `no products`
* `1` → `1 product`
* `other` (fallback) → `@{count} products`
9. For languages that do not distinguish singular/plural in the same way, you **may** keep a single string value rather than `LanguageConditions`. Use `LanguageConditions` only when the target language requires multiple forms.
## Quality and style
10. Try to keep translated text length similar to the original for layout/UX consistency (preferred, not mandatory).
11. Produce natural, context-appropriate translations — prefer idiomatic phrasing over literal word-for-word translation when context suggests it.
12. Preserve the original uppercase/lowercase intent of each source string in the translated value (e.g., ALL CAPS stays ALL CAPS, Title Case stays Title Case, lowercase stays lowercase), unless the target language has a clear grammatical exception.
13. Double-check grammar, punctuation, interpolation markers (e.g., `@{count}`), escape sequences, and casing consistency so the resulting Dart file stays valid.
## Automation / workflow rules
14. Do not prompt the user for permission or confirmation; perform the translation using best effort. Do not stop prematurely — continue translating until every `TODO` value in the input file has been translated and all corresponding `TODO` markers have been removed. If you encounter transient errors or rate limits, retry and resume work until the translation pass is fully complete.
15. After finishing the translation pass, include a short summary note that describes:
* Any ambiguous entries and the choices you made.
* Where plural handling was applied and why.
* Any entries left unchanged (and the reason).
16. Run a final syntactic check to ensure the map remains valid Dart and that all TODO markers for translated values were removed.
---
## Plural example
**Input**
```dart
// TODO
'@{count} sản phẩm': '@{count} sản phẩm'
Output (English)
'@{count} sản phẩm': LanguageConditions(
param: 'count',
conditions: {
'0': 'no products',
'1': '1 product',
'_': '@{count} products',
},
)
(If the target language does not require distinct plural forms, replace the value with a single translated string instead of LanguageConditions.)
Quick checklist (use at the end of each file)
- Only values with
TODOwere translated. - Keys, structure, and comments unchanged.
- All
TODOmarkers removed for translated entries. - Plural forms converted to
LanguageConditionswhen needed. - Interpolations (e.g.,
@{count}) preserved correctly. - Uppercase/lowercase intent of original strings preserved in translated values.
- Short summary note added describing ambiguous choices and plural handling.
- File compiles / is syntactically valid Dart (basic check).

