• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

Rapid Blog

  • Enterprise
  • API Hub
  • Add Your API
  • About
  • Docs
    • API Glossary
  • Blog
    • What is an API?
    • REST API Tutorials
    • Most Popular APIs
  • Sign Up
    • Log In
Blog » API Tutorials » JavaScript API Tutorials » Microsoft Text Translation API JavaScript Example
translation blog with article and commenting functionality

Build a Translation App with the Microsoft Text Translation API [JavaScript Tutorial]

By Team RapidAPI // September 14, 2020

Introduction

Translation capabilities are commonplace on the web. There are browser add-ons and plenty of translation APIs available. With a global web and marketplace, it’s important to have the ability for users to receive information in their preferred language.

The popular choice is using Google Translate to translate webpage components. However, there are many other interesting APIs available that utilize machine learning and other powerful programming techniques. One of these other translation APIs that I want to explore today is Microsoft Text Translation.

In addition to normal translation capabilities, this API offers a text-to-speech translation endpoint that returns an audio file of the submitted text. That means that the translated text is read back to the user by a Native speaker of the supported language. It’s not a typical feature that I have seen on the web and can be set up quite easily.

To showcase how to set-up the translation capability I have put together an example app that we are going to add the API calls and translation to. We will be combining the powerful features of ReactJS and RapidAPI to achieve the desired result.

Connect to the Microsoft Text Translation API

New to RapidAPI?

If this is your first time using RapidAPI, you will need to sign up for an account. In addition, you will need to subscribe to the API. Fortunately, I will cover subscribing to the API and using the dashboard in the Prerequisites section and further down in the example app section below.

How to use the Microsoft Text Translation API with JavaScript

How To Add Native Speaking Audio Translations For 80 Different Languages To Your App

final app page with comment and audio translation

View the final project code on Github

I created a starter project hosted on Github that has the initial repository that we will download when we start the example. This repository was created with Create-React-App (CRA). I added CSS styling, removed some of the original components, and set up basic commenting functionality. The main page is a snippet from a different RapidAPI article on Javascript translation. The starter project allows a user to add comments below the post content.

Unfortunately, the comments are only held in the state, so they will not persist if the page is refreshed.

We will add translation capabilities to each comment, so every individual comment can be translated.

Connect to the Microsoft Text Translation API

Prerequisites

There are a few skills and tools that will help you complete this project:

  • Familiarity with the command-line and Git (using basic commands)
  • Installation of Node >= 8.10
  • Understanding of how ReactJS works (props, components, functions, hooks). I will explain some aspects as we go through the tutorial.
  • An internet connection.
  • A reputable code editor (I will be using Visual Studio Code)
  • A free RapidAPI account
  • A Subscription to the Microsoft Text Translation API on RapidAPI

manage and view usage

Above is the basic subscription box if you followed the link above. The basic plan allows 2500 requests a month. Notice that the link to ‘Manage and View Usage’. This is done in the RapidAPI dashboard.

IMPORTANT: This is NOT Microsoft Text Translation 3.0. Make sure the API name does not have 3.0 at the end of the title.

Let’s start!

1. Clone the Starting Repository From Github

Navigate to good directory in your terminal and execute git clone https://github.com/jdretz/rapidapi-microsoft-translation-example-starter.git

Next, change directories into the folder with cd rapidapi-microsoft-translation-example-starter/. Install the dependencies by running npm install in the root of the project. The installation may take a few minutes because the project uses CRA.

Finally, start the app by running npm start. The app starts on http://localhost:3000. You should see our example blog article once you navigate there.

translation blog with article and commenting functionality

Feel free to test out the commenting to get a feel for adding and deleting comments. If a name is not provided to the form then the ID is used.

Connect to the Microsoft Text Translation API

Project Structure

React apps start at index.js where the application is attached to the DOM. Furthermore, we import the component <App /> into this file and rendering it to the page. The App component lives in App.js and is where all of our other components and data are rendered from.

Our homepage (the article) and main title are in App.js. In addition, we use the popular libraries Bootstrap and React-Bootstrap to style the app.

All of the components have a corresponding CSS file. App.css and index.css contain styles that are applied anywhere in the app. In contrast, all the other component files (i.e CommentSection.js AddComment.js) have modular CSS styles. Modular CSS files end in module.css and are imported at the top of the page (usually as classes) in their partner js file.

We will add the translation capability to our commenting components in the components directory and therefore spending most of our time in those files.

2. Explore the Microsoft Text Translation API

Take a look at the endpoints in the API dashboard.

rapidapi dashboard. Highlights translate, speak, and get supported speak languages endpoints.

I highlighted the three endpoints that we need on the left side of the image. RapidAPI can generate code snippets for us when we select different languages/libraries.

Let’s use Javascript and the fetch API to make our API calls.

Finally, in the bottom right we can preview what the response will look like. Oh no! It’s XML! No problem, we will build a function for parsing the response and extracting the data we need. Two endpoints will return XML and the other, Speak, will return binary data (application/octet-string) which we will need to read and save to a local URL.

The Speak endpoint returns the submitted text spoken by someone in the target language. For example, submitting the text ‘Hello’ with Spanish as the target language returns audio with the voice of someone with a Spanish accent speaking English. In other words, the Speak endpoint does not translate the text for us. We need to do that first.

The individual comment’s text is sent to the Translate endpoint first. Then, the translated text is submitted to the Speak endpoint.

The final endpoint, Get Speak Supported Languages, is self-explanatory. However, the endpoint only returns a list of languages that are supported by the Speak endpoint. The returned languages are in their ISO 639-1 Code equivalent. These codes will be displayed as translation options for the languages.

Connect to the Microsoft Text Translation API

3. Add API Calls

All three API calls are written in the same file. The functions are attached to the object exported from the file. The file has a helper code block at the top that determines how to parse the XML. Browsers have support for parsing XML, but the code block determines what options are available at runtime.

Create the file api.js in the src directory. Add the helper function code block the top of a new file.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let parseXml;
// create xml parsing functions
// the next if/else block is from the following thread
// https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript
if (typeof window.DOMParser != "undefined") {
parseXml = function(content) {
return ( new window.DOMParser() ).parseFromString(content, "text/xml");
};
} else if (typeof window.ActiveXObject != "undefined" &&
new window.ActiveXObject("Microsoft.XMLDOM")) {
parseXml = function(content) {
let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(content);
return xmlDoc;
};
} else {
throw new Error("No XML parser found");
}
let parseXml; // create xml parsing functions // the next if/else block is from the following thread // https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript if (typeof window.DOMParser != "undefined") { parseXml = function(content) { return ( new window.DOMParser() ).parseFromString(content, "text/xml"); }; } else if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("Microsoft.XMLDOM")) { parseXml = function(content) { let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = "false"; xmlDoc.loadXML(content); return xmlDoc; }; } else { throw new Error("No XML parser found"); }
let parseXml;
// create xml parsing functions
// the next if/else block is from the following thread
// https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript
if (typeof window.DOMParser != "undefined") {
    parseXml = function(content) {
        return ( new window.DOMParser() ).parseFromString(content, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
        new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(content) {
        let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(content);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

Essentially, the above code block gives us a function, parseXML, that accepts XML text from an XML response and returns a document that we can parse.

Next, let’s add the object to export that has the three API calls below the parse code block. I’ve added comments to explain what is happens in each function.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
export default {
Translate: {
// Speak endpoints. Returns the url of the local audio file
textToSpeech: (encoded, target) => {
return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.blob())
.then(blob => {
return URL.createObjectURL(blob);
})
},
// Get Speak Language Options endpoint. Returns a list of strings
getSpeakLanguages: () => {
return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.text()) // convert response to text
.then(text => {
// creates XML document
let document = parseXml(text)
// creates array from HTMLCollection object
let stringElementArray = Array.from(document.getElementsByTagName('string'))
// extracts innerHTML value from string tag object
let languages = stringElementArray.map(string => string.innerHTML)
return languages
})
},
// Translate endpoint. Returns the translated text as a string
translateToText: (encoded, target) => {
return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.text())
.then(text => {
let document = parseXml(text)
let stringElementArray = document.getElementsByTagName('string')
return stringElementArray[0].innerHTML
})
.catch(err => {
console.log(err);
});
}
}
}
... export default { Translate: { // Speak endpoints. Returns the url of the local audio file textToSpeech: (encoded, target) => { return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.blob()) .then(blob => { return URL.createObjectURL(blob); }) }, // Get Speak Language Options endpoint. Returns a list of strings getSpeakLanguages: () => { return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.text()) // convert response to text .then(text => { // creates XML document let document = parseXml(text) // creates array from HTMLCollection object let stringElementArray = Array.from(document.getElementsByTagName('string')) // extracts innerHTML value from string tag object let languages = stringElementArray.map(string => string.innerHTML) return languages }) }, // Translate endpoint. Returns the translated text as a string translateToText: (encoded, target) => { return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.text()) .then(text => { let document = parseXml(text) let stringElementArray = document.getElementsByTagName('string') return stringElementArray[0].innerHTML }) .catch(err => { console.log(err); }); } } }
...
export default {
    Translate: {
        // Speak endpoints. Returns the url of the local audio file
        textToSpeech: (encoded, target) => {
            return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.blob())
            .then(blob => {
                return URL.createObjectURL(blob);
            })
        },
        // Get Speak Language Options endpoint. Returns a list of strings
        getSpeakLanguages: () => {
            return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.text()) // convert response to text
            .then(text => {
                // creates XML document
                let document = parseXml(text)

                // creates array from HTMLCollection object
                let stringElementArray = Array.from(document.getElementsByTagName('string'))

                // extracts innerHTML value from string tag object
                let languages = stringElementArray.map(string => string.innerHTML)
                return languages
            })
        },
        // Translate endpoint. Returns the translated text as a string
        translateToText: (encoded, target) => {
            return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.text())
            .then(text => {
                let document = parseXml(text)
                let stringElementArray = document.getElementsByTagName('string')
                return stringElementArray[0].innerHTML
            })
            .catch(err => {
                console.log(err);
            });
        }
    }
}

