DEV Community

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)

Enter fullscreen mode Exit fullscreen mode

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]
}


Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

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

 <Translate>Hello</Translate>
Enter fullscreen mode Exit fullscreen mode

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

Discussion (8)

pic
Editor guide
Collapse
bernardbaker profile image
Bernard Baker

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

Collapse
reflexgravity profile image
Joel D Souza Author

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

Collapse
reflexgravity profile image
Joel D Souza Author

I have created and added a new hooks version above.

Collapse
bernardbaker profile image
Bernard Baker

Apologies, I was thinking of custom hooks.

Thread Thread
reflexgravity profile image
Joel D Souza Author

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

Thread Thread
bernardbaker profile image
Collapse
clintz9 profile image
Clinton Dsouza

Good write up Joel !

Collapse
reflexgravity profile image
Joel D Souza Author

Thanks man. Really appreciate it.