How to translate AXIOS responses using Amazon Translate or Google Translate in React?

310 views Asked by At

I am trying to convert Axios JSON responses in React i.e

axios.get('https://jsonplaceholder.typicode.com/users')
            .then(res => {
                ...translation_logic_here
                setUsers(translatedJson)
             })

I am trying to translate all values(even if it is nested), to a target language.

I see both in Amazon and Google, they provide text translation API's, where we have to send HTTP request for each value in JSON..lets say if 100 values, 100 http requests which takes more time... A gist on the code and a screenshot is provided below(134 requests in screenshot!!!)

var params = {
                    Text: res.data[0].company.catchPhrase,
                    SourceLanguageCode: "auto",
                    TargetLanguageCode: 'ru',
                };

translate.translateText(params, function(err, data) {
           ...after_translation_logic
}

enter image description here

I tried https://www.npmjs.com/package/react-google-translate and official Javascript SDK AWS SDK both has this same approach.

AFAIK, even google provides text translation API's in same approach which can't be used for web applications.

Lastly, i came across this solution googleTranslateElementInit which works like a charm... but we require Amazon Custom Terminology or Google Glossary feature for custom translation.

Will googleTranslateElementInit still be supported in future? If so how can i integrate Google Glossary in googleTranslateElementInit? or any ways in Amazon Translate without multiple http requests?

Can anyone please support me on how to proceed? Any help is much appreciated...Thanks.

1

There are 1 answers

0
Richard Tyler Miles On

I'm searching more about this process myself; the major caveat with what I've written below is the private key exchange. While @aws-sdk/client-translate says in the description "AWS SDK for JavaScript Translate Client for Node.js, Browser and React Native." I don't think translating everything on the front end is the best idea due to possible bad actors. A more backend-heavy approach may be needed.

import { TranslateClient, TranslateTextCommand } from "@aws-sdk/client-translate";
import {useEffect, useState} from "react";
import Bootstrap from "src/Bootstrap";

// @link https://stackoverflow.com/questions/69734293/aws-sdk-js-for-translate-client-results-an-error-cannot-read-property-byteleng/69879101#69879101
const client = new TranslateClient({
    region: "us-east-1",
    credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
    }
});


interface iTranslateText {
    original: string,
    translated: string
}

let cache : iTranslateText[] = []

const buildLanguage = "en";

export default function translateText({children = "StackOverflow is very good."}: {
    children: string
}) {

    const {translateToLanguage} = Bootstrap.bootstrap.state
    const [translation, setTranslation] = useState<string>(children)


    useEffect(() => {

        if (buildLanguage === translateToLanguage.code) {

            if (translation !== children) {

                setTranslation(children)

            }

            return;

        }

        (async () => {

            // @link https://docs.aws.amazon.com/translate/latest/dg/what-is-languages.html
            const command = new TranslateTextCommand({
                Text: children,
                SourceLanguageCode: buildLanguage,
                TargetLanguageCode: translateToLanguage.code
            })

            const data = await client.send(command);

            cache.push({
                original: children,
                translated: data.TranslatedText
            })

            setTranslation(data.TranslatedText)

        })()

    }, [translateToLanguage])

    const cacheResult = cache.find(results => results.original === children)

    if (undefined !== cacheResult) {

        return cacheResult.translated

    }

    return translation

}

We've decided to use the approach above to help generate a static 1->1 mapping which produces a local cache generated in localhost. We remove the env private key for production as its unneeded when the local cache fills.