DEV Community

Cover image for Setting Up Localization in your React App
Sanjeev Sharma
Sanjeev Sharma

Posted on

Setting Up Localization in your React App

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.

Localization Demo

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.

React Localization - Translation files

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.

React Localization - constants

We have everything we need to set up our context.

React Localization - locale 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.

React Localization - custom hook

Now, the final piece of the puzzle is to use this context by wrapping our app with it.

React Localization - context provider

We can now refactor our app to use the locale strings. This is how App.js looks now.

React Localization - component

👍 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.

React Localization - country constants

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.

React Localization - context

To use the constant let's add one more string to our translation files.

React Localization - data strings

Finally, updating our component to use this string.

React Localization - using constants

💡 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.

React Localization - interpolate utility

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)

Collapse
 
brense profile image
Rense Bakker

Consider using the i18next react libary: react.i18next.com/

Collapse
 
thesanjeevsharma profile image
Sanjeev Sharma

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?

Collapse
 
seancassiere profile image
Sean Cassiere

For me, I'd personally use react-i18n because of the following:

  • Smaller bundle-size: As I wouldn't need to import all the translation files at build, and can load them as and when I need them. This is aside from Namespaces.
  • Fallbacks: Since, the JSON files are being loaded in directly into state, you aren't dealing with the use-case when a key is missing. Like if string.heading didn't exist in the ru.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 support: i18n's built-in Intl API is great for stuff like number formatting and additonal region specific localization.
Thread Thread
 
lwchkg profile image
WC Leung

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":

    case "CHANGE_LOCALE": {
      return {
        ...state,
        strings: Object.assign(
          {},
          LOCALE_STRINGS[REGIONS.EN],
          LOCALE_STRINGS[action.payload.region]
        ),
        constants: Object.assign(
          {},
          LOCALE_STRINGS[REGIONS.EN],
          COUNTRY_CONSTANTS[action.payload.region]
        ),
      };
    }
Enter fullscreen mode Exit fullscreen mode

For "smaller bundle size" the code depends on the packager used, so there's no point including the code here.

Collapse
 
brense profile image
Rense Bakker

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.

Collapse
 
noctap0d profile image
Victoria Rodriguez

Thanks for sharing! It's nice to see a solution that's not just "use x library" 🤣

Collapse
 
didier84 profile image
Didier Toussaint

Interesting article! If you found react-i18next hard, may I recommend LinguiJS (lingui.js.org/). It's clean, simple, and lightweight ✌️