Manage localizations for internationalization
This document outlines the basic structure and workflow for the custom creation, merge and check scripts used to manage application localization (l10n).
The primary goal of these scripts is to:
- Generate necessary localization files (like Dart classes and schemas) from base configuration files.
- Merge project-specific modifications with the base localization file (
arb.json). - Check that the base ARB file stays in sync with the schema.
All file names and paths mentioned below are examples and can be modified by adjusting the script parameters accordingly.
| Requirement | Version |
|---|---|
| Dart SDK | >=3.13.2 <4.0.0 |
The generator uses modern Dart language features (const new, factory fromJson, pattern
matching) that require Dart 3.13 or newer.
All three packages in this repository share the same lint configuration, based on
coolint ^3.0.0. Run the linter with:
dart analyzeBefore running any script, the user must create the following template files. These files define the structure, languages, and specific modifications for the localization process.
| File Name | Purpose | Used as Schema for |
|---|---|---|
arb.json |
Base ARB File: Contains all localization keys and default texts. | - |
language_localizations.json |
Defines the structure of a language and its text keys. It's the primary source of truth for all required keys. | Used by the creation script to generate Dart files. |
| File Name | Purpose | Used as Schema for |
|---|---|---|
array_localizations.json |
ARB Schema: Used as the schema for arb.json to ensure all necessary language keys are present and prevent missing keys (warnings/errors in development tools). |
arb.json |
modification_localizations.json |
Merge Schema: Defines the structure for the arb_merge.json file, allowing developers to specify partial or complete changes by language. |
arb_merge.json |
Every script exposes its own usage information:
dart run generator/bin/creation_arb.dart help
dart run generator/bin/merge_arb.dart help
dart run generator/bin/checker_non_required_arb.dart help
dart run generator/bin/checker_non_used_arb.dart helpThe first step is to generate the necessary supporting files (Dart classes, schemas) used throughout the project.
Run the following command from the appropriate directory:
dart run generator/bin/creation_arb.dart -s ./example/lib/generators/language_localizations.json -n ./example/lib/gen/arb_localizations -m ./example/lib/gen/modification_schema.json| Parameter | Description |
|---|---|
-s |
Path to the source file (language_localizations.json). |
-n |
Output name/path for the generated Dart localization classes (e.g., ./example/lib/gen/arb_localizations will generate arb_localizations.dart, etc.). Missing directories are created automatically. |
-m |
Output path for the generated modification schema file (modification_schema.json). |
-c |
Optional directory where the resulting schema is copied as localization_schema.json. The directory is created if missing. |
The generated classes read the raw JSON through a Map<String, dynamic> and
expose typed getters, so there is no .g.dart boilerplate to generate and no
need to run build_runner. You can compile right after the creation script.
Releases before
0.3.4emitted@JsonSerializableclasses and requireddart run build_runner build. See Version history if you are pinned to an older tag.
Upon successful execution, the following files will be generated/modified within the ./example/lib/gen/ directory:
arb_localizations_divisions: Contains class divisions (e.g., if localization keys are grouped).arb_localizations_merge.dart: The file used for potentially modifying localization information remotely (e.g., dynamic updates).arb_localizations.dart: Contains the final Dart classes with all localization keys from the base file.modification_schema.json: A modified version oflanguage_localizations.jsonwithout required fields. This acts as the schema for merge files.- Modification to
language_localizations.json: This file is updated to include all required fields for its objects, ensuring thatarb.jsontriggers warnings if any text key is missing.
The merge script allows for modification of the base arb.json output, which is especially useful when multiple applications share the same base keys but require partial or complete changes to some values.
| File Name | Generation Method | Purpose |
|---|---|---|
arb_merge.json |
Manually Created | Uses the modification_localizations.json schema. Specifies the changes for the base ARB file, typically defined per language. |
arb_after_merge.json |
Automatically Generated | The final output file containing the merged localization data for the specific application. Do NOT create this file manually. |
β οΈ Recommendation: It is strongly recommended to ignore thearb_merge.jsonfile in Git andpubspec.yaml, and only commit the automatically generatedarb_after_merge.jsonto the repository.
After defining the necessary changes in arb_merge.json, run the script:
dart run generator/bin/merge_arb.dart -a ./example/lib/generators/arb.json -m ./example/lib/merge/arb_merge.json -o ./example/lib/merge/arb_after_merge.json --typology localization| Parameter | Description |
|---|---|
-a |
Path to the Base ARB file (arb.json). |
-m |
Path to the Modification file (arb_merge.json). |
-o |
Path to the Output file (arb_after_merge.json). |
--typology |
The type of merge being performed: localization or any (default). |
-r |
Optional list of global word replacements with the format word:replacement,other:otherReplacement. Applied to the whole output, and malformed pairs are reported and skipped. |
The execution of the merge script generates the arb_after_merge.json file. This is the final localization file that will be consumed by the specific application, typically placed in the assets/l10n directory of the consuming app.
Two additional scripts validate that the base ARB file and the code stay in sync with
language_localizations.json. Both exit with code 1 when they find problems, so they can be
wired into CI.
Reports the schema keys that are never read in the given source directory:
dart run generator/bin/checker_non_used_arb.dart -a ./example/lib/generators/language_localizations.json -o ./example/lib/checks/non_used -s ./example/lib| Parameter | Description |
|---|---|
-a |
Path to the schema (language_localizations.json). |
-o |
Output path for the report of unused keys. |
-s |
Directory that is recursively scanned looking for .<key> accesses. |
Reports the keys present in arb.json but missing from the schema:
dart run generator/bin/checker_non_required_arb.dart -a ./example/lib/generators/language_localizations.json -o ./example/lib/checks/non_required -s ./example/lib/generators/arb.json| Parameter | Description |
|---|---|
-a |
Path to the schema (language_localizations.json). |
-o |
Output path for the report of keys that are not required. |
-s |
Path to the base ARB file (arb.json). |
Both reports are written as valid, indented JSON, for example:
{
"result": [
{
"locale": "es",
"non_requires": [
"welcomeMessage"
]
}
]
}To use these scripts in your Dart or Flutter project, you must first add the necessary development dependencies to your pubspec.yaml file.
The library and the generator live in the same repository, but they are two
separate packages, so each one gets its own git entry. Note that
coollocalizations_generator needs the path: generator to point at the
sub-package.
environment:
sdk: ">=3.13.2 <4.0.0"
dependencies:
coollocalizations: # Brings you the generated classes that you will need in your Dart/Flutter project
git:
url: git@github.com:coolosos/coollocalizations.git
ref: 0.3.3 # Use a release tag, 'latest', or a specific commit/branch
dev_dependencies:
coollocalizations_generator:
git:
url: git@github.com:coolosos/coollocalizations.git
path: generator
ref: 0.3.3 # Keep this in sync with the ref aboveAfter modifying the file, run dart pub get (or flutter pub get) in your terminal.
Keep both refs on the same release. The generated code and the runtime library must agree: the generator emits classes that call the
fromJsonconstructors defined incoollocalizations. Pinning the two to different releases is the most likely cause of a compile error right after generation.
build_runnerandjson_serializableare not required for this workflow. They are only needed if you want to rebuild this repository's own library sources, which use@JsonSerializable.
Once the dependency is installed, you can execute the scripts directly using the
package name (coollocalizations_generator) followed by the specific executable
(e.g., creation_arb or merge_arb). Paths are resolved relative to your
project root, so lib/... is what you type, not
../generator/bin/creation_arb.dart.
| Script Name | Command (Simplified) |
|---|---|
| Creation | dart run coollocalizations_generator:creation_arb [options] |
| Merge | dart run coollocalizations_generator:merge_arb [options] |
| Non required check | dart run coollocalizations_generator:checker_non_required_arb [options] |
| Non used check | dart run coollocalizations_generator:checker_non_used_arb [options] |
A full generation run for a consuming project looks like this:
# 1. Generate the Dart classes and the two schemas.
dart run coollocalizations_generator:creation_arb \
-s lib/generators/language_localizations.json \
-n lib/gen/arb_localization \
-m lib/gen/modification_schema.json
# 2. Validate that the schema keys you defined are actually used in code.
dart run coollocalizations_generator:checker_non_used_arb \
-a lib/generators/language_localizations.json \
-o lib/checks/non_used \
-s lib
# 3. Apply the per-language overrides to produce the final ARB.
dart run coollocalizations_generator:merge_arb \
-a lib/generators/arb.json \
-m lib/merge/arb_merge.json \
-o lib/merge/arb_after_merge.json \
--typology localizationCommit lib/gen/ (it is generated, but the app compiles against it) and keep
lib/merge/arb_merge.json out of version control, as described in
Phase 2.
Every script also prints its own usage:
dart run coollocalizations_generator:creation_arb helpAdd the same preset used across this repository so generated code stays lint clean:
include: package:coolint/dart.yamlThe
coollocalizations_generatorpackage is a CLI, so it disablesavoid_printin its ownanalysis_options.yaml.
coollocalizations and coollocalizations_generator are released from the same
repository and are intended to be used at the same release. Pin both ref
values to the same tag.
| Release | Notes |
|---|---|
0.3.4 |
Generator emits getters over a raw Map<String, dynamic> instead of @JsonSerializable fields. build_runner is no longer needed for the generated output. Using getters keeps each generated member small, which avoids WebAssembly's per-function size limit on apps with many keys. Malformed schema properties now fail loudly instead of being dropped silently. |
0.3.1 |
First release of the schema-driven creation script. Output still required dart run build_runner build. |
Both
refvalues must match. Earlier releases are still usable together, but mixing them (for example the library at0.3.3with the generator at0.3.1) produces classes that call constructors the pinned library may not expose.