Common i18n patterns in React¶
Following page describes the most common i18n patterns in React. It’s a follow-up to tutorial with practical examples. See the API reference for detailed information about all components.
Macros¶
Using jsx macros is the most straightforward way how to translate your React components.
<Trans> handles translations of messages including variables and other React components:
import { Trans } from "@lingui/macro"
<h1><Trans>LinguiJS example</Trans></h1>
<p><Trans>Hello <a href="/profile">{name}</a>.</Trans></p>
You don’t need anything special to use <Trans> inside your app (except of wrapping the root component in <I18nProvider>).
Using ID generated from message¶
With <Trans>¶
In the examples above, the content of <Trans> is transformed into
message in MessageFormat syntax. By default, this message is used as the message ID.
Considering the example above, messages LinguiJS example
and Hello <0>{name}</0>.
are extracted and used as IDs.
With t¶
In the following example, message Image caption
will be extracted and used as ID.
import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"
export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t`Image caption`)} />
)}
</I18n>
)
}
Using custom ID¶
With <Trans>¶
If you’re using custom IDs in your project, add id
prop to i18n components:
import { Trans } from "@lingui/macro"
<h1><Trans id="msg.header">LinguiJS example</Trans></h1>
<p><Trans id="msg.hello">Hello <a href="/profile">{name}</a>.</Trans></p>
Messages msg.header
and msg.hello
will be extracted with default values
LinguiJS example
and Hello <0>{name}</0>.
.
With t¶
If you’re using custom IDs in your project, call t with ID as a first argument and then use string templates as usual:
import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"
export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t('msg.caption')`Image caption`)} />
)}
</I18n>
)
}
Message msg.caption
will be extracted with default value Image caption
.
For all other js macros (plural, select, selectOrdinal),
pass ID as the first param (in this case, 'msg.caption'
):
import { I18n } from "@lingui/react"
import { plural } from "@lingui/macro"
export default function ImageWithCaption({ count }) {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(plural('msg.caption', {
value: count,
one: "# image caption",
other: "# image captions",
}))} />
)}
</I18n>
)
}
Element attributes and string-only translations¶
Sometimes you can’t use <Trans> component, for example when translating element attributes:
<img src="..." alt="Image caption" />
In such case you need to use <I18n> render prop component to access i18n
object and t macro to wrap message:
Use
withI18n()
HOC or <I18n> render prop component from@lingui/react
, to accessi18n
object.Call
i18n._`()
to translate message wrapped in JS macros. t is equivalent for <Trans>, plural is equivalent to <Plural>.
// using the withI18n HOC
import { withI18n } from "@lingui/react"
import { t } from "@lingui/macro"
function ImageWithCaption({ i18n }) {
return <img src="..." alt={i18n._(t`Image caption`)} />
}
export default withI18n(ImageWithCaption)
// using the render prop
import { I18n } from "@lingui/react"
import { t } from "@lingui/macro"
export default function ImageWithCaption() {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(t`Image caption`)} />
)}
</I18n>
)
}
Translations outside React components¶
Another common pattern is when you need to access translations (i18n
object)
outside React components, for example inside redux-saga
:
Create your own instance of
i18n
usingsetupI18n()
form@lingui/core
Pass this instance as
i18n
prop to <I18nProvider>.// App.js import { setupI18n } from "@lingui/core" import { I18nProvider } from "@lingui/react" export const i18n = setupI18n() export default function App() { return ( <I18nProvider i18n={i18n}> {/* Our app */} </I18nProvider> ) }
Whenever you are outside React context (i.e. you can’t access props), you can use this
i18n
object.import { i18n } from "./App.js" import { t } from "@lingui/macro" export function alert() { // use i18n as if you were inside a React component alert(i18n._(t`...`)) }
Lazy translations¶
Messages don’t have to be declared at the same code location where they’re displayed.
Tag a string with the t macro, and you’ve created a “message descriptor”, which
can then be passed around as a variable, and can be displayed as a translated string by
passing it to <Trans> as its id
prop:
import { t, Trans } from "@lingui/macro"
const favoriteColors = [
t`Red`,
t`Orange`,
t`Yellow`,
t`Green`,
]
export default function ColorList() {
return (
<ul>
{favoriteColors.map(color => (
<li><Trans id={color}/></li>
}
</ul>
)
}
Or to render the message descriptor as a string-only translation, just pass it to
the I18n._()
method as usual:
import { t } from "@lingui/macro"
const favoriteColors = [
t`Red`,
t`Orange`,
t`Yellow`,
t`Green`,
]
const translatedColorNames = favoriteColors.map(
color => i18n._(color)
)
Passing messages as props¶
It’s often convenient to pass messages around as component props, for example as a “label” prop on a button. The easiest way to do this is to pass a <Trans> element as the prop:
import { Trans } from "@lingui/macro"
export default function FancyButton(props) {
return <button>{props.label}</button>
}
export function LoginLogoutButtons(props) {
return <div>
<FancyButton label={<Trans>Log in</Trans>} />
<FancyButton label={<Trans>Log out</Trans>} />
</div>
}
If you need the prop to be displayed as a string-only translation, you can pass a message descriptor (tagged with the t macro), and have the component render it as a string using lazy translation:
import { t } from "@lingui/macro"
import { I18n } from "@lingui/react"
export default function ImageWithCaption(props) {
return (
<I18n>
{({ i18n }) => (
<img src="..." alt={i18n._(props.caption)} />
)}
</I18n>
)
}
export function HappySad(props) {
return <div>
<ImageWithCaption
hoverText={t`I'm so happy!`}
/>
<ImageWithCaption
hoverText={t`I'm so sad.`}
/>
</div>
}
Picking a message based on a variable¶
Sometimes you need to pick between different messages to display, depending on the value of a variable. For example, imagine you have a numeric “status” code that comes from an API, and you need to display a message representing the current status.
A simple way to do this, is to make an object that maps the possible values of “status” to message descriptors (tagged with the t macro), and render them as needed with lazy translation:
import { Trans } from "@lingui/macro";
const STATUS_OPEN = 1,
STATUS_CLOSED = 2,
STATUS_CANCELLED = 4,
STATUS_COMPLETED = 8
const statusMessages = {
[STATUS_OPEN]: t`Open`,
[STATUS_CLOSED]: t`Closed`,
[STATUS_CANCELLED]: t`Cancelled`,
[STATUS_COMPLETED]: t`Completed`,
}
export default function StatusDisplay(statusCode) {
return <div><Trans id={statusMessages[statusCode]} /></div>
}