I have a couple of questions about best practices and the workflow when working with i18n
I am currently using react-i18next
I am defining the keys directly with default values in the components and then extracting them using babel-plugin-i18next-extract
Example
<I18nText
ns="meeting"
i18nKey="meeting-invitation.videoConferenceLink"
defaults="You can join the video conference call for {{meeting.name}} when it starts via: <br /> <0>{{meeting.videoConference.link}}</0>"
components={[
<a
href={meeting.videoConference.link}
target="_blank"
rel="noopener noreferrer"
>
{meeting.videoConference.link}
</a>,
]}
values={{ meeting }}
/>
Note: I18nText
is a custom component wrapping Trans
component
Questions:
1️⃣ Should I put keywords that I use a lot across the app into their own key? if so, how do I handle pluralization, formatting and using context at the same time?
let's say that I use the keywords meeting
and action
across the app and I have a sentence like this
0 meetings, 0 actions => You have no scheduled meetings and no actions deadlines so far to prepare for.
1 meeting, 1 action => You have 1 scheduled meeting and 1 action deadline so far to prepare for.
2-inf meetings, 2-inf actions => You have (2-inf) scheduled meetings and (2-inf) action deadlines so far to prepare for.
meetings
and actions
can have a different count, I am aware that I can use nesting and that I pass count to each nested key like this
"key": "You have $t(glossary:scheduledMeetingWithCount, {\"count\": {{meetingCount}}}) and $t(glossary:actionDeadlinesWithCount, {\"count\": {{actionCount}}}) so far to prepare for."
But won't the translators get confused with all the nesting and passing count? and the scheduledMeetingWithCount
and the actionDeadlinesWithCount
keys, to what namespace should they be in? glossary
? each in their own related namespace as in meeting
and action
namespaces?
and how should there definition look like
"scheduledMeetingWithCount": "1 scheduled meeting",
"scheduledMeetingWithCount_plural": "{{count}} scheduled meeting",
"scheduledMeetingWithCount_0": "no scheduled meetings" // doesn't i18next not support `_0` for `en`?
and won't that make the keys meeting
and action
be needed to be translated multiple times? as when it's defined alone meeting
, its plural form meetings
, when there is a count no meetings
, 1 meeting
and (2-inf) meeting
, and when I need to add scheduled
before the meeting name as in 1 scheduled meeting
, {{count}} scheduled meetings
and no scheduled meetings
? Am I going to do this for each keyword I use across the system?
2️⃣ How can I format nested keys?
Let's say I have a key with value Meetings are scheduled for next week
and I have a key for meeting_plural
wtih the value meetings
, but it's lowercase but I have a format function titleCase
So I wanted to use something like {{$t(glossary:meeting_plural), titleCase}} are scheduled for next week
but that results in meeting_plural), titleCase}} are scheduled for next week
I've also tried
t('{{meeting, titleCase}} are scheduled for next week', {meeting: '$t(glossary:meeting_plural)'})
but that results in $T(Glossary:Meeting_Plural) are scheduled for next week
so I ended up using
t('{{meeting, titleCase}} are scheduled for next week', { meeting: t('glossary:meeting_plural') })
which worked but is that best practice, should I just leave the translator to translate meetings again? should I add another key for when the "meetings" is title-cased?
3️⃣ How to handle variations in values, should I use context or add a key for every variation? if I use context how do I extract each context that is required?
I have a sentence that changes based on whether the passed action has the property dueDate
or not
when dueDate
exists it shows this
Looks like you have a new action to complete: <strong>{{ action.title }}</strong> assigned by <strong> {{ action.creator.name }} </strong> and to be completed before <strong>{{ action.dueDate, dddd, MMMM Do, YYYY }}</strong>.
if dueDate
doesn't exist it shows
Looks like you have a new action to complete: <strong>{{ action.title }}</strong> assigned by <strong> {{ action.creator.name }} </strong>.
how should I handle this case? should they be separated in their own keys? I've tried using context like this
t('action:action-assigned.content', {
context: action.dueDate && 'dated'
})
and keys to action.json
as
"action-assigned.content": "Looks like you have a new action to complete: <strong>{{ action.title }}</strong> assigned by <strong> {{ action.creator.name }} </strong>.",
"action-assigned.content_dated": "Looks like you have a new action to complete: <strong>{{ action.title }}</strong> assigned by <strong> {{ action.creator.name }} </strong> and to be completed before <strong>{{ action.dueDate, dddd, MMMM Do, YYYY }}</strong>."
is that the right use of context? I had to add these keys manually, not by the extraction tool and had to turn off discardOldKeys
because it was removing the key with _dated
4️⃣ How do I organize my common keys?
do I throw anything that I'll use across the system in the common
namespace and is it okay if I named the key with its value? or would it better to give them a specific key
5️⃣ Should I abstract values that are similar but have different nouns?
I have the values View action
, View project
, View meeting
, ...etc. should I make a key with the value View {{item}}
and pass the key
for the noun that I want to use or should I just make each value in it's key?
6️⃣ Is there a TMS that support i18next-intervalPlural-postProcessor?
7️⃣ Should I switch to using I18next-icu?
I found ICU
to handle pluralization better than i18next
default format because in en
I can add a specific condition to 0
instead of being limited to key
and key_plural
and ICU
also has select
which is like a switch statement which solves some of the issues that I have, Why doesn't i18next
have something like select
? is context
supposed to handle the use-case that select
handles?
8️⃣ Does anyone has any personal recommendation for a TMS that they used before and liked?
I want one that supports i18next
features well, I've looked into locize but found their pricing hard to predict I would rather have something with a fixed price
9️⃣ Is there is a resource that I can learn best-practices and learn how to scale i18n?
I've searched for i18n resources but found the community to be a little lacking in in-depth guidance or an end-to-end workflow guide, I've mostly been trying things by trial and error but am not sure if I will be facing a roadblock or have growing pains with the current implementation am using