Multilingualism in applications
Tags: translations, languages, react
Published: 2019-04-16 06:59:47

---
title: Multilingualism in applications
published: true
description: Handling translations in React using Littera
tags: translations, languages, react
---
![Thumbnail](https://thepracticaldev.s3.amazonaws.com/i/mczo17hjst5hhiw5silz.jpeg)

---

Hello, Guten Tag, Dzień dobry, Bonjour, Salve, السَّلَامُ عَلَيْكُمْ!

About a year ago we needed some kind of translation management system for our project at work. We've built a very simple internal library, which fed with an object containing translations, spit with translated text.

All the translations were stored in a JSON file and then we moved to YAML - which actually is converted to JSON at build anyway so JavaScript can correctly interpret it.

The YAML file looks like below.
```yaml
unique.yes:
   de_DE: Ja
   en_US: Yes
   pl_PL: Tak
unique.no:
   de_DE: Nein
   en_US: No
   pl_PL: Nie
unique.example:
   de_DE: Beispiel
   en_US: Example
   pl_PL: Przykład
```
Everything is working just fine.. except that we now have a file of around 10 000 lines of translations, which are horribly hard to maintain and the fact that the application is still in development made me worry.

We've been trying to refactor the translations, built tools, which helped sorting but it didn't do much, there is still chaos in our translations.

One day while using JSS, I've came up with an idea to implement translations like it's done with styles in JSS and…

✨ tada ✨

**Littera** was borned!

---

# Introduction
Littera (/ˈlit.te.ra/) is a very simple mechanism which takes an object with keys representing a language and values representing a specific string in that language and returns only the string for the active language. For instance, you take the sentence "This is an example" which will be the value for "en_US" key and you repeat the same for each language.
```json
{
    "en_US": "This is an example",
    "de_DE": "Das ist ein Beispiel",
    "pl_PL": "To przykład"
}
```

# Setup
Now that we know how the core concept works, we can setup Littera. To make use of the library, you have to wrap your components with a context and provide the active language. For this we will use the LitteraProvider. You can pass it 3 props:

- language    - the active language (string)
- preset      - set of global translations (object)
- setLanguage - function to change the active language programically (function)

We will use create-react-app as an example. Remember to install Littera using npm or yarn before you jump into the code.

`npm install react-littera`
`yarn add react-littera`

Let's go, import the provider in App.js file wrapping all your components like shown below.
```jsx
import React, { useState } from "react";
import ReactDOM from "react-dom";

import LitteraProvider from "react-littera";
function App() {
  const [language, setLanguage] = useState("en_US");

  return (
    <div className="App">
      <LitteraProvider language={language} setLanguage={setLanguage}>
        <YourComponents />
      </LitteraProvider>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```
And that's it, Littera is ready to be used in your components.

I would suggest, you use Redux to handle the active language state.

# Usage
Now let's create an example component to showcase the power of Littera. Our component gonna be a button, which clicked will switch the language.

First we create a basic functional component returning a button.
```jsx
import React from 'react';

const SuperButton = () => {
    return <button>Example</button>;
}

export default SuperButton;
```
Now we have to import the useLittera hook, declare an object with our translations and make use of the hook.
```jsx
import React from 'react';
import { useLittera } from 'react-littera';

const translations = {
    example: {
        en_US: "Example",
        de_DE: "Beispiel",
        pl_PL: "Przykład"
    }
};

const SuperButton = () => {
     const [translated, language, setLanguage] = useLittera(translations);

     const switchLanguage = () => setLanguage("de_DE");

     return <button onClick={switchLanguage}>{translated.example}</button>;
}

export default SuperButton;
```

### Global translations
As mentioned above, we can pass a preset to LitteraProvider. It can be used the same way JSS handles it's theming. Simply make a function out of the translations constant with the preset attribute and returning an object, then use the attribute to reuse the existing preset.
```javascript
const translations = preset => ({
    example: {
        en_US: `This is an ${preset.example}`,
        de_DE: `Das ist ein ${preset.example}`,
        pl_PL: `To ${preset.example}`
    }
});
```

### Hook or HOC?
Littera supports hooks and HOCs. Both can be used with the same context but let's be real, class components are pretty much extinct. 😅

Anyway an example of both can be found on CodeSandbox.

HOC: https://codesandbox.io/s/6299pk9r1r
Hook: https://codesandbox.io/s/ywl2lm8r4z

# Conclusion
There are probably better methods to manage translations in large applications but Littera will fill your needs if you're building an one-pager. If you want to reach a greater audience, give Littera a try. 💖

You can fork the source code on GitHub and maybe we will squash few bugs together! 
https://github.com/DRFR0ST/react-littera