loading...

Building an i18n translator using React

reflexgravity profile image Joel D Souza Updated on ・2 min read

It's so obvious that websites need to be internationalized. But creating multiple versions of the same website is not the best answer to it. Using React we can completely globalize our application. I'm going to show you how it can be done.

This application includes:

Translate Engine

It does nothing but gets a word and returns the translated word based on the language selected. You need to pass the selected language and a word to this component. The children for the Translate component should only be a string. I have used Redux below, but you can use local state or Context API to set the language.

import React, { PureComponent } from "react"
import { connect } from "react-redux"

// The function which returns you translated words based on a language.
import Dictionary from "./dictionary"

class Translate extends PureComponent {

    translateWord(word) {
        try {
            const { lang } = this.props
            // lang = "es"
            const languageDb = Dictionary(lang)

            if (word in languageDb.words) {
                return languageDb.words[word]
            }

            return word

        } catch (err) {
            console.error('Error while translating::translateWord', err)

            // If something goes wrong return the word as it is.
            return word
        }
    }

    render() {
        let { children, lang } = this.props

        if (typeof children === "string" && lang !== "en") {
           // pass the lowerCased word to get in the translated form.
           return this.translateWord(children.toLowerCase())
        }

        return <>{children}</>
    }
}

const mapStateToProps = (state) => {
    return {
        lang: state.lang,
    }
}

export default connect(mapStateToProps, null)(Translate)

Dictionary

This can be an object/function that returns a list of all the available translated words based on a language. You'll have to feed a JSON object (as shown below) that lists all the translated words.


import es from "./es.json"
import ru from "./ru.json"
import de from "./de.json"

const languages = {
    es,
    ru,
    de,    
}

export default function(lang) {

    return languages[lang]
}


This is how my spanish DB (es.json) looks like:

{
   "lang":"es",
   "words" : {
      "search"        : "registrar",
      "conversation"  : "conversación"
   }
}

You can use the translate component as shown below, But remember its children can only be a string.

 <Translate>Hello</Translate>

I have created a simple sandbox for you to understand better practically. I have also created a hooks version below as suggested in comments.

The hooks version:

This is my first post/blog I have ever written and published. I thought of giving it a try during the pandemic lockdown. Let me know for suggestions on how to improve the content.

Happy coding!
Stay Inside and Stay Safe

Posted on by:

reflexgravity profile

Joel D Souza

@reflexgravity

Building reactjs apps at Kapture CRM. he/him. Writing bugs and then fixing them.

Discussion

pic
Editor guide
 

I like the idea. It's handy. Would you consider updating it to React hooks?

 

Yeah, sure. I can create a new sandbox with the hooks version.

 

I have created and added a new hooks version above.

 

Apologies, I was thinking of custom hooks.

Interesting... you want me to create a hook that returns the translated word?

 

Good write up Joel !

 

Thanks man. Really appreciate it.