inlang
ICU MessageFormat v1

ICU MessageFormat v1

Plugin

The ICU MessageFormat v1 plugin is a storage plugin for inlang. It reads and writes ICU1 strings in JSON files per locale. It targets ICU MessageFormat v1 (a.k.a. ICU MessageFormat) and maps it onto inlang's data model so selectors and variants are preserved.

Features

  • Parses ICU1 messages using @messageformat/parser.
  • Supports select, plural, and selectordinal, including exact matches (=n) and offset.
  • Supports # (octothorpe) inside plural/selectordinal cases. # imports as {$count :icu:pound}, with an offset option when the plural has one ({$count :icu:pound offset=1}), because # displays count - offset.
  • Supports formatter functions (e.g. number, date, time, spellout, ordinal, duration) with style parameters.
  • Exports ICU1 strings back from inlang data.

Installation

Install the plugin in your Inlang Project by adding it to your modules in project.inlang/settings.json and configure pathPattern.

// project.inlang/settings.json
{
  "modules": [
+    "https://cdn.jsdelivr.net/npm/@inlang/plugin-icu1@latest/dist/index.js"
  ],
+ "plugin.inlang.icu-messageformat-1": {
+   "pathPattern": "./messages/{locale}.json"
+ }
}

Configuration

Configuration happens in project.inlang/settings.json under "plugin.inlang.icu-messageformat-1".

pathPattern

You can define a single pathPattern or provide an array of patterns. The placeholder should be {locale}.

Single path pattern example

{
  "plugin.inlang.icu-messageformat-1": {
    "pathPattern": "./messages/{locale}.json"
  }
}

Multiple path patterns example

{
  "plugin.inlang.icu-messageformat-1": {
    "pathPattern": ["./defaults/{locale}.json", "./product/{locale}.json"]
  }
}

[!NOTE] Multiple patterns are a one-way merge for import. When exporting, a file that doesn't exist yet gets all messages of its locale (one file per pattern and locale). Existing files keep their messages: an edited or deleted message only changes in the files that have it, and a new message is added to every file of its locale.

Messages

ICU1 files contain key-value pairs with ICU MessageFormat strings.

// messages/en.json
{
  "hello_world": "Hello World!",
  "greeting": "Good morning {name}!",
  "likes": "You have {count, plural, one {# like} other {# likes}}"
}

Plurals and selectordinal

{
  "items": "{count, plural, offset:1 =0 {no items} one {# item} other {# items}}",
  "rank": "{place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}"
}

Select

{
  "gender": "{gender, select, male {He} female {She} other {They}}"
}

Escaping

ICU1 uses apostrophes to escape literals. To include literal braces, wrap them in apostrophes:

  • `'{'
  • '}'

If you need a literal apostrophe, use '' (two single quotes).

Caveats

  • Export is canonicalized. Output is semantically equivalent, but whitespace and formatting may differ from the original source.
  • Tags/markup are treated as plain text by the parser.