This script translates your language json to any language easily
Tags: ai, node, typescript, i18n
Published: 2023-03-11 15:54:56

> You can find the Github Repo on my original blog post here:
> https://jhayer.tech/blog/easily-translate-json-files

Lets dive into it, its not much so we can go through it step by step.
```js
async function mirrorObject(obj, targetLang) {
const mirroredObj = {};

for (const [key, value] of Object.entries(obj)) {
  if (typeof value === "object") {
    mirroredObj[key] = await mirrorObject(value, targetLang);
  } else {
    mirroredObj[key] = await translateService.translateText(
      value as string,
      targetLang
    );
  }
}

return mirroredObj;
}

```

This is our first function the `mirrorObject`. It has one simple job, to mirror the json object structure but instead of the original value we want the translated value.

This function is recursively iterating over the json object and translating each value. You see in line 6, if the value is a object we need to call our function again, otherwise we can use the translateService to translate the value. 

The translateService is simply using the node package from deepL to traslate the text, but we will have later a look at it.

```js
async function mirrorJsonFileWithTranslation(inputFilename, outputFilename, targetLang: string) {
  // Read the JSON file
  const fileData = fs.readFileSync(inputFilename)
  const jsonData = JSON.parse(fileData)

  // Create a mirrored object structure
  const mirroredData = await mirrorObject(jsonData, targetLang)

  // Write the mirrored data to a new file
  fs.writeFileSync(outputFilename, JSON.stringify(mirroredData, null, 2))

  console.log('Mirroring complete!')
}
```

Here we will have a look at the `mirrorJsonFileWithTranslation` function. This function is reading the json file (with the parameter inputFilename), calling our previously defined mirrorObject function with the desired target language and writes the result to a new json file (parameter outputFilename). What we need now is our entry function the main, to orchestrate the whole process :)

```js

(async () => {
const fileNames = ["common.json"];
const targetLangs = ["es", "fr"] as string[];
const fileName = fileNames[0];
for (const val in targetLangs) {
  const targetLang = targetLangs[val];
  console.log(
    `./locales/en/${fileName}.json`,
    `./locales/${targetLang}/${fileName}.json`
  );
  await mirrorJsonFileWithTranslation(
    `./locales/de/${fileName}.json`,
    `./locales/${targetLang}/${fileName}.json`,
    targetLang
  );
}
})();
```

Here we define fileNames as an array for the json files we want to translate. In the targetLangs array we define the languages we want to translate to. We are iterating over the targetLangs array and calling the `mirrorJsonFileWithTranslation` function. The main function is using the async/await syntax to wait for the translation to complete before starting the next translation.

What we need now is the translateService:

```js
import \* as deepl from "deepl-node";
import { TargetLanguageCode } from "deepl-node";
const fs = require("fs");

export interface Translation {
translateText: (
text: string,
targetLang: TargetLanguageCode
) => Promise<string>;
}
export class TranslateService implements Translation {
authKey = process.env.DEEPL_API_KEY ?? "YOUR_DEEPL_API_KEY"; // Replace with your key
translator: deepl.Translator;

constructor() {
this.translator = new deepl.Translator(this.authKey);
}

translateText = async (text: string, targetLang: string): Promise<string> => {
if (targetLang === "en") {
targetLang = "en-US";
}
const results = await this.translator.translateText(
text,
null,
targetLang as TargetLanguageCode
);
return results.text;
};
}

const translateService = new TranslateService();

export { translateService };
```

The translateService is using the deepl-node package to translate the text. We are using the environment variable `DEEPL_API_KEY` to store our deepl api key. If you don't have one you can get one for free here: https://www.deepl.com/pro#developer

To run the script just run: `npx ts-node translator.ts`

Now you can easily create multiple translations for your web application, maybe you can even automate the process with a github action or build an API to translate your web application on the fly ?