Hey 👋
If your company(or product) is expanding into multiple geographies, Localization is one of the most important things you will be working on. The sooner you do it, the better! If you do the base setup in the initial stage it will make things easier as your codebase expands.
So, how do we do it? You'll have to spend few minutes reading this post. 😉 I'll also leave the codesandbox link in the end for you to reference later.
👉 To follow through you'll need basic understanding of React Context API.
We'll start by creating some translation files. For this demo, we'll support USA, Spain and Russia.
All the strings in our codebase will lie in these files.
Next, we need to setup a Locale context which will be consumed by our app tree. But first let's create a constants file which will store geography related data.
We have everything we need to set up our context.
On line 6, we define our initial state which is set to use English(USA).
On line 12, we create a reducer function which will modify the state.
On line 25, we create the provider which will wrap our app tree. I prefer using useReducer
in context, but the same could have been achieved by useState
.
Before we end our work on the context, it's good to create a custom hook to consume the context.
Now, the final piece of the puzzle is to use this context by wrapping our app with it.
We can now refactor our app to use the locale strings. This is how App.js
looks now.
👍 This finishes our setup. Now when we switch the region, action is dispatched from this component which updates the file we're referring for translations.
Additionally, we can store some data related to each geography and provide that through the context.
I've added phone codes for each geography but you can expand it to keep whatever data you need for example addresses, currencies, etc.
Now, we update context file to add a new key constants
.
To use the constant let's add one more string to our translation files.
Finally, updating our component to use this string.
💡 I've used this utility function name interpolate
which is quite useful when working with translations.
Notice how in the phone_text
translation strings, phoneCode
lies at different positions for different geographies. Also, not everything can be hard-coded in translations strings. Sometimes you want to show some user data inside these strings. That's exactly where interpolate
helps.
interpolate
looks for patterns we've set inside in our strings and replaces those with actual data.
We can further extend interpolate to apply different styles to different substrings.
That's it! This is how you set up localization.
🔗 Here's the codesandbox link: https://codesandbox.io/s/locale-context-qfgkdr
I hope this post was helpful. Follow for more!
🤝 Connect with me on LinkedIn or Twitter.
Cover image by Kalen Emsley.
Top comments (7)
Consider using the i18next react libary: react.i18next.com/
At my last job, we were using react i18n, but I found it hard. It could be because I didn't do the initial setup for it and I was still a beginner at react.
Anyway, my current job has a custom setup similar to what I have shared here(has much more helper methods and components). Do you see any potential problems with this? Or in what ways react i18n could be more useful that we are convinced to get rid of our custom implementation?
For me, I'd personally use react-i18n because of the following:
string.heading
didn't exist in theru.json
file, then the app would crash. This, is not the case with i18n where it'd simply pull-up the key from the main/primary json file.Intl API
is great for stuff like number formatting and additonal region specific localization.Speaking for Sanjeev: I believe that it is possible to have what you've said "smaller bundle-size" and "fallbacks" with some minor change in the code.
Here's my change for "fallbacks":
For "smaller bundle size" the code depends on the packager used, so there's no point including the code here.
In the short term no, but in the long term, react i18n offers a lot of additional features that are a lot of work to implement yourself. I highly recommend learning it, i18n skills also transfer to other frameworks as well and it will be easier to connect with external translation software that have an option to export to i18n format.
Thanks for sharing! It's nice to see a solution that's not just "use x library" 🤣
Interesting article! If you found react-i18next hard, may I recommend LinguiJS (lingui.js.org/). It's clean, simple, and lightweight ✌️