Project JSON carries everything about a translation key in one place: the key itself, its translations in all languages, and its metadata (description, tags, character limit, lock state, attributes).
It combines what multi-language-json and simplelocalize-json do separately:
| Multi-Language JSON | SimpleLocalize JSON | Project JSON | |
|---|---|---|---|
| Many languages in one file | yes | no | yes |
| Metadata | no | yes | yes |
| Namespaces | not supported | namespace:key prefix | namespace field |
| Versioned format | no | no | yes |
Project JSON is the best choice for backups, migrations between projects, and for uploading translations together with the context translators need.
File format example
The smallest file you can write by hand:
{
"version": 1,
"keys": [
{
"key": "signup.button",
"translations": {
"en": {
"text": "Sign up",
"reviewStatus": "REVIEWED"
},
"pl": "Zarejestruj się"
}
},
{
"key": "signup.email",
"namespace": "common",
"translations": {
"en": "Email",
"pl": "Adres e-mail"
}
}
]
}
The same file with everything SimpleLocalize can export:
{
"version": 1,
"keys": [
{
"key": "signup.button",
"namespace": "web",
"description": "CTA on the signup page",
"tags": ["onboarding", "cta"],
"charactersLimit": 20,
"locked": false,
"attributes": { "path": "src/pages/signup.tsx" },
"translations": {
"en": { "text": "Sign up", "reviewStatus": "REVIEWED" },
"pl": "Zarejestruj się",
"de": ""
}
},
{
"key": "signup.title",
"namespace": "mobile",
"translations": {
"en": "Create your account",
"pl": "Załóż konto"
}
}
]
}
File structure
Header
| Field | Description |
|---|---|
version | Format version. Required, and it must be 1 |
keys | The translation keys. Required. |
Translation key entry
| Field | Description |
|---|---|
key | Translation key. Required. |
namespace | Namespace of the key. When absent, the key has no namespace. |
description | Description for translators. "" or null removes it. |
tags | Tags of the translation key. [] or null removes all of them. |
charactersLimit | Character limit for translations, use -1 or null to remove the limit. |
locked | Locks translations of this key against modification. |
autoTranslation | Set to false to disable auto-translation for this key. |
deprecated | Exported for deprecated keys. Ignored on import. |
attributes | Your own data attached to the key. Merged on import, never removed. |
translations | Translations of the key, by language key. |
description always updates the translator description,
also when uploading with the CLI. Other formats uploaded with the CLI write code descriptions by default and need
--uploadOptions UPDATE_DESCRIPTIONS to overwrite translator descriptions — Project JSON does not, because a file
you exported and upload back must land in the same field.
Translations
A translation is either a plain string or an object when it carries more than the text:
"translations": {
"en": "Sign up",
"pl": { "text": "Zarejestruj się", "reviewStatus": "REVIEWED" }
}
| Field | Description |
|---|---|
text | The translated message. |
reviewStatus | REVIEWED or NOT_REVIEWED. |
Missing and empty values
A field that is not present in the file is never touched by the import, so a file with a handful of keys is a safe partial upload, it will not wipe the metadata of the keys it does not mention.
A field that is present is taken literally, including an empty value, so every metadata field can be cleared by an import:
| Field | Removes the value in SimpleLocalize |
|---|---|
description | "" or null |
tags | [] or null |
charactersLimit | null or -1 |
locked | false |
autoTranslation | true (re-enables auto-translation) |
Message interpolation
Pluralization and variable formatting is done by your translation library (e.g. FormatJS), exactly like in the other JSON formats.
{
"version": 1,
"keys": [
{
"key": "home.welcome",
"translations": { "en": "Hello, {name}!" }
},
{
"key": "home.notifications",
"translations": { "en": "You have {itemCount, plural, =0 {no items} one {1 item} other {{itemCount} items}}." }
}
]
}
Learn more about ICU message syntax or use our ICU syntax playground to test your messages.
Upload translation files
Project JSON is a multi-language format, so you do not pass a language key.
Upload with the command-line tool
simplelocalize upload --apiKey <PROJECT_API_KEY> \
--uploadFormat project-json \
--uploadPath ./translations.json
Add the
--updateargument to update existing translations; otherwise, only new, missing translations will be added
Learn more about uploading translations with CLI.
Import with REST API
curl
--request POST \
--url 'https://api.simplelocalize.io/api/v2/import?uploadFormat=project-json' \
--header 'x-simplelocalize-token: <API_KEY>' \
--form file=@/path/to/your/file.json
Learn more about importing translations with API.
Download translation files
Metadata is always included in the exported file, so no INCLUDE_* export option is needed.
Download with command-line tool
simplelocalize download --apiKey <PROJECT_API_KEY> \
--downloadFormat project-json \
--downloadPath ./translations.json
Learn more about downloading translations with CLI.
Export with REST API
curl
--request GET \
--url https://api.simplelocalize.io/api/v4/export?downloadFormat=project-json \
--header 'x-simplelocalize-token: <API_KEY>'
Learn more about exporting translations with API.