# FormatJS

> Localize FormatJS & react-intl messages — no custom formatter required.

URL: https://store.crowdin.com/formatjs
Identifier: formatjs
Category: File Formats
Type: App
Author: Awesome Crowdin

FormatJS's `formatjs extract` command outputs messages in a standard JSON shape (`{ "id": { "defaultMessage", "description" } }`) that Crowdin doesn't handle natively — so today you have to run `formatjs extract --format crowdin` to convert it first. This app reads the standard output directly, removing that extra step.



## How It Works



### Step 1: Upload extracted messages



Upload the JSON produced by `formatjs extract`. The app detects FormatJS-shaped catalogs (any `.json` containing `defaultMessage`) and leaves other JSON to Crowdin's native parser.



### Step 2: Extract translatable content



Each message becomes a Crowdin string: `defaultMessage` is the source text and `description` is the translator context. ICU placeholders, plurals, and react-intl rich-text tags are kept verbatim.



### Step 3: Translate in Crowdin



Translators work with the extracted strings, with the message id and description for context.



### Step 4: Export translated files



Exports mirror the original structure, replacing only each `defaultMessage` with the translation while preserving `description`, key order, and any other fields — so the file is ready for `formatjs compile`.

Untranslated messages keep their source text.



The app also supports Crowdin bundles, generating a translated catalog for any target language.

## File Format Details

| Attribute | Value |
| --------- | ----- |
| File Extension | .json |
| [API Type](https://developer.crowdin.com/api/v2/#operation/api.projects.files.post) | formatjs-messages |
| Source can be edited in Crowdin | No |
| Generating translated files via [Bundles](https://support.crowdin.com/bundles/) | [Search Crowdin Store](https://store.crowdin.com/tags/string-exporter) |
| Supports pluralization | Yes |
| WYSIWYG Preview in the editor | No |
| Supported types of contextual information | Text comments, Screenshots |
| Custom attributes | Yes |
| Existing translations import possibility | Key-value mapping |

## Sample File

```json
{
  "with.description": {
    "defaultMessage": "Save changes",
    "description": "primary action button"
  },
  "no.description": {
    "defaultMessage": "Cancel"
  },
  "empty.message": {
    "defaultMessage": "",
    "description": "intentionally empty, should be skipped"
  },
  "bare.string": "Logged compiled value still translatable",
  "object.description": {
    "defaultMessage": "Notifications",
    "description": { "context": "nav label", "component": "Sidebar" }
  }
}

```
