loading...

Help: How to make a multilanguage website?

cecilelebleu profile image Cécile Lebleu ・2 min read

Hi everyone!

I'm building a website the simple way — HTML, CSS, and vanilla JavaScript, that's it. I'm trying to keep it as light and simple as I can. It's looking pretty good so far, but everything is in English and I will eventually need to add translations, mainly Spanish in the very near future, but then probably a couple more. (I can do the translation part).

I have been looking around for options and tools to implement this. My first thought was, since the site is static, only has about 5 pages, (and mostly because I have the time and enthusiasm to do it and keep it updated in more than one language), I'll just do it all by hand! When everything is about ready in English, I'll just duplicate the pages, translate the content, and add a button to switch between the different versions of the same page — manually linking each page. Yes, I actually consider this a viable option. Please don't judge!

Most of the answers, tutorials, and solutions I've found include using a CMS (which I don't think this site needs, and again, I'm trying to keep it as bloat-free as possible. Heck, I've been avoiding jQuery, even though it means writing some functionality from scratch. I like the challenge.)

Or they suggest using PHP or MySQL, which I know the basics of, but definitely would entail a learning curve, and again — keeping it as light as possible.

Or they suggest using the Google Translate API, which...just, no.

Get to the question already!

So my question is, is this actually doable? Have you done it before? Is it insane? Any tips, for example, on how to keep the same content on different pages related, in the eyes of search engines' robots?

Or, am I delusional, and should I give up and add in some PHP? If so, how would you do it? Any guides, or tutorials, ideas, etc?

I would highly appreciate any help, tips, links, funny judgmental gifs, or anything else in the comments!

Posted on by:

cecilelebleu profile

Cécile Lebleu

@cecilelebleu

Brand identity designer learning to be a proper dev. My tabs are 3 spaces long.

Discussion

markdown guide
 

We have done this for one of our apps in a very simple way. It was a matter of taking all the text and putting it in a key/value collection (a JS object).

var en_us = {
    welcome: "Welcome!"
}

var fr_ca = {
    welcome: "Salut!"
}

var lang = en_us;

// set all the text
document.getElementById("welcome").innerHTML = lang.welcome;

This is off-the-top sketch, may not run. You could also be more clever here and have the IDs of the elements containing text exactly match the property names. Then you could write a few lines of code to loop through all the keys in the dictionary and set the text on the corresponding HTML element with the same ID.

That could facilitate developing the site once and having a JS function switch all the text out when the user changes languages.

Our case was slightly different since it was in Elm, but the concept of having two different "dictionaries" and swapping them out is similar.

 

If you're building a static website I would say you have 3 options:

  1. duplicating - no one likes this word, but if you know you'll be updating your site very rarely, if ever, that could actually be a simple option that does the job, so why not. If you know you'll be updating it, better chose another way.

  2. use some 3rd party libs that help you with this. A quick Google search shows i18next and Lingumania. Both can be included via a script tag so that very easy to add. The second looks a bit nicer as an API, but the first looks more supported and stable. Never used either of them so I can't really say.

  3. come up with some other crazy solution like doing in CSS (it will work though!).

These are the options I see for a static website.
If instead you're up for the challenge and want to try another approach, PHP is one them, but purely frontend solutions like React, Vue or Angular will open you some more options, surely nicer than the ones you have on static website.

In any case, good luck and have fun, hope that was helpful in some way!

ps - now that I think of it another option you can look into is a static site generator like Jekyll. The learning curve is very manageable, you'd be working mainly with html and it definitely supports internationalisation. An example (this article is about building a blog, but you can easily publish "normal" pages with Jekyll and build a small website that is easy to update when you need to).

 

This is awesome! Thanks a lot for your answer. I'll take a look at all your suggestions. I never would have thought of using CSS — wow! I wonder how I could make that work across different pages: if you change the language on page A and then go to page B it should stay in the same language. I think it might be doable, and sounds possibly even easier to maintain than duplicate pages.
Anyway, thanks a lot for your time! Great suggestions here!

 

