Repository: WeblateOrg/weblate

Issue:
Support FormatJS (aka React-Intl) with descriptions
### Describe the problem

I initially thought that Weblate supported FormatJS, aka React-Intl, based on issue #3286 and based on the documentation [saying that](https://docs.weblate.org/en/latest/formats.html#formats) Weblate supports "Simple key / value files, used for example by vue-i18n or react-intl."

After much confusion, I've realized that Weblate only supports FormatJS if I throw away all the string descriptions and provide strings with no context, and doesn't support FormatJS's [default format](https://formatjs.io/docs/getting-started/message-extraction), which looks like this:

```.json
{
  "some-message-id": {
    "defaultMessage": "Control Panel",
    "description": "title of control panel section"
  }
}
```

### Describe the solution you'd like

Ideally, Weblate would support the format I gave an example of above, where there is a JSON dictionary that maps each message ID to a hash of `defaultMessage` and possibly `description` strings.

### Describe alternatives you've considered

I have worked around this by writing a custom formatter on the FormatJS side for the WebExtension JSON format, and this appears to work OK so far.

However, that's not one of the [builtin formatters in FormatJS](https://formatjs.io/docs/getting-started/message-extraction), none of which Weblate appears to support.

### Screenshots

_No response_

### Additional context

I submitted a Hosted Weblate support request a week ago about this, and haven't heard back. At that time, I didn't realize the feature was unsupported, and thought it was just a configuration problem. I'm trying to translate my project [BikeHopper](https://github.com/bikehopper/bikehopper-ui).


Discussion:
The issue you've reported needs to be addressed in the [translate-toolkit](https://github.com/translate/translate/). Please file the issue there, and include links to any relevant specifications about the formats (if applicable).
Using “Crowdin Chrome JSON” formatter should work fine with Weblate https://docs.weblate.org/en/latest/formats.html#webextension-json. 

Adding native support for FormatJS should not be hard, it looks quite similar to other JSON formats. We recently got https://github.com/translate/translate/pull/4798 to add one of these.


Thanks! Well spotted that the "Crowdin" and "WebExtension" formats are mutually compatible, despite different names.

I've filed an issue on the translate toolkit here: https://github.com/translate/translate/issues/4838

Do you want to keep this issue open as well to track? If not, feel free to close this.
Please keep this open, once the format is added in translate-toolkit, integration needs to be done in Weblate as well.
Would very much appreciate that 👍

Resolving patch:
diff --git a/weblate/formats/models.py b/weblate/formats/models.py
--- a/weblate/formats/models.py
+++ b/weblate/formats/models.py
@@ -99,6 +99,7 @@ class FormatsConf(AppConf):
         "weblate.formats.ttkit.GoI18V2JSONFormat",
         "weblate.formats.ttkit.GoTextFormat",
         "weblate.formats.ttkit.ARBFormat",
+        "weblate.formats.ttkit.FormatJSFormat",
         "weblate.formats.ttkit.CSVFormat",
         "weblate.formats.ttkit.CSVUtf8Format",
         "weblate.formats.ttkit.CSVSimpleFormat",
diff --git a/weblate/formats/ttkit.py b/weblate/formats/ttkit.py
--- a/weblate/formats/ttkit.py
+++ b/weblate/formats/ttkit.py
@@ -1515,6 +1515,14 @@ class GoTextFormat(JSONFormat):
     supports_plural: bool = True
 
 
+class FormatJSFormat(JSONFormat):
+    name = gettext_lazy("Format.JS JSON file")
+    format_id = "formatjs"
+    loader = ("jsonl10n", "FormatJSJsonFile")
+    autoload = ()
+    check_flags = ("icu-message-format",)
+
+
 class CSVFormat(TTKitFormat):
     name = gettext_lazy("CSV file")
     format_id = "csv"


Test patch: