In this article, we’ll walk through the step-by-step process of creating a text translation application with MongoDB, React, ExpressJS, and NodeJS. This application will provide users with a user-friendly interface for translating text between different languages.
Output Preview: Let us have a look at how the final output will look like.

Prerequisites:
Approach to Create Text Translation Tool using MERN Stack:
Backend:
- Set up a new NodeJS project with npm or yarn and initialize a Git repository.
- Create a folder called "server" within the project directory.
- Within the "server" folder, create the following file:
- server.js: This file contains the server-side code using Express to create a RESTful API for translation. It listens on port 5000 and handles requests for translations.
- Inside the "server" folder, run the command npm install express cors to install the dependencies.
Frontend:
- Set up a new React project with create-react-app. Initialize a Git repository. Define the project structure.
- Create a folder called "client" within the project directory. The "client" folder will contain the front-end code.
- Within the "client" folder, create the following files and directories:
- src/index.js: This file contains the client-side code to render the Translate component to the root HTML element.
- src/styles/App.css: This file contains the CSS styles for the Translate component.
- src/components/App.js: This file contains the main component that renders the Translate component.
- src/components/data.js: This file contains an array of country codes and their corresponding languages.
- src/components/Translate.js: This file contains the Translate component that handles text input and translation requests.
- Inside the "client" folder, run the command npm install react react-dom to install the React library.
Steps to Create the Backend Server:
Step 1: Create a directory for the project.
mkdir server
cd server
Step 2: Initialized the Express app and installing the required packages
npm init -yStep 3: Install the necessary package in your server using the following command.
npm install express corsProject Structure(Backend):