Happy you liked, I should probably mention Jekyll is supported out of the box for free on Github. There are a lot of tutorials online that show how plus the official docs of course.

The bottom line is that you would have a website live for free (and with a few dollars a year you can add your own domain name), it will be easy to update, plus it would be actually be a good solution to you multi lang requirement. All things considered that's the option I would choose, I use it for my own website and it's very easy and convenient (and free)!

Cheers!

 

Where and how do you want to do the detection? Server side? Client side? User selected?

That's the biggest thing to consider. Best option, if you really can consistently translate and keep everything up-to-date by hand, is to do it server side (this is quite simply the most portable approach, it will work even for truly ancient browsers). You don't need PHP or Node or any other server-side scripting language though, you can do it with URL rewrites and simple regex matching on the contents of the Accept-Languages header.

In short:

  • Structure your site so that you have one sub-directory per-language, with your default language at the top level (this is good practice if you're handling things server-side even if you're doing some form of scripting to do it).
  • If you're on a UNIX-like platform, make a symbolic link for the default language code pointing to the top-level directory. On Windows, set up the equivalent as a URL rewrite rule in the server configuration. This is just a consistency bit to help users who actually manually edit URLs.
  • On each page, add something (usually in the footer, sidebar, or menu) to allow users to jump to the same page in each other language. This is something you can easily generate dynamically while deploying your site. The two popular options are flags for the country the language is associated with, or a list of languages using their native names (so Español, Svenska, François instead of Spanish, Swedish, French).
  • In your server configuration, add a rule to look at the contents of the Accept-Languages header. If the header isn't present, contains none of the languages you support, or the URL is explicitly matching a specific language directory, don't modify the URL. Otherwise, pick the leftmost language code in the Accept-Languages header that you support, and rewrite the URL (or redirect) to the appropriate language directory.

This is, in essence, the traditional method of handling web page translations. I'm pretty sure MDN and a number of other sites are still doing it this way in fact. It puts no significant burden on the client (again, well behaved user agents set the Accept-Languages header properly in most cases) or the user, means you send nothing extra over the network, and makes it surprisingly easy to manage on the server side too. The downside is that it doesn't scale past maybe half a dozen languages very well unless you use some form of scripting to generate the web-server config and the language-switchers in the pages.

 

You could use a template engine like moustache to process your html pages before uploading them, then you can have only one version of each page and render it multiple times with the different languages and upload that to your server.

# my-page.html
<h1>{{ myPage.title }}</h1>
// en.json
{
  "myPage.title": "Welcome"
}

// es.json
{
  "myPage.title": "Bienvenido"
}
mustache en.json my-page.html > en/my-page.html
mustache es.json my-page.html > es/my-page.html
 

You have a very French name 😀.
A couple of people have mentioned the dictionary approach, and that really seems most suitable for your use case (it's been a few years, but last time I had to deal with this, we used a dictionary and a translation service). It's also pretty easy to implement and makes text changes a breeze. Server-side might be better for SEO, but if you're not that worried about it, client-side is totally fine.

 

Oui, je suis moitié française :) (Yes, I'm half french!)
Although for now, I'm looking to translate to Spanish, because of the market in my location.

Using a dictionary sounds like the best option so far, but I'm still wondering how I could keep the language "preference" when moving from page to page. Do you have any suggestions?

 

Je suis Français aussi (Cajun, en fait).

Easiest way to persist the preference would be local storage or a cookie. When the user selects the language preference, you just point to the relevant dictionary object (could be a file or you could just load the object into memory on page load depending on how much text there is).

You mentioned you might duplicate pages in the different languages, but you can just use tokens to reference the text (e.g., {{ myPage.title }} -- see Avalander's post), and dynamically swap the text upon user selection without page requests. If you load the dictionaries when the user first hits the site, you won't need to make subsequent requests, and the UX will be very snappy. However, if you're really gonna go with vanilla JS, then using tokens will likely be more work than it's worth (a framework like Vue gives you that functionality out of the box); in that case, just use innerHTML or innerText on id-targeted elements, e.g., <div id="biography"><!-- your script inserts language-specific biography text here --></div>. Good luck!