GlobalLingo needs no configuration. When the checked folder has a .globallingo.json, it reads
it; --config <file> names another file. Every field is optional. An unknown field, an unknown
rule or a wrong type stops the run with exit code 2, so a typo cannot quietly turn a check off.
{
"$schema": "./node_modules/@mcamdali/globallingo/schema/config.schema.json",
"sourceLanguage": "en",
"locales": ["de", "fr", "tr", "pl"],
"ignore": {
"paths": ["**/Tests/**", "ios/Pods/**", "lib/generated/**"],
"keys": ["debug.*", "app_name"]
},
"rules": {
"MIS004": "off",
"HCS001": "error",
"PLU001": "info"
},
"jsonSyntax": "i18next",
"catalogDirs": ["app/i18n/strings"]
}
| Field | What it does |
|---|---|
sourceLanguage |
The language the others are translated from, for files that do not say it (.strings tables without an Xcode project, JSON folders without en). String Catalogs use their own sourceLanguage, ARB folders their template file. --source overrides it. |
locales |
Check only these locales, and report each one a catalog has no file for. --locales de,fr overrides it. |
ignore.paths |
Globs matched against paths from the checked folder. * stays within a folder, ** crosses folders, and a folder pattern covers everything below it. At most 256 characters per glob and 4,096 for the list. |
ignore.keys |
Globs matched against keys, in every catalog and in code. The same limits as ignore.paths. |
rules |
error, warning, info or off per rule ID. See rules. |
jsonSyntax |
i18next, icu or i18n-js: the placeholder syntax of JSON translation files, when package.json does not show which library the app uses. |
catalogDirs |
Folders with JSON translation files that GlobalLingo does not find on its own (see below). They must be inside the checked folder. |
The $schema line lets editors complete and check the file once the package is installed in the
project; schema/config.schema.json is the same schema.
| Files | Read as |
|---|---|
*.xcstrings |
One String Catalog per file |
<folder>/<locale>.lproj/<Table>.strings and .stringsdict |
One table per folder and table name; the source language is the Xcode project's developmentRegion, else en, else Base |
*.arb, with l10n.yaml |
One catalog per folder; arb-dir, template-arb-file, output-class and use-escaping from l10n.yaml |
<folder>/<locale>.json, <folder>/<locale>/<namespace>.json |
One catalog per folder (or per namespace), when the folder is called locales, locale, i18n, l10n, lang, langs, languages, translations or messages, or holds at least two locales |
*.swift, *.m, *.mm, *.dart, *.js, *.jsx, *.ts, *.tsx |
Source code for the KEY, HCS and TRI rules (--no-code skips it) |
The placeholder syntax of JSON files comes from the nearest package.json: react-intl, FormatJS, next-intl, use-intl, Lingui or i18next-icu mean ICU; i18next, react-i18next or next-i18next mean i18next; i18n-js means i18n-js. Without a package.json it comes from the files themselves.
Skipped: node_modules, Pods, Carthage, build, .build, DerivedData, .dart_tool,
dist, vendor, version control and editor folders, and symbolic links. Tests, stories and
generated localization code are not checked for hard-coded text.
GlobalLingo reads at most 200,000 files and folders, 24 folder levels, catalogs up to 16 MB, source files up to 2 MB and 20,000 source files, and stops at 100,000 findings. Each limit adds a note to the report; point GlobalLingo at the app's folder in a monorepo.
A line that ends with a globallingo-ignore comment is not reported by the code rules, and
neither is the line after a globallingo-ignore-next-line comment:
// globallingo-ignore-next-line
const Text('GlobalLingo'), // brand name, the same in every language
A baseline file accepts the findings a project has today, so CI fails only on new ones:
npx @mcamdali/globallingo --write-baseline .globallingo-baseline.json
npx @mcamdali/globallingo --baseline .globallingo-baseline.json
The run that writes the file exits 0, since it accepts what it finds. The file stores a fingerprint
per finding (rule, file, key, locale and what the finding is about, hashed), not line numbers, so
findings keep matching when lines move. Fixed findings drop out of the count; write the file again
to shrink it. Baseline findings are still reported, marked BASELINE in the terminal and as
suppressed results in SARIF.