Why React components instead of key or functions
See original GitHub issueJust to make it clear, there’re two i18n APIs:
lingui-i18n
, for vanilla javascript (i18n.t'Hello World'
). This works without React and it’s a base for future integrations.lingui-react
, for React components (<Trans>Hello World</Trans>
) which under the hood useslingui-i18n
, so it’s possible to use it for translation of attributes (<Trans title={i18n.t'Title'}>Hello World</Trans>
)
Components vs. functions
React is all about rendering data. When data changes, React renders updates. Given example below:
<span>{i18n.t`Hello World`}</span>
<Trans>Hello World</Trans>
when language or message catalog changes, the span
(or probably parent component) is responsible for update, while Trans
take care of it itself. When parent component is optimized using shouldComponentUpdate
, the Trans
component will update the translated message even when parent skips update.
Reason 1: Using Trans
component shifts responsibility from parent to Trans
component itself. As a developer, you don’t have to worry about skipped updates.
Second reason are inline components. Using Trans
component you can go wild a do things like this:
<Trans>
Any component is <strong className="green">valid</strong> here, even <Link>custom</Link> ones.
</Trans>
Example above will result in single entry in your message catalog: Any component is <0>valid</0> here, even <1>custom</1> ones.
This has several advantages:
- Translator doesn’t care about html tags
- Props of inline components doesn’t affect message
- You get only one message. This is obvious, but other libs (
i18next
,formatjs
) translate content of inline components separately which is unfortunate for translators.
Reason 2: First-class support for inline components. As a developer, you can use JSX as you’re used to. As a translator, you see the full message.
In future I’m planning further optimization, when message is rendered to React components tree and when props changes (like values, params) the message isn’t parsed from scratch, but React handle update itself. Right now, message itself is cached, but inline components are rendered on each update.
Key vs. source language
// key
i18n.t`component.title`
// message in source language
i18n.t`Title`
Both approaches have pros & cons. I never settled to either solution. I’m trying to support both approaches:
// Key
<Trans id=`msg.hello`>Hello World</Trans>
// becomes {'msg.hello': 'Hello World'} for English
// Message
<Trans>Hello World</Trans>
// becomes {'Hello World': 'Hello World'} for English
I’m using second approach in examples because it’s easier to start with.
Issue Analytics
- State:
- Created 7 years ago
- Comments:20 (6 by maintainers)
@cJayyy Yeah, sorry, this issues was opened almost 2 years ago. Meanwhile,
react-i18next
implemented similar concept with few exceptions. The main one is that they process JSX children at runtime - because of that you have to use double curly braces for variables. Unfortunately,object as a child
isn’t a valid JSX so some linters might not like it.I’m closing this issue, as it was mostly discussion and it’s clearly outdated.
According to i18next docs this doesn’t seem to be up-to-date. In their example sandbox complex message extraction results into one piece.