
Creating a language selector in JavaScript
Today, we're going to talk about how to implement a simple language selector on the basic static website, without the need of any backend or database calls or redirection to another page. We will be using only JavaScript, no PHP or other programming languages.
Serving HTML content in multiple languages is a big topic. To start with, what we’re going to do is to basically modify HTML classes by JavaScript to change the appearance of specific HTML elements on the page.
For demonstration purposes we chose the simple portfolio website.
Now we show you how to do multiple language versions on a basic website and how to switch content with JavaScript without any backend, with the added benefit of being light and fast. When we select a language in our header element, all the content we have prepared will switch to that language.
Without further redue, let’s go into it.
Prerequisites
Surely to continue, we assume HTML, CSS and JavaScript knowledge might come handy.
Language Selectors in Header
Let's say we have a simple page with header, body etc already done, but we would like to add languages options. First we create three versions of the languages we want to have >
<div class="languageContainer"> <div id="eng" class="languages british"><a>english</a></div> <div id="esp" class="languages spain"><p>español</p></div> <div id="svk" class="languages slovak"><p>slovensky</p></div> </div> <nav class="menu"> <a href="#about" class="eng" lang="en">About</a> <a href="#about" class="esp" lang="es">Acerca de</a> <a href="#about" class="svk" lang="sk">O mne</a> <a href="#work" class="eng" lang="en">My work</a> <a href="#work" class="esp" lang="es">Trabajos</a> <a href="#work" class="svk" lang="sk">Moja praca</a> <a href="#contact" class="eng" lang="en">Contact</a> <a href="#contact" class="esp" lang="es">Contacto</a> <a href="#contact" class="svk" lang="sk">Kontakt</a> </nav>
Now we describe what we have done. We created container <div>
with a specific class to hold and visually modify its content by CSS(we show it later).
Next, we have 3 sets of languages, each have class language
, again for CSS, the british, spain, slovak
classes are for a set of flags we took from Country Flags - A simple API to load any country flags.
We also have a lang attribute, which will let search crawlers know that this content is in another language, they will treat that content differently, that is for a better rankings.
The most important is attribute id, this serves for the event listener - basically when JavaScript code detects we for example clicked on one of these three, it will run our code.
CSS for the upper HTML code>
.languageContainer { display: flex; justify-content: end; overflow: visible; height: 3rem; font-size: small; } .languages { display:flex; align-items: center; margin:.2rem; padding: 0.5rem; color: #fff; cursor: pointer; } .languages::before { content: ''; display: block; width: 32px; height: 32px; } .british::before{ background:url("https://www.countryflags.io/gb/flat/32.png"); } .spain::before{ background:url("https://www.countryflags.io/es/flat/32.png"); } .slovak::before{ background:url("https://www.countryflags.io/sk/flat/32.png"); }
(Note that with and height of the icons in the class languages::before
correlates with the image size we have set in the URL)
(Note2 : we set nice pointer - hand will show when we move mouse cursor above the language class)
Alternatively, we can use downloaded images(icons), these are from flagpedia.net, to be sure that our page won't hang when the external source isn't available. So we made it local like this>
.british::before{ background:url('../img/flags/unitedkingdom32x32.png') } .spain::before{ background:url('../img/flags/spain32x32.png') } .slovak::before{ background:url('../img/flags/slovakia32x32.png') }
JavaScript part
Now the coding part. We would need to manipulate the appearance or disappearance of those elements with different texts. To access them, in our JavaScript file we create >
const selectedEnglish = document.getElementById("eng"); const selectedEspanol = document.getElementById("esp"); const selectedSlovensky = document.getElementById("svk"); const hidden = "display:none;"; const shown = "display:block;";
The variable hidden and shown will modify the style of the HTML element from this script.
To access all the elements with the same language, we create this code>
const allEnglishText = document.getElementsByClassName("eng"); const allEspanolText = document.getElementsByClassName("esp"); const allSlovakText = document.getElementsByClassName("svk");
Now we need to recognize what we are going to do with it. We need to switch on the one language version and by the same time switch off all the other versions.
This can be put in the function, and we need to have 3 functions for each language version. For example :
allEnglishText
is a collection of all HTML elements with the same class name eng
. In the function, we cycle through all such elements and we set parameter, or lets say style to all of them, and similarly, all the other language versions will not be displayed at all.
//SHOW ALL ENGLISH TEXT function showEnglishText() { for (element in allEnglishText) { allEnglishText[element].style = shown; } for (element in allEspanolText) { allEspanolText[element].style = hidden; } for (element in allSlovakText) { allSlovakText[element].style = hidden; } } //SHOW ALL SPANISH TEXT function showSpanishText() { for (element in allEnglishText) { allEnglishText[element].style = hidden; } for (element in allEspanolText) { allEspanolText[element].style = shown; } for (element in allSlovakText) { allSlovakText[element].style = hidden; } } //SHOW ALL SLOVAK TEXT function showSlovakText() { for (element in allEnglishText) { allEnglishText[element].style = hidden; } for (element in allEspanolText) { allEspanolText[element].style = hidden; } for (element in allSlovakText) { allSlovakText[element].style = shown; } }
Buttons and EventListeners
Until now we have created all the text in HTML and functions to show or hide them, but we also need the switch to launch the functions. We continue behind previous code by adding this>
//ENGLISH-> ALL OTHERS SWITCHED OFF selectedEnglish.addEventListener("click", () => { selectedEnglish.classList.add("langSelected"); selectedEspanol.classList.remove("langSelected"); selectedSlovensky.classList.remove("langSelected"); showEnglishText(); });
To explain, by adding event listener on the element stored in variable selectedEnglish
--> that's our element in the header with id=’eng’
, when we make mouse click on it, it will launch our function showEnglishText()
and also we have bunch of code to add a CSS class to it, which contain border, to show off visually what button is currently clicked.
Of course we need to add all other versions>
//SPANISH-> ALL OTHERS SWITCHED OFF selectedEspanol.addEventListener("click", () => { selectedEspanol.classList.add("langSelected"); selectedEnglish.classList.remove("langSelected"); selectedSlovensky.classList.remove("langSelected"); showSpanishText(); }); //SLOVAK-> ALL OTHERS SWITCHED OFF selectedSlovensky.addEventListener("click", () => { selectedSlovensky.classList.add("langSelected"); selectedEspanol.classList.remove("langSelected"); selectedEnglish.classList.remove("langSelected"); showSlovakText(); });
This alone would be enough to have it working, but there is a slight problem, so far we still see all 3 versions by default, only after we click on the respective button, they hide. So we need to make sure by default there is only 1 visible by calling for example showEnglishText()
function behind the definition of variables. But we can make it better as we can see in the next chapter.
Mechanism for storing the selected language in Local Storage
Now we will step up and we store the picked language into Local Storage of the user’s browser. This way user will be served the language that was last selected. That means even if the page is refreshed, it will “remember” the last selection. We create an entry to the local storage by using localStorage.setItem()
in each of the event listeners, like this>
//ENGLISH-> ALL OTHERS SWITCHED OFF selectedEnglish.addEventListener("click", () => { selectedEnglish.classList.add("langSelected"); selectedEspanol.classList.remove("langSelected"); selectedSlovensky.classList.remove("langSelected"); showEnglishText(); localStorage.setItem("languageActive", "english"); }); //SPANISH-> ALL OTHERS SWITCHED OFF selectedEspanol.addEventListener("click", () => { selectedEspanol.classList.add("langSelected"); selectedEnglish.classList.remove("langSelected"); selectedSlovensky.classList.remove("langSelected"); showSpanishText(); localStorage.setItem("languageActive", "espanol"); }); //SLOVAK-> ALL OTHERS SWITCHED OFF selectedSlovensky.addEventListener("click", () => { selectedSlovensky.classList.add("langSelected"); selectedEspanol.classList.remove("langSelected"); selectedEnglish.classList.remove("langSelected"); showSlovakText(); localStorage.setItem("languageActive", "slovak"); });
This way we will have stored under id languageActive
the language version we just clicked on. Now its time to write the code to recover this information from Local Storage. And this is how>
//LOCAL STORAGE ADDON switch (localStorage.getItem("languageActive")) { case "english": selectedEnglish.classList.add("langSelected"); showEnglishText(); break; case "espanol": selectedEspanol.classList.add("langSelected"); showSpanishText(); break; case "slovak": selectedSlovensky.classList.add("langSelected"); //console.log("slovak on"); showSlovakText(); break; default: //default ENGLISH text shown, all others disabled //default -> no local storage exists selectedEnglish.classList.add("langSelected"); showEnglishText(); }
By default - if we couldnt recover anything from Local Storage, e.g. the user is the first time on your site, there will be launched code under default
. We chose english to be shown first.
When there is an entry found, switch will recognize the value and it will call the respective function.
Conclusion
We showed you how to do some very basic language switching and hopefully you liked it.
The best thing would be let the search engine know that we have localized versions of the text on our page, so they won't treat the translated text as duplicate. Because that can lead to a lot of aplicated content and that can in turn might lead in lower rank in search engines.
Surely we can make this better, for example putting all the text content (all the translations as well) into one object and selecting the desired version of the text from it with code that retrieves value from the key, but that we will do in another article. Until then!
Images by Tibor Kopca

Tibor Kopca
From tinkering with computers as a teenager, through a career in datacenter he stepped into web development with full force and started coding. Absorbs all information like a sponge.
Fan of aerospace, engineering, information technologies and watches.
Related Posts
How to make your own custom cursor for your website
When I started browsing different and original websites to learn from them, one of the first things that caught my attention was that some of them had their own cursors,…
Node.js and npm: introductory tutorial
In this tutorial we will see how to install and use both Node.js and the npm package manager. In addition, we will also create a small sample application. If you…
How to connect to MySQL with Node.js
Let's see how you can connect to a MySQL database using Node.js, the popular JavaScript runtime environment. Before we start, it is important to note that you must have Node.js installed…
JavaScript Programming Styles: Best Practices
When programming with JavaScript there are certain conventions that you should apply, especially when working in a team environment. In fact, it is common to have meetings to discuss standards…
Difference between arrow and normal functions in JavaScript
In this tutorial we are going to see how arrow functions differ from normal JavaScript functions. We will also see when you should use one and when you should use…
JavaScript Arrow functions: What they are and how to use them
In this article we are going to see what they are and how to use JavaScript Arrow Functions, a new feature introduced with the ES6 standard (ECMAScript 6). What are Arrow…
How to insert an element into an array with JavaScript
In this brief tutorial you will learn how to insert one or more elements into an array with JavaScript. For this we will use the splice function. The splice function will not…
What is the difference between primitives types and objects in JavaScript?
In this short tutorial we are going to look at the differences between primitive types and objects in JavaScript. To start with, we're going to look at what primitive types…
How to get DOM elements with JavaScript
When you access any element of the DOM, it is usual to save it in a variable. This is something that at first might seem very simple, but if you…
How to reverse an array in JavaScript
In this tutorial we are going to see how you can change the order of the elements of an array so that they are inverted. You could use a loop…
How synchronize the scroll of two divs with JavaScript
In case you have two divs of different sizes you may sometimes want to scroll both at the same time but at different speeds depending on their size. For example,…
How to use the codePointAt method in JavaScript
The JavaScript codePointAt method has more or less the same function as the charCodeAt method, used to get the 16-bit Unicode representation of the character at a certain position in…