Documentation section

File Format - JSON

Learn how to use Localazy CLI for app and software localization with translations in JSON files.

Localazy doesn’t come with small parsers for each of the different flavors of JSON files used for app and software localization. Instead, it comes with flexible and configurable solution and you can fine-tune it for your specific needs.

Plain JSONs 🔗

The most common JSON format for apps and sofware localization is simple plain JSON as shown below. It’s supported out-of-the-box and no extra configuration is necessary.

{
  "key1": "Text 1",
  "key2": "Text 2"
}

Structured JSONs 🔗

Structured JSONs are supported by default and no configuration is necessary.

{
  "parent": {
    "child": {
      "another_nested_level": "All is supported."
    }
  }
}

Multilingual JSONs 🔗

Multilingual JSONs allow defining more languages inside a single file. Localazy supports multilingual JSONs with all the features describe in this document.

The top-level elements must be locale codes, and the corresponding source language as set in the project must be included.

The multilingual support must be enabled by adding multilingual to features in the upload section.

{

  "en": {
    "key": "in English"
  },

  "cs": {
    "key": "in Czech"
  }

}

Locale codes can be defined using one of the supported methods:

  • LL_RR_Scrp
  • LL_Scrp_RR
  • LL_RR#Scrp
  • LL-RR-Scrp
  • LL-Scrp-RR
  • LL-RR#Scrp
  • LL+RR+Scrp
  • LL+Scrp+RR

Where LL is the language code (ISO 639-1), RR is the region code (ISO 3166-2), Scrp is the script code (ISO 15924). Parameters RR and Scrp can be omitted.

If the locale is not known to Localazy, it’s skipped during the processing of uploaded files.

Mozilla/Chrome i18n 🔗

By including content_as_object in features in the upload section, you can enable parsing of more complex JSON files often referred as Mozilla i18n or Chrome i18n.

{
  "key": {
    "message": "String content",
    "description": "Optional additional comment for translators."
  }
}

Instead of message, you can use string, value, text, content or translation. Localazy remembers the field name and generates exactly the same document - just translated - for each of languages.

For the context information, instead of description, any of context, comment and developer_comment can be used.

All other features describe in this document are still available including structured JSONs, arrays and plurals parsing, etc.

Array notation (i18next) 🔗

Another commonly used JSON format is an array of objects. Enable it by listing content_as_array in features in the upload section.

[
  {
    "id": "string1",
    "content": "String 1",
    "description": "Information for the translator."
  },
  {
    "id": "string2",
    "content": "String 2",
    "description": "Information for the translator."
  }
]

As with the Mozilla/Chrome i18n, you can use different names for fields. See the table below.

Type Variants
String Id / key id, key, name
Text content message, string, text, value, content, translation
Comment description, context, comment, developer_comment

All other features describe in this document are still available including structured JSONs, arrays and plurals parsing, etc.

RequireJS 🔗

For RequireJS files with the format shown below, you can use our JSON parser. Just add requirejs to features in the upload section and it will correctly remove define(...); wrapping before parsing and add it back when generating output files.

define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    }
});

All other features describe in this document are still available including structured JSONs, arrays and plurals parsing, etc.

ARB-style metadata 🔗

Allows defining additional metadata for the string using @key notation.

With arb_metadata in features in the upload section, you can enable ARB-style metadata. With the feature enabled, Localazy extracts content from description, context and placeholders and presents it to the translators to provide better context and improve translation quality.

For plurals and arrays, metadata can be defined using the base form without the suffix.

{

  "singleString": "This is just a normal string.",
  "@singleString": {
    "context": "views:Home page",
    "description": "Comment for the single string."
  },

  "datePickerMinuteOne": "1 minute",
  "datePickerMinuteOther": "$minute minutes",
  "@datePickerMinute": {    
    "description": "Accessibility announcement for the selected minute on a time picker such as '15 minutes' or '15分'",
    "plural": "minute",
    "placeholders": {
      "minute": {
        "description": "the number of minutes",
        "example": "15"
      }
    }
  }

}

Arrays 🔗

Arrays are good but beware changing number of items to prevent mismatching translations. If your files contain incomplete arrays, don’t use array features at all.

There are two ways how to define arrays.

JSON Arrays 🔗

Standard JSON arrays are recognized as arrays and stored with Localazy in corresponding way.

This feature can be enabled by adding array to features in the upload section.

{
  "game.difficulty": [
    "easy",
    "medium",
    "hard"
  ]
}

Arrays defined by suffix 🔗

Localazy parses automatically also the suffixed variant shown below and present it to translators in a way that keeps items together and thus improves context and translation quality.

This feature can be enabled by adding array_br to features in the upload section.

{
  "difficulty[0]": "easy",
  "difficulty[4]": "normal",
  "difficulty[7]": "hard",
  "difficulty[9]": "extreme"
}

The code above will be processed as an array and additional metadata will be stored, so Localazy can restore the indexes correctly.

All valid indexes are processed where valid index is non-negative integer value.

Plurals 🔗

Beware that plurals may lead to different output for translated files due to how plurals are handled in different languages.

