@lingui/macro - Reference¶
@lingui/macro
package provides babel macros which
transforms JavaScript objects into messages in ICU MessageFormat.
Overview¶
All JSX macros are transformed to <Trans> component from @lingui/react. Other macros are transformed into message descriptors.
The advantages of using macros vs. low level API are:
generated message format is guaranteed to be syntactically valid
components and functions are type checked
additional validation of plural rules is performed during transformation
output of macros depends on target environemnt. Non essentials data are removed in production build.
Following examples are the same messages above but written using JSX macros. As above, macros create a message in MessageFormat syntax, but this time the result in <Trans> component:
Generated message is used as a message ID in catalog, but can be overriden by custom ID.
Installation¶
Babel macros require babel-plugin-macros to work. If you use a framework (for example GatsbyJS, Create React App >2.0) you might already have macros enabled. Otherwise install it as any other Babel plugin:
Install
babel-plugin-macros
and@lingui/macro
as a development dependency:npm install --save-dev babel-plugin-macros @lingui/macro # yarn add --dev babel-plugin-macros @lingui/macro
Add
macros
to the top of plugins section in your Babel config.{ "plugins": [ "macros" ] }
Usage¶
JS macros¶
These macros can be used in any context (e.g. outside JSX) and are intended to work in combination with i18n._ method. All JS macros are transformed into a Message Descriptor which is an object with message ID, default message and other parameters. i18n._ accepts message descriptors and performs translation and formatting:
type MessageDescriptor = {
id: String,
message?: String,
values?: Object,
formats?: Object,
comment?: string
}
id
is message ID and the only required parameter. id
and message
are extracted to message catalog. Only id
, values
, and formats
are used at runtime, all other attributes are removed from production code
for size optimization.
Note
i18n comment
In the examples below you might notice /*i18n*/
comment in
macro output. This comment tells the extract plugin that following
object or string should be collected to message catalog.
t¶
-
t
¶
The most common macro for messages. It transforms tagged template literal into message in ICU MessageFormat. It’s allowed to use other i18n macros as variables.
import { setupI18n } from "@lingui/core"
import { t } from "@lingui/macro"
const i18n = setupI18n()
// Static Message
const static = i18n._(t`Static Message`)
// ↓ ↓ ↓ ↓ ↓ ↓
// const static = i18n._(/*i18n*/{
// id: 'Static',
// })
// My name is {name}
const vars = i18n._(t`My name is ${name}`)
// Macros can be nested, date is macro for date formatting
const date = i18n._(t`Today is ${date(name)}`)
plural¶
-
plural
¶
function plural(value: string | number, options: Object)
plural
macro is used for pluralization, e.g: messages which has different form
based on counter. It accepts an object with required key value
which determines
the plural form. The only required plural form is a catch-all other
. Other forms
depends on source language you’re using (e.g: English has one
and other
plural
forms).
import { setupI18n } from "@lingui/core"
import { plural } from "@lingui/macro"
const i18n = setupI18n()
const msg = i18n._(plural(count, {
one: "# Book",
other: "# Books"
}))
// t macro isn't required for nested messages,
// template strings are transformed automatically.
const vars = i18n._(plural(count, {
one: `${name} has # friend`,
other: `${name} has # friends`
}))
// Example of pluralization using two counters
const double = i18n._(plural(numBooks, {
one: plural({
value: numArticles,
one: `1 book and 1 article`,
other: `1 book and ${numArticles} articles`,
}),
other: plural(numArticles, {
one: `${numBooks} books and 1 article`,
other: `${numBooks} books and ${numArticles} articles`,
}),
}))
date¶
-
date
¶
This macro marks variable as a date which is formatted using Intl.DateTimeFormat.
First parameter is a value to be formatted.
Second argument (optional) specifies date format.
import { setupI18n } from "@lingui/core"
import { t, date } from "@lingui/macro"
const i18n = setupI18n()
const today = new Date()
const msg = i18n._(t`Today is ${date(today)}.`)
number¶
-
number
¶
This macro marks variable as a number which is formatted using Intl.NumberFormat.
First parameter is a value to be formatted.
Second argument (optional) specifies number format.
import { setupI18n } from "@lingui/core"
import { t, number } from "@lingui/macro"
const i18n = setupI18n()
const msg = i18n._(t`There were ${number(10000)} people.`)
const percent = i18n._(t`Interest rate is ${number(0.05, "percent")}.`)
defineMessage¶
-
defineMessage
¶
defineMessage
macro is a wrapper around macros above which allows you
to add comments for translators or override the message ID.
```js type MessageDescriptor = {
id?: string, message?: string, comment?: string
}
function defineMessage(message: MessageDescriptor) ```
Either id
or message
property is required.
id
is a message id. If it isn’t set, the message
is used instead.
message
is the default message. Any macro can be used here.
comment
is a comment for translators. It’s extracted o message catalog and it gives
extra context for translators.
Examples:
defineMessage
macro is mostly used to add comment
for translators or to override
the default message ID:
import { defineMessage } from "@lingui/macro"
// add comment and override id
const message = defineMessage({
id: "Navigation / About",
comment: "Link in navigation pointing to About page",
message: "About us"
})
// ↓ ↓ ↓ ↓ ↓ ↓
const message = /*i18n*/{
id: 'Navigation / About',
comment: "Link in navigation pointing to About page",
message: "About us"
}
import { defineMessage } from "@lingui/macro"
// just add comment
const message = defineMessage({
comment: "Link in navigation pointing to About page",
message: "About us"
})
// ↓ ↓ ↓ ↓ ↓ ↓
const message = /*i18n*/{
comment: "Link in navigation pointing to About page",
id: "About us"
}
Any macros used in message
are expanded as if the macro
were used outside defineMessage
:
import { defineMessage, t } from "@lingui/macro"
const name = "Joe"
const message = defineMessage({
comment: "Greetings on the welcome page",
message: t`Welcome, ${name}!`
})
// ↓ ↓ ↓ ↓ ↓ ↓
const message = /*i18n*/{
comment: "Greetings on the welcome page",
message: "Welcome, {name}",
values: {
name
}
}
Note
In production build, the macro is replaced with an id
string:
import { defineMessage } from "@lingui/macro"
const message = defineMessage({
id: "Navigation / About",
comment: "Link in navigation pointing to About page",
message: "About us"
})
// process.env.NODE_ENV === "production"
// ↓ ↓ ↓ ↓ ↓ ↓
const message = "Navigation / About"
message
and comment
are used only in message catalogs.
defineMessages¶
-
defineMessages
¶
defineMessages macro is a helper function to define several messages at once.
function defineMessages(messages: {
[key: string]: string | MessageDescriptor
})
Object values passed to defineMessages
can be either strings, for simple messages,
or message descriptors. In such case they’re transformed in the same way as in
defineMessage
macro:
import { defineMessages } from "@lingui/macro"
const messages = defineMessages({
ok: "OK",
about: {
id: "Navigation / About",
comment: "Link in navigation pointing to About page",
message: "About us"
}
})
// ↓ ↓ ↓ ↓ ↓ ↓
const messages = {
ok: /*i18n*/"OK",
about: /*i18n*/{
id: "Navigation / About",
comment: "Link in navigation pointing to About page",
message: "About us"
}
}
Note
In production build, the all message descriptors are replaced with message id:
import { defineMessages } from "@lingui/macro"
const messages = defineMessages({
ok: "OK",
about: {
id: "Navigation / About",
comment: "Link in navigation pointing to About page",
message: "About us"
}
})
// process.env.NODE_ENV === "production"
// ↓ ↓ ↓ ↓ ↓ ↓
const messages = {
ok: "OK",
about: "Navigation / About",
}
JSX Macros¶
Common props¶
All macros share following props:
id¶
Each message in catalog is identified by message ID.
While all macros use generated message as the ID, it’s possible to override it. In such case, generated message is used as a default translation.
import { Trans } from "@lingui/macro"
<Trans id="message.attachment_saved">Attachment {name} saved.</Trans>
// ↓ ↓ ↓ ↓ ↓ ↓
// <Trans id="message.attachment_saved" message="Attachment {name} saved." />
comment¶
Comment for translators to give them additional context about the message. It’s removed from production code.
render¶
Custom component to render translation into. This prop is directly passed to <Trans> component from @lingui/react. See rendering of translations for more info.
Trans¶
-
Trans
¶ - Props
id (string) – Custom message ID
<Trans> is the basic macro for static messages, messages with variables, but also for messages with inline markup.
import { Trans } from "@lingui/macro"
<Trans>Refresh inbox</Trans>;
// ↓ ↓ ↓ ↓ ↓ ↓
// <Trans id="Refresh inbox" />
<Trans id="message.attachment_saved">Attachment {name} saved.</Trans>
// ↓ ↓ ↓ ↓ ↓ ↓
// <Trans id="message.attachment_saved" message="Attachment {name} saved." />
This macro is especially useful when message contains inline markup.
import { Trans } from "@lingui/macro"
<Trans>Read the <a href="/docs">docs</a>.</Trans>;
// ↓ ↓ ↓ ↓ ↓ ↓
// <Trans id="Read the <0>docs</0>." components={{0: <a href="/docs" />}} />
Components and HTML tags are replaced with dummy indexed tags (<0></0>
) which
has several advatanges:
both custom React components and built-in HTML tags are supported
change of component props doesn’t break the translation
the message is extracted as a whole sentence (this seems to be obvious, but most i18n libs simply split message into pieces by tags and translate them separately)
Plural¶
-
Plural
¶ - Props
value (number) – (required) Value is mapped to plural form below
format (string|Object) – Number format passed as options to Intl.NumberFormat
offset (number) – Offset of value when calculating plural forms
zero (string) – Form for empty
value
one (string) – Singular form
two (string) – Dual form
few (string) – Paucal form
many (string) – Plural form
other (string) – (required) general plural form
_<number> (string) – Exact match form, corresponds to
=N
rule
MessageFormat:
{arg, plural, ...forms}
Props of <Plural> macro are transformed into plural
format.
import { Plural } from "@lingui/macro"
<Plural value={numBooks} one="Book" other="Books" />
// ↓ ↓ ↓ ↓ ↓ ↓
// <Trans id="{numBooks, plural, one {Book} other {Books}}" values={{ numBooks }} />
#
are formatted using number
format. format
prop is passed to this
formatter.
Exact matches in MessageFormat syntax are expressed as =int
(e.g. =0
),
but in React this isn’t a valid prop name. Therefore, exact matches are expressed as
_int
prop (e.g. _0
). This is commonly used in combination with
offset
prop. offset
affects only plural forms, not exact matches.
import { Plural } from "@lingui/macro"
const count = 42
<Plural
value={count}
offset={1}
// when value == 0
_0="Nobody arrived"
// when value == 1
_1="Only you arrived"
// when value == 2
// value - offset = 1 -> `one` plural form
one="You and # other guest arrived"
// when value >= 3
other="You and # other guests arrived"
/>
// This is transformed to Trans component with ID:
// {count, plural, _0 {Nobody arrived}
// _1 {Only you arrived}
// one {You and # other guest arrived}
// other {You and # other guests arrived}}
Select¶
-
Select
¶ - Props
value (number) – (required) Value determines which form is outputted
other (number) – (required) Default, catch-all form
MessageFormat:
{arg, select, ...forms}
Props of <Select> macro are transformed into select
format:
import { Select } from "@lingui/macro"
// gender == "female" -> Her book
// gender == "male" -> His book
// gender == "unspecified" -> Their book
<Select
value={gender}
male="His book"
female="Her book"
other="Their book"
/>
SelectOrdinal¶
-
SelectOrdinal
¶ - Props
value (number) – (required) Value is mapped to plural form below
offset (number) – Offset of value for plural forms
zero (string) – Form for empty
value
one (string) – Singular form
two (string) – Dual form
few (string) – Paucal form
many (string) – Plural form
other (string) – (required) general plural form
_<number> (string) – Exact match form, correspond to
=N
rule. (e.g:_0
,_1
)format (string|Object) – Number format passed as options to Intl.NumberFormat
MessageFormat:
{arg, selectordinal, ...forms}
Props of <SelectOrdinal> macro are transformed into selectOrdinal
format:
import { SelectOrdinal } from "@lingui/macro"
// count == 1 -> 1st
// count == 2 -> 2nd
// count == 3 -> 3rd
// count == 4 -> 4th
<SelectOrdinal
value={count}
one="1st"
two="2nd"
few="3rd"
other="#th"
/>