Guides

Work with translators

Your catalogs are plain flat JSON, with nothing proprietary to convert. That gives you three ways to get translations done: hand the files to a TMS, round-trip translator files with export/import, or machine-translate with translate.

Plain JSON, no lock-in

Most TMS platforms (Crowdin, Lokalise, Phrase and friends) ingest flat JSON natively. Point the platform at locales/ and you're done: no export step, no custom format. Translations come back as the same files, and every change reviews like a normal diff.

Export for humans

When there's no TMS (a freelance translator, an agency, a coworker with a spreadsheet), verbaly export writes one translator-ready file per locale, with the source text next to each translation.

npx verbaly export                   # verbaly-export/es.xlf, pt.xlf (XLIFF 2.0)
npx verbaly export --format csv      # key,source,target (opens in any spreadsheet)
npx verbaly export --missing         # only what's untranslated

XLIFF 2.0 is the industry interchange format, so TMS and CAT tools open it directly. CSV is for everyone else: three columns, editable anywhere.

Before exporting, verbaly status (0.23.0) shows how much is left per language: es: 45/48 translated (94%).

Import back, validated

verbaly import reads the translated files (XLIFF 2.0 or 1.2, or CSV) and fills your catalogs. Every entry passes the same structural validation as machine translation: placeholders, plural variants and tags must survive verbatim. Anything else is rejected and reported, never written.

npx verbaly import verbaly-export/es.xlf
#   es: +42 imported
#   es: 1 rejected (params/tags not preserved): home.greeting
npx verbaly import es.csv --dry-run    # preview without writing
npx verbaly import es.xlf --overwrite  # replace existing translations

Existing translations are kept unless you pass --overwrite; unknown keys are ignored and reported. The target locale comes from the file itself (or the filename for CSV), and --locale overrides both.

Export for mobile apps

The same catalogs can ship to a companion mobile app as native resources: android-xml writes strings.xml folders you can drop into res/, and ios-strings writes .lproj folders for Xcode.

npx verbaly export --format android-xml   # verbaly-export/values-es/strings.xml, values-pt-rBR/…
npx verbaly export --format ios-strings   # verbaly-export/es.lproj/Localizable.strings, …

Your source language becomes the platform default (values/strings.xml, en.lproj), and untranslated keys are left out so the app falls back to it instead of showing empty text. Keys are adapted to valid Android resource names, values keep their parameter syntax untouched, and the flow is one-way: translations go from your catalogs to the app.

No humans available yet?

Machine translation fills the gaps with the same structural guarantees, and everything a provider or a person gets wrong is caught by verbaly check in CI.

Copied to clipboard