The functions are basically pulled straight from the RapidAPI dashboard (pictured above). To use the functions import the object, import api from 'path/to/api/file', then access the functions on the Translate object. For example, api.Translate.translateToText(encoded, target).

The functions are almost ready. There is a variable used in the functions that are not defined: rapidAPIHeaders. This object is repeated in all the functions because the RapidAPI headers are sent in each request, so let’s pull it out and add it as a variable to the top of the file.

The final api.js will be:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let rapidAPIHeaders = {
"x-rapidapi-host": "microsoft-azure-translation-v1.p.rapidapi.com",
"x-rapidapi-key": process.env.REACT_APP_RAPIDAPI_KEY
}
let parseXml;
// create xml parsing functions
// the next if/else block is from the following thread
// https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript
if (typeof window.DOMParser != "undefined") {
parseXml = function(content) {
return ( new window.DOMParser() ).parseFromString(content, "text/xml");
};
} else if (typeof window.ActiveXObject != "undefined" &&
new window.ActiveXObject("Microsoft.XMLDOM")) {
parseXml = function(content) {
let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(content);
return xmlDoc;
};
} else {
throw new Error("No XML parser found");
}
export default {
Translate: {
textToSpeech: (encoded, target) => {
return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.blob())
.then(blob => {
return URL.createObjectURL(blob);
})
},
getSpeakLanguages: () => {
return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.text())
.then(text => {
// creates XML document
let document = parseXml(text)
// creates array from HTMLCollection object
let stringElementArray = Array.from(document.getElementsByTagName('string'))
// extracts innerHTML value from string tag object
let languages = stringElementArray.map(string => string.innerHTML)
return languages
})
},
translateToText: (encoded, target) => {
return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, {
"method": "GET",
"headers": rapidAPIHeaders
})
.then(response => response.text())
.then(text => {
let document = parseXml(text)
let stringElementArray = document.getElementsByTagName('string')
return stringElementArray[0].innerHTML
})
.catch(err => {
console.log(err);
});
}
}
}
let rapidAPIHeaders = { "x-rapidapi-host": "microsoft-azure-translation-v1.p.rapidapi.com", "x-rapidapi-key": process.env.REACT_APP_RAPIDAPI_KEY } let parseXml; // create xml parsing functions // the next if/else block is from the following thread // https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript if (typeof window.DOMParser != "undefined") { parseXml = function(content) { return ( new window.DOMParser() ).parseFromString(content, "text/xml"); }; } else if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("Microsoft.XMLDOM")) { parseXml = function(content) { let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = "false"; xmlDoc.loadXML(content); return xmlDoc; }; } else { throw new Error("No XML parser found"); } export default { Translate: { textToSpeech: (encoded, target) => { return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.blob()) .then(blob => { return URL.createObjectURL(blob); }) }, getSpeakLanguages: () => { return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.text()) .then(text => { // creates XML document let document = parseXml(text) // creates array from HTMLCollection object let stringElementArray = Array.from(document.getElementsByTagName('string')) // extracts innerHTML value from string tag object let languages = stringElementArray.map(string => string.innerHTML) return languages }) }, translateToText: (encoded, target) => { return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, { "method": "GET", "headers": rapidAPIHeaders }) .then(response => response.text()) .then(text => { let document = parseXml(text) let stringElementArray = document.getElementsByTagName('string') return stringElementArray[0].innerHTML }) .catch(err => { console.log(err); }); } } }
let rapidAPIHeaders = {
    "x-rapidapi-host": "microsoft-azure-translation-v1.p.rapidapi.com",
    "x-rapidapi-key": process.env.REACT_APP_RAPIDAPI_KEY
}

let parseXml;
// create xml parsing functions
// the next if/else block is from the following thread
// https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript
if (typeof window.DOMParser != "undefined") {
    parseXml = function(content) {
        return ( new window.DOMParser() ).parseFromString(content, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
        new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(content) {
        let xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(content);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

export default {
    Translate: {
        textToSpeech: (encoded, target) => {
            return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/Speak?text=${encoded}&language=${target}`, {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.blob())
            .then(blob => {
                return URL.createObjectURL(blob);
            })
        },
        getSpeakLanguages: () => {
            return fetch("https://microsoft-azure-translation-v1.p.rapidapi.com/GetLanguagesForSpeak", {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.text())
            .then(text => {
                // creates XML document
                let document = parseXml(text)

                // creates array from HTMLCollection object
                let stringElementArray = Array.from(document.getElementsByTagName('string'))

                // extracts innerHTML value from string tag object
                let languages = stringElementArray.map(string => string.innerHTML)
                return languages
            })
        },
        translateToText: (encoded, target) => {
            return fetch(`https://microsoft-azure-translation-v1.p.rapidapi.com/translate?from=en&to=${target}&text=${encoded}`, {
                "method": "GET",
                "headers": rapidAPIHeaders
            })
            .then(response => response.text())
            .then(text => {
                let document = parseXml(text)
                let stringElementArray = document.getElementsByTagName('string')
                return stringElementArray[0].innerHTML
            })
            .catch(err => {
                console.log(err);
            });
        }
    }
}

Connect to the Microsoft Text Translation API

Environment Variables

We need to keep our RapidAPI key safe. In order to do that we can pull the value from process.env, which is an object available at runtime. This keeps us from publishing our API to Github where other people could use or abuse it.

Add the API key to process.env by creating the file .env in the project root. It should be on the same level as your package.json file. The contents of the file are REACT_APP_RAPIDAPI_KEY=yourrapidapikey.

Two additional points to add:

  1. Environmental variables in CRA need to start with ‘REACT_APP_’
  2. This file needs to be in our .gitignore file so it’s not added if we were to push the code to Github.

In .gitignore, add .env to the bottom.

4. Add Language Options

First, let’s add the language options. The data returned in this endpoint doesn’t change while using the app, will only need to be fetched once, and is used by every comment.

Therefore, it makes sense that the data is fetched in a component higher up the ‘tree’ and passed down the individual Comment components as props.

In App.js, where it says ‘get speak language options here’ add the code below.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
useEffect(() => {
api.Translate.getSpeakLanguages()
.then(response => setLanguageOptions(response))
.catch(e => console.log(e))
}, [])
useEffect(() => { api.Translate.getSpeakLanguages() .then(response => setLanguageOptions(response)) .catch(e => console.log(e)) }, [])
useEffect(() => {
    api.Translate.getSpeakLanguages()
      .then(response => setLanguageOptions(response))
      .catch(e => console.log(e))
  }, [])

This is a React hook that is called once when the page is loads. It calls our function and sets the value to the setLanguageOptions variable. However, none of the functions used above exist in our file yet.

Import { useEffect, useState }  at the top of the file, as well as our API object.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useState, useEffect } from 'react';
import { Container, Row, Col } from 'react-bootstrap'
import CommentSection from './components/CommentSection/CommentSection'
import api from './api'
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import React, { useState, useEffect } from 'react'; import { Container, Row, Col } from 'react-bootstrap' import CommentSection from './components/CommentSection/CommentSection' import api from './api' import './App.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import React, { useState, useEffect } from 'react';
import { Container, Row, Col } from 'react-bootstrap'
import CommentSection from './components/CommentSection/CommentSection'
import api from './api'

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

Next, create the languageOptions variable above our call to useEffect.

let [languageOptions, setLanguageOptions] = useState([])

Finally, pass the languageOptions variable as a prop to the <CommentSection /> component.

The final code for App.js will be:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useState, useEffect } from 'react' // MODIFIED import hooks
import { Container, Row, Col } from 'react-bootstrap'
import CommentSection from './components/CommentSection/CommentSection'
import api from './api' // NEW import functions
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
function App() {
let [languageOptions, setLanguageOptions] = useState([]) // NEW create state variable
// get speak language options here
useEffect(() => { // NEW function
api.Translate.getSpeakLanguages()
.then(response => setLanguageOptions(response))
.catch(e => console.log(e))
}, [])
return (
<div className="App">
<header className="App-header display-2 bg-light mb-4">
Translation Blog
</header>
<main>
<h1 className="m-4 p-3 text-center bg-light"><a className="heading-link" href="https://rapidapi.com/blog/google-translate-api-tutorial/">How To Build Support for Language Translating In Web Forms (Google Translate API Tutorial) [JavaScript]</a></h1>
<article>
<Container fluid>
<Row className="justify-content-center">
<Col md="8">
<p>We are back with yet another <a href="https://rapidapi.com/blog/category/tutorial/">tutorial</a> on Google Translate API. This time we are going to address the language personalization feature on the web with this API.</p>
<p>As a non-native English speaker, if you come across a web form in English that you want to fill out and submit, it can be difficult to interpret the meaning of each form field. Using the Google Translate API, we can build language personalization features for web forms so that you can choose the language while filling out the form.</p>
<p>If this sounds interesting, then follow along this blog post to build a demo web form with language translation capability, powered by RapidAPI. But first, a very brief introduction to Google Translate API.</p>
--- Read More ---
<CommentSection languages={languageOptions} /> // NEW: pass in language options
</Col>
</Row>
</Container>
</article>
</main>
</div>
);
}
export default App;
import React, { useState, useEffect } from 'react' // MODIFIED import hooks import { Container, Row, Col } from 'react-bootstrap' import CommentSection from './components/CommentSection/CommentSection' import api from './api' // NEW import functions import './App.css'; import 'bootstrap/dist/css/bootstrap.min.css'; function App() { let [languageOptions, setLanguageOptions] = useState([]) // NEW create state variable // get speak language options here useEffect(() => { // NEW function api.Translate.getSpeakLanguages() .then(response => setLanguageOptions(response)) .catch(e => console.log(e)) }, []) return ( <div className="App"> <header className="App-header display-2 bg-light mb-4"> Translation Blog </header> <main> <h1 className="m-4 p-3 text-center bg-light"><a className="heading-link" href="https://rapidapi.com/blog/google-translate-api-tutorial/">How To Build Support for Language Translating In Web Forms (Google Translate API Tutorial) [JavaScript]</a></h1> <article> <Container fluid> <Row className="justify-content-center"> <Col md="8"> <p>We are back with yet another <a href="https://rapidapi.com/blog/category/tutorial/">tutorial</a> on Google Translate API. This time we are going to address the language personalization feature on the web with this API.</p> <p>As a non-native English speaker, if you come across a web form in English that you want to fill out and submit, it can be difficult to interpret the meaning of each form field. Using the Google Translate API, we can build language personalization features for web forms so that you can choose the language while filling out the form.</p> <p>If this sounds interesting, then follow along this blog post to build a demo web form with language translation capability, powered by RapidAPI. But first, a very brief introduction to Google Translate API.</p> --- Read More --- <CommentSection languages={languageOptions} /> // NEW: pass in language options </Col> </Row> </Container> </article> </main> </div> ); } export default App;
import React, { useState, useEffect } from 'react'              // MODIFIED import hooks
import { Container, Row, Col } from 'react-bootstrap'
import CommentSection from './components/CommentSection/CommentSection'
import api from './api'                               // NEW import functions

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  let [languageOptions, setLanguageOptions] = useState([])  // NEW create state variable

  // get speak language options here
  useEffect(() => {                             // NEW function
    api.Translate.getSpeakLanguages()
      .then(response => setLanguageOptions(response))
      .catch(e => console.log(e))
  }, [])

  return (
    <div className="App">
      <header className="App-header display-2 bg-light mb-4">
        Translation Blog
      </header>
      <main>
        <h1 className="m-4 p-3 text-center bg-light"><a className="heading-link" href="https://rapidapi.com/blog/google-translate-api-tutorial/">How To Build Support for Language Translating In Web Forms (Google Translate API Tutorial) [JavaScript]</a></h1>
        <article>
          <Container fluid>
            <Row className="justify-content-center">
              <Col md="8">
                <p>We are back with yet another <a href="https://rapidapi.com/blog/category/tutorial/">tutorial</a> on Google Translate API. This time we are going to address the language personalization feature on the web with this API.</p>

                <p>As a non-native English speaker, if you come across a web form in English that you want to fill out and submit, it can be difficult to interpret the meaning of each form field. Using the Google Translate API, we can build language personalization features for web forms so that you can choose the language while filling out the form.</p>

                <p>If this sounds interesting, then follow along this blog post to build a demo web form with language translation capability, powered by RapidAPI. But first, a very brief introduction to Google Translate API.</p>
                --- Read More ---
                <CommentSection languages={languageOptions} />   // NEW: pass in language options
              </Col>
            </Row>
          </Container>
        </article>
      </main>
    </div>
  );
}

