
In this tutorial, I will teach you how to create a Google Translate Clone App using HTML5, CSS3, and JavaScript. The complete source code of this JavaScript Language Translator App is given below.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Language Translator</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Font Awesome CDN Link for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
<div class="container">
<div class="wrapper">
<div class="text-input">
<textarea spellcheck="false" class="from-text" placeholder="Enter text"></textarea>
<textarea spellcheck="false" readonly disabled class="to-text" placeholder="Translation"></textarea>
</div>
<ul class="controls">
<li class="row from">
<div class="icons">
<i id="from" class="fas fa-volume-up"></i>
<i id="from" class="fas fa-copy"></i>
</div>
<select></select>
</li>
<li class="exchange"><i class="fas fa-exchange-alt"></i></li>
<li class="row to">
<select></select>
<div class="icons">
<i id="to" class="fas fa-volume-up"></i>
<i id="to" class="fas fa-copy"></i>
</div>
</li>
</ul>
</div>
<button>Translate Text</button>
</div>
<script src="js/countries.js"></script>
<script src="js/script.js"></script>
</body>
</html>/* Import Google Font - Poppins */@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
min-height: 100vh;
background: #5372F0;
}
.container{
max-width: 690px;
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: #5372F0;
}
@media (max-width: 660px){
.container{
padding: 20px;
}
.wrapper .text-input{
flex-direction: column;
}
.text-input .to-text{
border-left: 0px;
border-top: 1px solid #ccc;
}
.text-input textarea{
height: 200px;
}
.controls .row .icons{
display: none;
}
.container button{
padding: 13px;
font-size: 16px;
}
.controls .row select{
font-size: 16px;
}
.controls .exchange{
font-size: 14px;
}
}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"
}const fromText = document.querySelector(".from-text"),
toText = document.querySelector(".to-text"),
exchageIcon = document.querySelector(".exchange"),
selectTag = document.querySelectorAll("select"),
icons = document.querySelectorAll(".row i");
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", () => {
let tempText = fromText.value,
tempLang = selectTag[0].value;
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", () => {
let text = fromText.value.trim(),
translateFrom = selectTag[0].value,
translateTo = selectTag[1].value;
if(!text) return;
toText.setAttribute("placeholder", "Translating...");
let apiUrl = `https://api.mymemory.translated.net/get?q=${text}&langpair=${translateFrom}|${translateTo}`;
fetch(apiUrl).then(res => res.json()).then(data => {
toText.value = data.responseData.translatedText;
data.matches.forEach(data => {
if(data.id === 0) {
toText.value = data.translation;
}
});
toText.setAttribute("placeholder", "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);
}
});
});If you have been searching for the right note-taking or knowledge management app, you have…
Looking for AnyType alternatives? You're not alone. AnyType has gained popularity as a privacy-focused, local-first…
Notion is a popular all-in-one workspace, but many users seek alternatives for different needs (free…
Logseq is a beloved tool in the personal knowledge management (PKM) community. It's free, open-source,…
Looking for a Webshare alternative? You're not alone. Webshare is a popular proxy service with…
Docker changed software development forever. It made containers accessible, gave developers a simple workflow, and…