2

I want to make a page in English that has a button which can change the language to German. I have read thousands of articles about this topic but I haven't got the answer. I know for sure I don't want to make it with Google Translator API or any API. I want to make it with pure JS. I just want to how do you do it? With a button that has a lot of lines that changes the element's text one by one: function changeLang () { document.getElementById('someid').innerHTML = "some German text"; ... }

Or make it with const transLang { from = "en" to = "de" ...} ? Please let me know if you have any idea how to start it.

4
  • 1
    Another way of doing it is to have all the text into separate JSON files (one for each language) and load the appropriate one whenever the language changes. The advantage, compared to having all translation in data-[lang] attribute is that you send the text to the client only in the required language and the system is easier to scale (in case you think you might add new languages in the future). Commented Feb 23, 2021 at 12:26
  • 2
    @secan I agree that a "pure JS" solution is not ideal. Loading in language translations form a resource (json) file or making an API call to a database would be much more manageable. But for a small page / a handful of lines to translate / only 1 or two languages, that may be over the top. Commented Feb 23, 2021 at 12:33
  • @freedomn-m, yes, of course; as almost always, there are many ways to skin a cat and the (supposedly) "best" one depends on circumstances. I did not mean to dispute the solution you proposed, I was just offering an alternative... and I might also misunderstood what the OP meant with "pure JS", which I interpreted as "no external/third-party library". Commented Feb 23, 2021 at 12:40
  • @secan no worries - I do agree with you. Just wanted to add possible reasons for not wanting to go down that (viable) route. Commented Feb 23, 2021 at 12:52

1 Answer 1

4

For a "pure JS" solution, in other words none of the usual solutions:

  • no Ajax to get the translated page text / replacement html
  • no redirect to a different page which can handle layout incongruities

one option is to store the translations on each div and switch them over using .text(). Do not code your translations into your javascript as that will quickly become impossible to maintain.

function switchLang(lang)
{
    $("[data-" + lang + "]").text(function(i, e) {
        return $(this).data(lang);
    });
}

switchLang("en");

$(".switchlang").click(function() {
    // change the button caption here, eg a flag
    // UX opinion of whether it should be what it is 
    // or what it will become
    // ie "de" click to make it "de"
    // or "de" it's currently "de", click to change it
    $(this).text($(this).data("lang"));
    
    // switch to other language based on language on the button
    var lang = $(this).data("lang") == "de" ? "en" : "de";
    $(this).data("lang", lang);
    switchLang(lang)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span data-de="Um die Nachrichten zu lesen" 
      data-en="To read the news"></span>,&nbsp;
<span data-de="Übersetzungsdienst nicht verfügbar" 
      data-en="click here"></span>
<hr/>
<div data-en="no de translation for this line"></div>
<hr/>
<button class='switchlang' data-lang="en">de</button>

You can then easily add new languages without needing to change any code (this time with separate buttons)

var defaultlang = "en";

function switchLang(lang)
{
    $("[data-" + lang + "]").text(function(i, e) {
        return $(this).data(lang);
    });
}

switchLang("en");

$(".switchlang").click(function() {
    switchLang($(this).data("lang"))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span data-de="Um die Nachrichten zu lesen" 
      data-es="Para leer las noticias"
      data-en="To read the news"></span>,&nbsp;
<span data-de="Übersetzungsdienst nicht verfügbar" 
      data-es="haga clic aquí"
      data-en="click here"></span>
<hr/>
<div data-es="no hay traducción para esta línea"
     data-en="no de translation for this line"></div>
<hr/>
<button class='switchlang' data-lang="en">en</button>
<button class='switchlang' data-lang="de">de</button>
<button class='switchlang' data-lang="es">es</button>


You may prefer to default the language in the HTML directly, rather than on startup, eg:

<span data-de="speichern">save</span>

then store the original in .data("en") on load. This would remove the FOUC (delay when loading the page) which may be important for your scenario.

Sign up to request clarification or add additional context in comments.

2 Comments

It's cool and thanks a lot but is it possible to make it working with only one button? I mean on the first click, change the language to German, on the second click change the language back to English.
Sure, I'll update - it's not much different just how you handle the click event. I wanted to show an extensible version without putting the translations in the js.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.