export default App;

The language options are passed to the <CommentSection /> component, but their final home is in the <Comment /> component. Therefore, in CommentSection.js pass the props another level down into the <Comment /> component.

Line 29 in CommentSection.js should be:

return <Comment languages={props.languages} key={comment.owner_id} delete={deleteComment} comment={comment} />
Notice, the only thing added is languages={props.languages}.
Finally, in Comment.js add the select dropdown input and the state variable that holds the selected language option.
For this to work we need to:
  • install react-select for the project (if you cloned the repo it already was)
  • import useState at the top of the file again
  • add the variable, target, to the component’s state.

Comment.js becomes;

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useState } from 'react'
import classes from './Comment.module.css'
import Select from 'react-select'
const Comment =(props) => {
let [target, setTarget] = useState({value: 'en'})
// add translate function here
return (
<div className={classes.Comment}>
<button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button>
<p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p>
<p>{props.comment.comment}</p>
{/* add translation functionality here */}
<div className={classes.TranslateContainer}>
{props.languages &&
<div>
<label htmlFor="languages"><small>Select Language</small></label>
<Select
className={classes.Select}
value={target}
name="languages"
onChange={(selectedOption) => setTarget(selectedOption)}
options={props.languages.map(lang => { return { value: lang, label: lang } })}
/>
</div>}
</div>
</div>
)
}
export default Comment
import React, { useState } from 'react' import classes from './Comment.module.css' import Select from 'react-select' const Comment =(props) => { let [target, setTarget] = useState({value: 'en'}) // add translate function here return ( <div className={classes.Comment}> <button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button> <p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p> <p>{props.comment.comment}</p> {/* add translation functionality here */} <div className={classes.TranslateContainer}> {props.languages && <div> <label htmlFor="languages"><small>Select Language</small></label> <Select className={classes.Select} value={target} name="languages" onChange={(selectedOption) => setTarget(selectedOption)} options={props.languages.map(lang => { return { value: lang, label: lang } })} /> </div>} </div> </div> ) } export default Comment
import React, { useState } from 'react'
import classes from './Comment.module.css'
import Select from 'react-select'

const Comment =(props) => {
    let [target, setTarget] = useState({value: 'en'})
    // add translate function here

    return (
        <div className={classes.Comment}>
            <button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button>
            <p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p>
            <p>{props.comment.comment}</p>
            {/* add translation functionality here */}
            <div className={classes.TranslateContainer}>
                {props.languages && 
                    <div>
                        <label htmlFor="languages"><small>Select Language</small></label>
                        <Select
                            className={classes.Select}
                            value={target}
                            name="languages"
                            onChange={(selectedOption) => setTarget(selectedOption)}
                            options={props.languages.map(lang => { return { value: lang, label: lang } })}
                            />
                    </div>}
                </div>
        </div>
    )
}

export default Comment

After leaving a comment, there is now a dropdown option to select the language.

drop with available language options in the comment box

Connect to the Microsoft Text Translation API

5. Add Translate Function

For the translation function to work we need it to;

  1. Encode the comment text so the special characters can be sent in the request URL
  2. translate the text into the target language
  3. Encode the translated language text
  4. Retrieve the speech recording for the translated phrase
  5. Set the URL to a variable in state

With HTML5 we can use the <audio> tag to create a decent experience for users to play, playback, download, or increase the volume of .wav or .mp3 files.

The <source> tag expects the local URL returned by textToSpech, and later stored, in a state variable.

The final code for the file uses conditional logic to render components if the data is available. For example, {output && <Component />} means if the output variable is truthy render the component. If this logic is not set, an error will be thrown that the value we are trying to render in <Component /> is null or undefined.

The new code blocks have comments above or below to describe what is happening. The final code for Comment.js is;

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useState } from 'react' // import the useState function
import classes from './Comment.module.css'
import Select from 'react-select'
import api from '../../api' // import the api object
const Comment =(props) => {
//
// Add the needed variables to state
//
let [target, setTarget] = useState({value: 'en'})
let [output, setOutput] = useState('')
let [error, setError] = useState('')
const translate = () => {
// Clears URL
setOutput('')
// encodes original text comment
const encodedEnglish = encodeURI(props.comment.comment)
// translates english to target language
api.Translate.translateToText(encodedEnglish, target.value)
.then(response => {
// encodes target language
const encodedTarget = encodeURI(response)
// Retrieves audio data in target languages
api.Translate.textToSpeech(encodedTarget, target.value)
.then(response => setOutput(response)) // sets URL
})
.catch(e => setError('Something went wrong...'))
}
return (
<div className={classes.Comment}>
<button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button>
<p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p>
<p>{props.comment.comment}</p>
{/* */}
{/* If there is an output url show the audio player */}
{/* */}
{output &&
<div>
<div style={{textAlign: "center"}}>
<audio controls>
<source src={output} type="audio/wav" />
</audio>
</div>
</div>
}
<div className={classes.TranslateContainer}>
{/* */}
{/* Add an error tag if API call fails */}
{/* */}
<p style={{color: 'red'}}>{error}</p>
{/* */}
{/* Button that calls the tranlate function */}
{/* */}
<button onClick={() => translate()} className={classes.TranslateButton + ' btn'}>Translate</button>
{props.languages &&
<div>
<label htmlFor="languages"><small>Select Language</small></label>
<Select
className={classes.Select}
value={target}
name="languages"
onChange={(selectedOption) => setTarget(selectedOption)}
options={props.languages.map(lang => { return { value: lang, label: lang } })}
/>
</div>}
</div>
</div>
)
}
export default Comment
import React, { useState } from 'react' // import the useState function import classes from './Comment.module.css' import Select from 'react-select' import api from '../../api' // import the api object const Comment =(props) => { // // Add the needed variables to state // let [target, setTarget] = useState({value: 'en'}) let [output, setOutput] = useState('') let [error, setError] = useState('') const translate = () => { // Clears URL setOutput('') // encodes original text comment const encodedEnglish = encodeURI(props.comment.comment) // translates english to target language api.Translate.translateToText(encodedEnglish, target.value) .then(response => { // encodes target language const encodedTarget = encodeURI(response) // Retrieves audio data in target languages api.Translate.textToSpeech(encodedTarget, target.value) .then(response => setOutput(response)) // sets URL }) .catch(e => setError('Something went wrong...')) } return ( <div className={classes.Comment}> <button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button> <p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p> <p>{props.comment.comment}</p> {/* */} {/* If there is an output url show the audio player */} {/* */} {output && <div> <div style={{textAlign: "center"}}> <audio controls> <source src={output} type="audio/wav" /> </audio> </div> </div> } <div className={classes.TranslateContainer}> {/* */} {/* Add an error tag if API call fails */} {/* */} <p style={{color: 'red'}}>{error}</p> {/* */} {/* Button that calls the tranlate function */} {/* */} <button onClick={() => translate()} className={classes.TranslateButton + ' btn'}>Translate</button> {props.languages && <div> <label htmlFor="languages"><small>Select Language</small></label> <Select className={classes.Select} value={target} name="languages" onChange={(selectedOption) => setTarget(selectedOption)} options={props.languages.map(lang => { return { value: lang, label: lang } })} /> </div>} </div> </div> ) } export default Comment
import React, { useState } from 'react'  // import the useState function
import classes from './Comment.module.css'
import Select from 'react-select'

