Skip to content

Translation Files ​

TypeGlot uses JSON files to store translations. This guide covers the file format and supported features.

File Structure ​

Translation files are stored in the localesDir (default: ./locales):

locales/
├── en.json    # Source locale (required)
├── es.json    # Spanish
├── fr.json    # French
├── de.json    # German
└── ja.json    # Japanese

The filename (without .json) is used as the locale code.

Basic Format ​

Translation files are simple JSON objects mapping keys to values:

json
{
  "hello": "Hello",
  "goodbye": "Goodbye",
  "thank_you": "Thank you"
}

Nested Keys ​

You can organize translations with nested objects:

json
{
  "common": {
    "save": "Save",
    "cancel": "Cancel",
    "delete": "Delete"
  },
  "auth": {
    "login": "Log in",
    "logout": "Log out",
    "signup": "Sign up"
  }
}

These are flattened to dot-notation in the generated code:

typescript
m.common_save();
m.common_cancel();
m.auth_login();

Parameters (Interpolation) ​

Use {paramName} syntax for dynamic values:

json
{
  "welcome": "Welcome, {name}!",
  "items_in_cart": "You have {count} items in your cart",
  "greeting": "Hello {firstName} {lastName}"
}

Generated TypeScript:

typescript
export function welcome(params: { name: string }): string;
export function items_in_cart(params: { count: string }): string;
export function greeting(params: { firstName: string; lastName: string }): string;

Pluralization ​

Use ICU MessageFormat syntax for pluralization:

json
{
  "items_count": "{count, plural, one {# item} other {# items}}",
  "messages": "{count, plural, =0 {No messages} one {# message} other {# messages}}"
}

The # symbol is replaced with the count value.

Plural Categories ​

CategoryDescriptionExample Languages
zeroZero itemsArabic
oneSingularEnglish, Spanish
twoDualArabic, Hebrew
fewFew itemsRussian, Polish
manyMany itemsRussian, Polish
otherDefault (required)All

Example with multiple categories:

json
{
  "apples": "{count, plural, =0 {No apples} one {One apple} few {{count} apples} many {{count} apples} other {{count} apples}}"
}

Number and Date Formatting ​

Use ICU format for numbers and dates:

json
{
  "price": "Price: {amount, number, currency}",
  "date": "Created on {date, date, medium}",
  "percent": "{value, number, percent}"
}

Select (Gender/Variants) ​

Use select for gender or variant-based text:

json
{
  "notification": "{gender, select, male {He commented} female {She commented} other {They commented}} on your post"
}

Best Practices ​

Use Descriptive Keys ​

json
// ❌ Bad
{
  "msg1": "Welcome",
  "btn": "Submit"
}

// ✅ Good
{
  "homepage_welcome_message": "Welcome",
  "contact_form_submit_button": "Submit"
}

Keep Keys Flat When Possible ​

Deep nesting can make keys unwieldy:

json
// ❌ Too nested
{
  "pages": {
    "settings": {
      "account": {
        "profile": {
          "name_label": "Name"
        }
      }
    }
  }
}

// ✅ Better
{
  "settings_profile_name_label": "Name"
}

Include Context in Keys ​

json
{
  "save_button": "Save", // Generic save
  "save_draft_button": "Save Draft", // Specific context
  "save_settings_button": "Save Settings"
}

File Encoding ​

Always use UTF-8 encoding for translation files to properly support all languages and special characters.

Released under the MIT License.