-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recipe: Migrating from i18n-js to react-i18next #177
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. It does slightly differ some of the setup you've done in v10, but if you're OK with this and this is more of a shortcut in terms of making the minimum amount of work to switch, I'm fine with that.
One observation is to just make a note about which file the edits will be located in for the main setup after the dependency step
docs/recipes/MigratingToI18Next.md
Outdated
|
||
### Update translation initialization | ||
|
||
Modify your translation initialization logic to use the `initReactI18next` from `i18next`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd point the user in the direction of which file it is they should be modifying here (at least in terms of standard previous ignite builds), app/i18n/i18n.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frankcalise added
Thanks @frankcalise! It was meant to be minimal, but let me recheck my PR to add another important steps or suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two points to mention. I would recommend we put all translations in their own TS files and also add typesafety. happy to pair on this if needed
Thanks @mazenchami. I think I'm assuming here that whoever is reading is, did generate a RN app from Ignite, which already should have translations in each file with type safety. Let me know if that's a good assumption. |
Yes, good call. this looks good to me! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
docs/recipes/MigratingToI18Next.md
Outdated
}); | ||
``` | ||
|
||
In a project generated by Ignite, this can be found in the app/i18n/i18n.ts file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a project generated by Ignite, this can be found in the app/i18n/i18n.ts file. | |
In a project generated by Ignite, this can be found in the `app/i18n/i18n.ts` file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🎉 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing this up. I followed along and I ran into several issues (quite understandable since we kind of changed the direction of this recipe and it's across two PRs now).
I left lots of comments/suggestions, depending on the direction you want to take here.
My process for following was spinning up an Ignite 9 application and trying to work through the steps.
Definitely some of the things I mentioned don't hvae to be so exact, but I do feel like a few of these things so get mentioned, whether or not the syntax is exactly correct (because of course people change their projects too).
Use your best judgement if you don't think all of them belong, but I think I uncovered most of the items here.
docs/recipes/MigratingToI18Next.md
Outdated
yarn remove i18n-js | ||
yarn remove @types/i18n-js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can be combined into one command yarn remove i18n-js @types/i18n-js
docs/recipes/MigratingToI18Next.md
Outdated
Add the two new dependencies: | ||
|
||
```bash | ||
yarn add react-i18nex i18next |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yarn add react-i18nex i18next | |
yarn add react-i18next i18next |
docs/recipes/MigratingToI18Next.md
Outdated
|
||
import * as i18next from "i18next" | ||
|
||
const initI18n = async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const initI18n = async () => { | |
export const initI18n = async () => { |
|
||
## Step 6: Update translation keys from dots (.) to colons (:) | ||
|
||
`react-i18next` uses different types of separators for translation keys. Colons (:) are used for first-level translations within an object, while dots (.) are used for nested translations. As a result, you’ll need to update all translation keys in your app accordingly. For example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In doing this dot notation to colon notation, you will receive errors on any tx
prop until you update the types in i18n.ts to
type RecursiveKeyOf<TObj extends object> = {
[TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue<TObj[TKey], `${TKey}`, true>
}[keyof TObj & (string | number)]
type RecursiveKeyOfInner<TObj extends object> = {
[TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue<TObj[TKey], `${TKey}`, false>
}[keyof TObj & (string | number)]
type RecursiveKeyOfHandleValue<
TValue,
Text extends string,
IsFirstLevel extends boolean,
> = TValue extends any[]
? Text
: TValue extends object
? IsFirstLevel extends true
? Text | `${Text}:${RecursiveKeyOfInner<TValue>}`
: Text | `${Text}.${RecursiveKeyOfInner<TValue>}`
: Text
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So after showing this change, I'd probably show an example of changing some props as you did with the translate function below (but we generally don't use that one as much in the boilerplate). Maybe an example from the <WelcomeScreen />
since it's pretty straight forward, for example:
useHeader(
{
rightTx: "common:logOut",
onRightPress: logout,
},
[logout],
)
return (
<View style={$container}>
<View style={$topContainer}>
<Image style={$welcomeLogo} source={welcomeLogo} resizeMode="contain" />
<Text
testID="welcome-heading"
style={$welcomeHeading}
tx="welcomeScreen:readyForLaunch"
preset="heading"
/>
<Text tx="welcomeScreen:exciting" preset="subheading" />
<Image style={$welcomeFace} source={welcomeFace} resizeMode="contain" />
</View>
<View style={[$bottomContainer, $bottomContainerInsets]}>
<Text tx="welcomeScreen:postscript" size="md" />
<Button
testID="next-screen-button"
preset="reversed"
tx="welcomeScreen:letsGo"
onPress={goNext}
/>
</View>
</View>
)
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you will receive errors on any tx prop until you update the types in i18n.ts to
I never looked into this, but I was wondering why we kept types that were defined when using the previous library. I would've expected we'd be able to use types defined by the new library.
docs/recipes/MigratingToI18Next.md
Outdated
// error-line | ||
const locale = i18n.locale.split("-")[0] | ||
// success-line | ||
const locale = i18n.language.split("-")[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const locale = i18n.language.split("-")[0] | |
const locale = i18next.language.split("-")[0] |
also needs import of
import i18next from "i18next"
which would have been in place of import { i18n } from "app/i18n"
docs/recipes/MigratingToI18Next.md
Outdated
const initI18n = async () => { | ||
await i18n.use(initReactI18next).init({ | ||
resources, | ||
lng: pickSupportedLocale()?.languageTag || fallbackLocale, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pickSupportedLocale
and the helper that gets used for it via @lindboe's PR did not seem to make it in here
docs/recipes/MigratingToI18Next.md
Outdated
|
||
Finally, the steps outlined in this guide, are based on the changes outlined in the following two PRs: | ||
* [Swap out i18n-js for react-18next](https://github.com/infinitered/ignite/pull/2770) | ||
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2778) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2778) | |
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2788) |
docs/recipes/MigratingToI18Next.md
Outdated
For detailed code changes, including initialization updates, translation function updates, and testing, refer to the following PRs on the Ignite Github repo: | ||
|
||
* [Swap out i18n-js for react-18next](https://github.com/infinitered/ignite/pull/2770) | ||
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2778) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2778) | |
* [Fix language switching and update date-fns to v4](https://github.com/infinitered/ignite/pull/2788) |
Hello @frankcalise ! Based on my previous understanding, we wanted a guide to point out key places to update the i18n implementation. Your comments sound like we want the exact difference and changes compared to a fresh Ignite installation. We can go that way too! If we feel devs won't be updating the i18n Ignite implementation too much, then we might just as well provide the full detail. Let me know what do you think. |
Hey @frankcalise! Improved the PR based on your feedback. Please give it another peek. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Description
This PR adds a recipe to migrate from
i18n-js
toreact-i18next
library.Related PRs:
Open Source License Notice for Contributors
If you are contributing a recipe to this repository, you agree to license your contribution under the terms of the CC BY-SA 4.0 license.
If you have any questions, please reference the CONTRIBUTING.md or LICENSE.md file for more information.
Thank you for your contribution!