globetrotter

Generate runtime translations and type-safe bindings for a polyglot application from one set of TOML translation files.

globetrotter
$ globetrotter -c globetrotter.yaml
     
       app[rust]       wrote generated/translations.rs
       app[typescript] wrote generated/translations.ts
       app[de]         wrote generated/translations_de.json (354 B, 227 B gzipped)
       app[en]         wrote generated/translations_en.json (340 B, 206 B gzipped)
       app[fr]         wrote generated/translations_fr.json (355 B, 225 B gzipped)
                       completed in 0.00ms

build status test status crates.io docs.rs

Globetrotter keeps the two parts of internationalization separate. Translation text stays in language-specific JSON that an application can load at runtime. Translation keys and template arguments become generated source code, so compilers and editors can catch mistakes before the application starts.

One catalog

Keep every language and each template argument contract together in readable TOML files.

Runtime JSON

Generate one versioned translation file per language and deploy text independently from application code.

Typed bindings

Generate Rust and TypeScript definitions from the same keys and argument declarations.

Translation linting

Find missing text, broken templates, argument mismatches, duplicate strings, and unused keys.

A complete input#

This catalog is part of the documentation’s runnable example:

translations.toml
[account.greeting]
en = "Welcome back, {{name}}!"
de = "Willkommen zurück, {{name}}!"
fr = "Bon retour, {{name}} !"
arguments = { name = "string" }

[cart.summary]
en = "You have {{count}} items in your cart."
de = "Du hast {{count}} Artikel in deinem Warenkorb."
fr = "Vous avez {{count}} articles dans votre panier."
arguments = { count = "number" }

[navigation.sign_out]
en = "Sign out"
de = "Abmelden"
fr = "Se déconnecter"

Its config generates JSON for three languages plus Rust and TypeScript bindings:

globetrotter.yaml
version: 1
configs:
  app:
    languages: [en, de, fr]
    engine: handlebars
    strict: true
    check_templates: true
    inputs:
      - path: ./translations.toml
        prefix: app
    outputs:
      json:
        - ./generated/translations_{{language}}.json
      typescript:
        type: ./generated/translations.ts
      rust:
        - ./generated/translations.rs

The documentation build runs that exact config with the current source tree before Hugo renders the site. The quick start shows the resulting files.

Get started#

brew install --cask LuupSystems/tap/globetrotter
globetrotter

Globetrotter discovers globetrotter.yaml in the current directory. Start with Installation, then follow the Quick start.

Documentation#