// English has only two plural forms:
{
  "pluralOne": "You have 1 item.",
  "pluralOther": "You have %d items."
}

// Czech has three plural forms:
{
  "pluralOne": "Máte 1 položku.",
  "pluralFew": "Máte %d položky.",
  "pluralOther": "Máte %d položek."
}

Localazy knows the rules for different languages and adapt its interface to assist translators to correctly translate all mandatory forms.

Your app should be able to handle this. We are also working on SDK to help you with this task.

Allowed plurals types are: zero, one, two, few, many, other.

Defined as array 🔗

Enabled by plural_array in features in the upload section.

{
  "users": [
    {
      "quantity": "zero",
      "content": "There are no users."
    },
    {
      "quantity": "one",
      "content": "There is one user."
    },
    {
      "quantity": "other",
      "content": "There are %d users."
    }
  ]
}

It’s also possible to use type, t or q instead of quantity and value, v or c instead of content for shorter form.

If the exact structure is not met, the array is not considered plural and is read as structured JSON instead.

Defined by suffix 🔗

Several variants are available, and you can enable any of them and even combine them together. Localazy remembers how the plurals are formatted in the input file and keeps the same format for the translated files.

Add desired variants below to features in the upload section:

  • plural_postfix_sd for single dot variant.
  • plural_postfix_dd for colon variant.
  • plural_postfix_us for underscore variant.
  • plural_postfix_cc for camelCase variant.
  • plural_postfix_br for [brackets] variant.

Examples:

{

  "single_dot": {
    "users.zero": "There are no users.",
    "users.one": "There is one user.",
    "users.other": "There are $number users."
  },

  "colon": {
    "users:zero": "There are no users.",
    "users:one": "There is one user.",
    "users:other": "There are $number users."
  },

  "underscore": {
    "users_zero": "There are no users.",
    "users_one": "There is one user.",
    "users_other": "There are $number users."
  },

  "camelCase": {
    "usersZero": "There are no users.",
    "usersOne": "There is one user.",
    "usersOther": "There are $number users."  
  },

  "brackets": {
    "users[zero]": "There are no users.",
    "users[one]": "There is one user.",
    "users[other]": "There are $number users."  
  }

}

Defined as object 🔗

Enabled by plural_object in features in the upload section.

{

  "users": {
    "zero": "There are no users.",
    "one": "There is one user.",
    "other": "There are $number users."
  }

}

The object is considered plural if and only if all items are key-value strings with keys being valid plural types (zero, one, two, few, many, other).

If the condition above is not met, the object is not considered plural and is parsed as a structured JSON.

Defined using i18Next plural 🔗

Enabled by plural_i18next in features in the upload section.

Singular/plural variant:

{
  "key": "item",
  "key_plural": "items"
}

All plural forms:

{
  "key_0": "zero",
  "key_1": "singular",
  "key_2": "two",
  "key_3": "few",
  "key_4": "many",
  "key_5": "other"
}

Defined using ICU 🔗

Enabled by plural_icu in features in the upload section.

{
  "users": "There are {COUNT, plural, one {one user} other {# users}}."
}

Only one ICU plural can be used in the string as otherwise, it wouldn’t be possible to convert it to a specific Localazy plural structure. If more than two ICU plurals are contained, the string is kept in the original form.

Allowed plurals types are: zero (=0), one (=1), two (=2), few, many, other.

Other ICU types like gender, number, etc. can be used but will not be converted and will be kept in string in the original form.

Filtering untranslated strings 🔗

By default, when the output file is generated, Localazy uses texts from the source languages when the translation in the exported language is missing.

This approach is safeguarding you from missing keys that can lead to crashes in some solutions/frameworks.

This feature can be disable by adding filter_untranslated to features in the upload section and reuploading your source language file.

Using key as the source translation 🔗

There is a special format where the key is also the source language translation. It’s possible to enable the support for this format by adding source_is_key in features in the upload section.

{
  "Text in the source language": "Translation in the defined language"
}

Features overview 🔗

The table below is a summary of all available features for JSON parser.

Feature Description
content_as_object Enable content as a JSON object; also known as Mozilla/Chrome i18n.
content_as_array Enable content as objects in an array; older format of i18next.
requirejs Enable support of RequireJS format.
multilingual Enable support of multilingual JSON files.
array Parse JSON arrays as arrays and not as list of single strings.
array_br Parse strings with keys suffixed by [x] as arrays.
plural_array Enable plurals defined as arrays.
plural_postfix_dd Parse strings with keys suffixed by :type as plural.
plural_postfix_us Parse strings with keys suffixed by _type as plural.
plural_postfix_cc Parse strings with keys suffixed by Type as plural.
plural_postfix_br Parse strings with keys suffixed by [type] as plural.
plural_postfix_sd Parse strings with keys suffixed by .type as plural.
plural_object Enable plurals defined as objects.
plural_i18next Enable i18Next plurals.
plural_icu Enable support for ICU plurals.
arb_metadata Enable support for ARB-style metadata.
filter_untranslated Don’t use the source language texts for missing translations.
source_is_key Use the key as the source translation.