import api from '../../api' // import the api object

const Comment =(props) => {
    //
    // Add the needed variables to state
    //
    let [target, setTarget] = useState({value: 'en'})
    let [output, setOutput] = useState('')
    let [error, setError] = useState('')

    const translate = () => {
        // Clears URL
        setOutput('')

        // encodes original text comment
        const encodedEnglish = encodeURI(props.comment.comment)

        // translates english to target language
        api.Translate.translateToText(encodedEnglish, target.value)
        .then(response => {
            // encodes target language
            const encodedTarget = encodeURI(response)
            // Retrieves audio data in target languages
            api.Translate.textToSpeech(encodedTarget, target.value)
                .then(response => setOutput(response)) // sets URL
        })
        .catch(e => setError('Something went wrong...'))
    }

    return (
        <div className={classes.Comment}>
            <button className={classes.DeleteButton + " btn btn-sm btn-danger float-right"} onClick={() => props.delete(props.comment.owner_id)}>X</button>
            <p className="font-weight-bold">{props.comment.name ? props.comment.name : props.comment.owner_id}</p>
            <p>{props.comment.comment}</p>

            {/*  */}
            {/* If there is an output url show the audio player */}
            {/*  */}
            {output &&
                <div>
                    <div style={{textAlign: "center"}}>
                        <audio controls>
                            <source src={output} type="audio/wav" />
                        </audio>
                    </div>
                </div>
            }

            <div className={classes.TranslateContainer}>

                {/*  */}
                {/* Add an error tag if API call fails */}
                {/*  */}
                <p style={{color: 'red'}}>{error}</p>

                {/*  */}
                {/* Button that calls the tranlate function */}
                {/*  */}
                <button onClick={() => translate()} className={classes.TranslateButton + ' btn'}>Translate</button>

                {props.languages && 
                    <div>
                        <label htmlFor="languages"><small>Select Language</small></label>
                        <Select
                            className={classes.Select}
                            value={target}
                            name="languages"
                            onChange={(selectedOption) => setTarget(selectedOption)}
                            options={props.languages.map(lang => { return { value: lang, label: lang } })}
                            />
                    </div>}
                </div>
        </div>
    )
}

