- Published on
- • 3 min read
Translating JSX - How to use Conditionals
Introduction
One of the most common mistakes I see in internationalization is the tendency to split simple ternary statements into multiple translation calls. It will often look something like this:
const gt = useGT()
return (
<>
<span>
<T> Dark Mode: </T>
</span>
<Button>{enabled ? gt('On') : gt('Off')}</Button>
</>
)
For the most part, this works as intended. Prior to implementing i18n, the code probably looked something like { enabled ? 'On' : 'Off' }
. Adding the gt()
function for i18n was probably just a natural extension of the existing code structure.
Every time I see this, I physically cringe a little. This is not at all how the library was designed to be used. There are two arguments for why this is a mistake, especially in the context of using machine translation: (1) Context and (2) Flexibility.
Context
Meaning is not only embedded in the words but also in how words are presented. The word "back", if located on a back arrow, probably means something very different than the word "back" on a chiropractor's resume. Additionally, without a larger context, translators (even human ones) might have difficulty translating the word correctly. There's a famous story of WhatsApp's i18n department translating the word "crop" on an image editor tool to "crop" as in farming in German.
To get around this context issue, we can pass information about the presentation of content with the <T>
and <Branch>
components. In our example, this would give our "translator" a larger picture of what "on" and "off" means.
<T>
<span>Dark Mode:</span>
<Button>
<Branch branch={enabled.toString()} true="On" false="Off" />
</Button>
</T>
Flexibility
Beyond context, another cool way we can leverage LLM translation is through its understanding of code. Let's look at an example where the order of components might change depending on the language:
<T>
I eat lunch at <Branch branch={atHome.toString()} true="home" false="work" />.
</T>
So we have two possible sentences:
- "I eat lunch at home"
- "I eat lunch at work"
In Mandarin we would have:
- "我在家吃午餐"
- "我在公司吃午餐"
The <T>
component recognizes that the sentence order must change here, and it rearranges its children accordingly—something that is not easily possible while using ternary operators with string translation.
<T>
我在
<Branch branch={atHome.toString()} true="家" false="公司" />
吃午餐。
</T>
Conclusion
If you take anything away from this article, you should always be looking for ways to leverage context and flexibility in your code. Using the <Branch />
component is probably one of the easiest ways to do this.
Check out the <Branch />
component documentation for more details.