icu-to-json
v0.0.20
Published
Compile ICU MessageFormat strings to JSON at build time and render them at runtime
Downloads
36
Readme
icu-to-json
Precompile i18n icu syntax translations to JSON at build time and render them at runtime
Build Time: compile("Hello {name}")
→ ["Hello ",["name"]]
Run Time: run( ["Hello ",["name"]], { name: "World"} )
→ "Hello World"
Goal
The main goal is to boot up javascript apps with ICU translations as fast as possible for the end user.
Therefore this library provides a way to compile ICU MessageFormat strings to compressed JSON at build time and render them at runtime with a minimal runtime footprint.
Features
- Smaller Runtime Footprint
The runtime footprint is only 1kb (minified and gzipped) - No parsing at runtime
The precompiled JSON can be rendered without any string parsing at runtime - Flexible
The runtime is able to not only return strings but also any object (aka rich text elements like JSX) - Types
The compiler has an optional feature to generate typescript types for the ICU messages and their arguments
⚠️ the typed t()
function is not part of this library. It is only an example how the generated types could be used.
Installation
npm install icu-to-json
Usage
Runtime
Pure Interpolations
import { run } from 'icu-to-json';
// e.g. precompiled icu messsage:
// "Hello {name}!"
run(precompiledMessage, "en", { name: 'World' })) // Hello, World!
Plurals and Selectordinal
import { run } from 'icu-to-json';
// e.g. precompiled icu messsage:
// "You have {count, plural, one {# unread message} other {# unread messages}}."
run(precompiledMessage, "en", { count: 1 })) // You have 1 unread message.
Tags
Tags can be used to wrap parts of the message.
import { run } from 'icu-to-json';
// e.g. precompiled icu messsage:
// "You have <b>{count}</b> messages."
run(precompiledMessage, "en", { count: 2, b: (content: number) => `**${number}**`})) // You have **2** messages.
Rich Text
The runtime is able to not only return strings but also richtext elements (e.g. JSX).
JSX is only used as an example here - it works with any other object as well.
import { evaluateAst } from 'icu-to-json';
// e.g. precompiled icu messsage:
// "You have <link><b>{count, plural, one {# unread message} other {# unread messages}}.</b></link>"
evaluateAst(precompiledMessage, "en", {
count: 1,
link: (content: string) => <a href="/messages">{content}</a>,
b: (content: string) => <b>{content}</b>
}) // [ 'You have ', <a href="/messages"><b>1 unread message.</b></a> ]
Compile
CLI
The CLI can be used to compile ICU MessageFormat strings to JSON at build time.
# compile icu messages to json
icu-to-json src/messages.json dist/messages.json
# generate typescript types, locales and formatters from the icu messages
icu-to-json --types src/messages.json dist/messages.json
API
import { compile } from 'icu-to-json/compiler';
const precompiledMessage = compile('Hello {name}!');
Status
This library is still in early development and not yet ready for production use.
How does it work?
The main work is done by the @formatjs/icu-messageformat-parser
, which parses the ICU MessageFormat strings and returns an AST.
The AST is then traversed and compiled to JSON by icu-to-json
.
License
MIT