export default Comment

To test it out, leave a comment, select a language, click Translate, make sure your sound is on, and listen to the translation! The request for the translation might take a second or two. However, I have found it to be quite fast.

comment with audio controls for the comment 'this is a great blog post'. Translation in spanish

We successfully added translation capabilities to our page! Although it was added to comments, the underlying process could be replicated for larger text components and varying use cases.

Connect to the Microsoft Text Translation API

Conclusion

Nice job! You learned how to add translation capabilities that can set your app apart from competitors or improve your current users’ experience.

While testing and creating the app I used ~300 calls to the Microsoft Text Translate API. Consequently, I still have over 2,000 calls left for this month to make the functionality even better.

There are some obvious you can improve the functions or components. Here are some ideas;

  • Add translation support for comments that are not in English (maybe we want to translate Spanish into English)
  • Display the actual language name and not just the language code for the options.
  • Show the translated text in the target language below the English text in the comment.

So many possibilities! I may have glazed over some aspects of the code that confused you. If that happened, ask a question in the comments and I would be happy to answer it. Thanks for reading!

5/5 - (1 vote)
« Dark Sky vs OpenWeatherMap: Two Weather API Services Compared
How To Use a News API with Ruby on Rails »

Filed Under: JavaScript API Tutorials, REST API Tutorials Tagged With: Google Translate, javascript, microsoft text translation api, translate, translate api, translation

Team RapidAPI

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Build anything with APIs, faster.

Discover, evaluate, and integrate with any API. RapidAPI is the world’s largest API Hub with over 4 Million developers and 35,000 APIs.

Browse APIs »

APIs mentioned in this article

Connect to the Microsoft Text Translation API
Connect to the Microsoft Text Translation API

Footer

  • API Guides
  • API Courses
  • API Glossary
  • API Testing
  • API Management
  • Most Popular APIs
  • Free APIs List
  • How to use an API
  • Learn REST API
  • Build API’s
  • About
  • Build APIs
  • Careers
  • Contact Us
  • Write for Us
  • API Directory
  • Press Room
  • Privacy Policy
  • Terms of Use

© 2025 RapidAPI. All rights reserved.

Building an Enterprise API Program
Learn More

×