The updated dependencies in package.json file of backend will look like:
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.3"
},
Example: Create the required files and write the following code.
// server.js
import express from 'express';
import cors from 'cors';
const app = express();
app.use(cors());
app.get('/', async (req, res) => {
try {
const { text, source, target } = req.query;
const url = `https://api.mymemory.translated.net/get?q=$%7Btext%7D&langpair=$%7Bsource%7D%7C$%7Btarget%7D%60;
const response = await fetch(url);
const json = await response.json();
const matches = await json.matches;
const translatedText = matches[matches.length - 1].translation || 'No translation found';
res.send(translatedText);
} catch (error) {
console.log(error);
res.send('Something went wrong!');
}
});
app.listen(5000, () => {
console.log('Server is running on port 5000');
});
Start your server using the following command.
node server.jsSteps to Setup Frontend with React:
Step 1: Create React App
npx create-react-app clientStep 2: Switch to the project directory
cd clientStep 3: Installing the required packages:
npm install react react-domProject Structure(Frontend):

The updated Dependencies in package.json file of frontend will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Example: Create the required files and write the following code.
/* App.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
min-height: 100vh;
background: #222222;
}
.container {
min-width: 700px;
width: 100%;
padding: 30px;
background: #fff;
border-radius: 7px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.01);
}
.wrapper {
border-radius: 5px;
border: 1px solid #ccc;
}
.wrapper .text-input {
display: flex;
border-bottom: 1px solid #ccc;
}
.text-input .to-text {
border-radius: 0px;
border-left: 1px solid #ccc;
}
.text-input textarea {
height: 250px;
width: 100%;
border: none;
outline: none;
resize: none;
background: none;
font-size: 18px;
padding: 10px 15px;
border-radius: 5px;
}
.text-input textarea::placeholder {
color: #b7b6b6;
}
.controls,
li,
.icons,
.icons i {
display: flex;
align-items: center;
justify-content: space-between;
}
.controls {
list-style: none;
padding: 12px 15px;
}
.controls .row .icons {
width: 38%;
}
.controls .row .icons i {
width: 50px;
color: #adadad;
font-size: 14px;
cursor: pointer;
transition: transform 0.2s ease;
justify-content: center;
}
.controls .row.from .icons {
padding-right: 15px;
border-right: 1px solid #ccc;
}
.controls .row.to .icons {
padding-left: 15px;
border-left: 1px solid #ccc;
}
.controls .row select {
color: #333;
border: none;
outline: none;
font-size: 18px;
background: none;
padding-left: 5px;
}
.text-input textarea::-webkit-scrollbar {
width: 4px;
}
.controls .row select::-webkit-scrollbar {
width: 8px;
}
.text-input textarea::-webkit-scrollbar-track,
.controls .row select::-webkit-scrollbar-track {
background: #fff;
}
.text-input textarea::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 8px;
}
.controls .row select::-webkit-scrollbar-thumb {
background: #999;
border-radius: 8px;
border-right: 2px solid #ffffff;
}
.controls .exchange {
color: #adadad;
cursor: pointer;
font-size: 16px;
transition: transform 0.2s ease;
}
.controls i:active {
transform: scale(0.9);
}
.container button {
width: 100%;
padding: 14px;
outline: none;
border: none;
color: #fff;
cursor: pointer;
margin-top: 20px;
font-size: 17px;
border-radius: 5px;
background: #2f8d46;
}
.above-container {
display: flex;
align-items: center;
justify-content: center;
}
.above-container-content {
font-size: xx-large;
font-weight: 100;
display: inline;
margin-right: 1%;
margin-bottom: 1%;
color: #ffffff;
}
.above-container img {
width: 40px;
}
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import App from './components/App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// App.js
import "../styles/App.css";
import Translate from "./Translate.js";
function App() {
return (
<>
<Translate />
</>
);
}
export default App;
// data.js
const countries = {
"am-ET": "Amharic",
"ar-SA": "Arabic",
"be-BY": "Bielarus",
"bem-ZM": "Bemba",
"bi-VU": "Bislama",
"bjs-BB": "Bajan",
"bn-IN": "Bengali",
"bo-CN": "Tibetan",
"br-FR": "Breton",
"bs-BA": "Bosnian",
"ca-ES": "Catalan",
"cop-EG": "Coptic",
"cs-CZ": "Czech",
"cy-GB": "Welsh",
"da-DK": "Danish",
"dz-BT": "Dzongkha",
"de-DE": "German",
"dv-MV": "Maldivian",
"el-GR": "Greek",
"en-GB": "English",
"es-ES": "Spanish",
"et-EE": "Estonian",
"eu-ES": "Basque",
"fa-IR": "Persian",
"fi-FI": "Finnish",
"fn-FNG": "Fanagalo",
"fo-FO": "Faroese",
"fr-FR": "French",
"gl-ES": "Galician",
"gu-IN": "Gujarati",
"ha-NE": "Hausa",
"he-IL": "Hebrew",
"hi-IN": "Hindi",
"hr-HR": "Croatian",
"hu-HU": "Hungarian",
"id-ID": "Indonesian",
"is-IS": "Icelandic",
"it-IT": "Italian",
"ja-JP": "Japanese",
"kk-KZ": "Kazakh",
"km-KM": "Khmer",
"kn-IN": "Kannada",
"ko-KR": "Korean",
"ku-TR": "Kurdish",
"ky-KG": "Kyrgyz",
"la-VA": "Latin",
"lo-LA": "Lao",
"lv-LV": "Latvian",
"men-SL": "Mende",
"mg-MG": "Malagasy",
"mi-NZ": "Maori",
"ms-MY": "Malay",
"mt-MT": "Maltese",
"my-MM": "Burmese",
"ne-NP": "Nepali",
"niu-NU": "Niuean",
"nl-NL": "Dutch",
"no-NO": "Norwegian",
"ny-MW": "Nyanja",
"ur-PK": "Pakistani",
"pau-PW": "Palauan",
"pa-IN": "Panjabi",
"ps-PK": "Pashto",
"pis-SB": "Pijin",
"pl-PL": "Polish",
"pt-PT": "Portuguese",
"rn-BI": "Kirundi",
"ro-RO": "Romanian",
"ru-RU": "Russian",
"sg-CF": "Sango",
"si-LK": "Sinhala",
"sk-SK": "Slovak",
"sm-WS": "Samoan",
"sn-ZW": "Shona",
"so-SO": "Somali",
"sq-AL": "Albanian",
"sr-RS": "Serbian",
"sv-SE": "Swedish",
"sw-SZ": "Swahili",
"ta-LK": "Tamil",
"te-IN": "Telugu",
"tet-TL": "Tetum",
"tg-TJ": "Tajik",
"th-TH": "Thai",
"ti-TI": "Tigrinya",
"tk-TM": "Turkmen",
"tl-PH": "Tagalog",
"tn-BW": "Tswana",
"to-TO": "Tongan",
"tr-TR": "Turkish",
"uk-UA": "Ukrainian",
"uz-UZ": "Uzbek",
"vi-VN": "Vietnamese",
"wo-SN": "Wolof",
"xh-ZA": "Xhosa",
"yi-YD": "Yiddish",
"zu-ZA": "Zulu",
};
export default countries;
// Translate.js
import React, { useEffect } from "react";
import countries from "./data.js";
const Translate = () => {
useEffect(() => {
const fromText = document.querySelector(".from-text");
const toText = document.querySelector(".to-text");
const exchageIcon = document.querySelector(".exchange");
const selectTag = document.querySelectorAll("select");
const icons = document.querySelectorAll(".row i");
const translateBtn = document.querySelector("button");
selectTag.forEach((tag, id) => {
for (let country_code in countries) {
let selected =
id === 0
? country_code === "en-GB"
? "selected"
: ""
: country_code === "hi-IN"
? "selected"
: "";
let option = `<option ${selected} value="${country_code}">${countries[country_code]}</option>`;
tag.insertAdjacentHTML("beforeend", option);
}
});
exchageIcon.addEventListener("click", () => {
console.log("helo");
let tempText = fromText.value;
let tempLang = selectTag[0].value;
console.log(tempText);
console.log(tempLang);
fromText.value = toText.value;
toText.value = tempText;
selectTag[0].value = selectTag[1].value;
selectTag[1].value = tempLang;
});
fromText.addEventListener("keyup", () => {
if (!fromText.value) {
toText.value = "";
}
});
translateBtn.addEventListener("click", async () => {
let text = fromText.value.trim();
let translateFrom = selectTag[0].value;
let translateTo = selectTag[1].value;
if (!text) return;
toText.setAttribute("placeholder", "Translating...");
try {
const response = await
fetch(`http://localhost:5000/?text=${text}&source=${translateFrom}&target=${translateTo}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const translatedText = await response.text();
toText.value = translatedText;
toText.setAttribute("placeholder", "Translation");
} catch (error) {
console.error("Fetch error:", error);
toText.setAttribute("placeholder", "Error in translation");
}
});
icons.forEach((icon) => {
icon.addEventListener("click", ({ target }) => {
if (!fromText.value || !toText.value) return;
if (target.classList.contains("fa-copy")) {
if (target.id === "from") {
navigator.clipboard.writeText(fromText.value);
} else {
navigator.clipboard.writeText(toText.value);
}
} else {
let utterance;
if (target.id === "from") {
utterance = new SpeechSynthesisUtterance(fromText.value);
utterance.lang = selectTag[0].value;
} else {
utterance = new SpeechSynthesisUtterance(toText.value);
utterance.lang = selectTag[1].value;
}
speechSynthesis.speak(utterance);
}
});
});
}, []);
return (
<>
<div className="above-container ">
<img
src={"https://media.geeksforgeeks.org/wp-content/uploads/20240306111234/gfg.jpg"}
className="above-container-content"
alt="GeeksforGeeks Logo"
/>
<h1 className="above-container-content">Translate</h1>
</div>
<div className="container">
<div className="wrapper">
<div className="text-input">
<textarea
spellCheck="false"
className="from-text"
placeholder="Enter text"
></textarea>
<textarea
spellCheck="false"
readOnly
disabled
className="to-text"
placeholder="Translation"
></textarea>
</div>
<ul className="controls">
<li className="row from">
<div className="icons">
<i id="from" className="fas fa-volume-up"></i>
<i id="from" className="fas fa-copy"></i>
</div>
<select></select>
</li>
<li className="exchange">
<i className="fas fa-exchange-alt"></i>
</li>
<li className="row to">
<select></select>
<div className="icons">
<i id="to" className="fas fa-volume-up"></i>
<i id="to" className="fas fa-copy"></i>
</div>
</li>
</ul>
</div>
<button>Translate Text</button>
</div>
</>
);
};
export default Translate;
Start your application using the following command.
npm startOutput:
