How to create multilingual static pages without frameworks


From time to time, we have the experience of building websites without frameworks like Angular, Vue.js, or React. Perhaps, for fun, we are new, or we just want something extremely simple.

In my case, I started building my personal website several years ago. In those days, I didn't know Angular, and it was a little bit messy to support everything I needed. I didn't consider myself a front-end developer. It was more like my hobby.

Something important in my case was to add multilingual support since I speak English and Spanish fluently. This was a little bit messy since I couldn't find any good library or solution. After several attempts, I came up with the following pieces of code that can simplify your life also.

I have two files, one for English and one for Spanish, where I store the translations in JSONs as constants. If you wonder why I don't store only the JSONs, I had several issues consuming the files later. I got several errors, and most solutions were for Node.js only.

lang-en.js

const translations = {
    "telephone": "Telephone",
    "email": "Email",
    "contactMe": "Contact me"
};

lang-es.js

const translations = {
    "telephone": "TelĂ©fono",
    "email": "Email",
    "contactMe": "Contáctame"
};

The following script is for reading the scripts:

get-script.js

const getScript = url => new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = url;
    script.async = true;
 
    script.onerror = reject;
 
    script.onload = script.onreadystatechange = function() {
      const loadState = this.readyState;
 
      if (loadState && loadState !== 'loaded' && loadState !== 'complete') return;
 
      script.onload = script.onreadystatechange = null;
 
      resolve();
    }
 
    document.head.appendChild(script);
});

And the last script is for setting the values in your HTML:

translations.js

let lang = 'en';

let nLang = (navigator.languages
    ? navigator.languages[0]
    : (navigator.language || navigator.userLanguage)).split('-')[0];

let supportedLang = ['en', 'es'];

lang = supportedLang.includes(nLang) ? nLang : lang;

getScript(`lang-${lang}.js`)
.then(() => {
    document.querySelectorAll('[data-translation]').forEach(item => {
        item.innerHTML = translations[`${item.dataset.translation}`];
    });
})
.catch((e) => {
  console.error(e);
});

So, how do you consume and configure your HTML? You define a data-* attribute called data-translation with the value you expect from the "JSON" like this:

<script src="get-script.js"></script>
<script src="translations.js"></script>

<p data-translation="contactMe"></p>
<p data-translation="telephone"></p>
<p data-translation="email"></p>

And that's all. Now, you can create your static multilingual pages without frameworks.

Notes:
  • If you create dynamic tags, consider adding the data-translation attribute always. If you do this and later add a link/button for selecting the language manually, the translations will be automatic. If not, you will need to update the dynamic tags manually.
  • Since the translations variable is a JSON, you can easily access its values and show other kinds of messages like warnings or errors.

Comments