l10n_flow 0.1.0
l10n_flow: ^0.1.0 copied to clipboard
Sync translations from collaborative spreadsheets and manage JSON localization at runtime in Flutter.
l10n_flow #
English | 中文文档
Collaborative localization for Flutter. Sync a published Google Sheet to JSON, validate translation quality, and consume the resources through a lightweight runtime manager.
Features #
- Public Google Sheets TSV source; no service account required
sync,validate, andwatchCLI commands- JSON output with safe stale-file cleanup
- Duplicate-key, empty-value, and placeholder validation
- Runtime locale switching and locale resolution
- Named and ordered interpolation
- Remote translation patches and global placeholders
- Missing-key stream,
.trextensions,L10nBuilder, andTextTr
Install #
dependencies:
flutter_localizations:
sdk: flutter
l10n_flow: ^0.1.0
Configure #
Publish a Google Sheet as TSV. A typical sheet looks like:
| Key | English | Simplified Chinese | Notes |
|---|---|---|---|
| app.title | My app | 我的应用 | App title |
| welcome | Hello {name} | 你好,{name} | Greeting |
The published URL must use output=tsv. CSV URLs such as output=csv are
not supported by the current Google Sheets source.
Add a root-level section to your app's pubspec.yaml:
l10n_flow:
source:
type: google_sheets_tsv
url: https://docs.google.com/spreadsheets/d/e/YOUR_ID/pub?output=tsv
# Generated JSON directory, relative to the directory where the command runs.
output: assets/l10n
# 1-based row containing Key and language column headers.
# Use 2 when row 1 is a document title and row 2 contains the headers.
header_row: 1
# Exact column header containing translation keys.
key_header: Key
# Non-language columns that should not generate locale files.
exclude_columns:
- Notes
# Sheet column header -> generated JSON filename (without .json).
languages:
English: en
Simplified Chinese: zh_cn
Vietnamese: vi
The keys under languages must exactly match the language column headers in
the sheet. English header names are recommended for shared demo projects.
Register the generated directory as a Flutter asset:
flutter:
assets:
- assets/l10n/
CLI #
dart run l10n_flow sync
dart run l10n_flow validate
dart run l10n_flow watch
Use another project configuration file when needed:
dart run l10n_flow sync --config path/to/pubspec.yaml
sync returns exit code 2 when quality warnings are found, making it suitable for CI checks.
Flutter runtime #
const english = AppLocale(
value: Locale('en'),
assetPath: 'assets/l10n/en.json',
);
const chinese = AppLocale(
value: Locale('zh', 'CN'),
assetPath: 'assets/l10n/zh_cn.json',
);
await L10nManager().init(
defaultLocale: english,
locales: const [english, chinese],
placeholders: const {'{brand}': 'Acme'},
);
Read translations:
Text('app.title'.tr);
Text('welcome'.trMap({'name': 'Aiwen'}));
Text('score'.trValues([2, 1]));
Rebuild automatically after a locale change:
L10nBuilder(
builder: (context, l10n) => MaterialApp(
locale: l10n.locale.value,
supportedLocales: L10nManager().supportedLocales,
localizationsDelegates: GlobalMaterialLocalizations.delegates,
home: const HomePage(),
),
);
Import GlobalMaterialLocalizations from
package:flutter_localizations/flutter_localizations.dart. Wrapping the root
MaterialApp lets both application translations and Flutter's Material and
Cupertino widgets react to locale changes.
Convenience widgets and rich text:
TextTr('welcome', named: {'name': 'Aiwen'});
'demo.rich_message'.rich(
defaultStyle: const TextStyle(color: Colors.black),
named: {
'terms': 'Terms of Service',
'privacy': 'Privacy Policy',
},
styleMap: {
'terms': const TextStyle(color: Colors.blue),
'privacy': const TextStyle(color: Colors.blue),
},
);
Switch locales:
await L10nManager().change(chinese);
Apply server-side patches without replacing bundled JSON:
await L10nManager().merge({
chinese: {'campaign.title': '限时活动'},
});
Listen for missing keys:
L10nManager().missingKeyStream.listen(logMissingTranslation);
Runnable example #
The example/ directory is a complete Flutter application for
Android, iOS, web, macOS, Linux, and Windows. It demonstrates English,
Simplified Chinese, and Vietnamese locale switching against a published demo
Google Sheet.
cd example
flutter pub get
dart run l10n_flow sync
flutter run
Configuration reference #
| Field | Required | Description |
|---|---|---|
source.url |
Yes | Published TSV URL |
output |
Yes | JSON output directory, resolved relative to the command's working directory |
languages |
Yes | Exact sheet language header to JSON filename mapping; values omit .json |
header_row |
No | 1-based row containing the Key and language headers, not the first translation row; defaults to 1 |
key_header |
No | Exact Key column header; auto-detects Key or ID when omitted |
exclude_columns |
No | Exact non-language column headers to ignore |
pretty_json |
No | Pretty-print JSON; defaults to true |
delete_stale_json |
No | Delete obsolete JSON locale files; defaults to true |
watch_interval_seconds |
No | Watch polling interval; defaults to 5 |
For example, given this sheet:
Row 1: L10n Flow Demo
Row 2: Key | English | Simplified Chinese | Vietnamese
Row 3: app.title | L10n Flow Demo | L10n Flow 示例 | Demo L10n Flow
set header_row: 2, because row 2 contains the column headers. Translation
data starts on the following row.