Translation of static website content into 4 languages

What tool have you used to release the option of translating the content of a static HTML site into another language? Some jQuery plugin, some api? What is the best practice for performance today?

Would it be ideal to use something that captures the user'S IP and loads a page already translated into the language for that country?

There will be only 4 languages: Portuguese, English, Spanish and Italian. For the rest of the countries, the language default may be English.

Author: rray, 2017-02-07

2 answers

You can do any translation via gulp, it has some interesting i18n Modules https://www.npmjs.com/package/gulp-static-i18n

You need a module in gulp that reads your texts or html elements with a given data/class attribute and that module throws everything into a json or .mo file(much used for translation)

And another task to build the translations, duplicating the htmls and exchanging the texts, so you could upload everything on a static server of the type Amazon's S3, which has low cost and so you don't need a server/backend to translate text, is scalable and fast.

And for the redirect via geolocation, maybe you can do it via nginx or htacces, so you need a server just to do the redirect, so you will have this:

User accesses the site -> server with nginx that checks the language and redirects to the right path of S3 -> S3 with folder / en / or / pt / or /es / or another language / folder .

 1
Author: Willian Sabião, 2017-04-21 18:48:32

I think one of the best ways is to use link, like:

<link rel="alternate" hreflang="en-gb" href="http://en-gb.site.com" />
<link rel="alternate" hreflang="pt-br" href="http://pt-br.site.com" />

This will already cause search engines to already show the content in the right language, in most cases.

But obviously that's not enough. To get the user language, a good way is to get the window.navigator.language, then use some kind of matcher from BCP-47, so if the browser result is en-us it would get the closest language available, the en-gb, for example. If not there is a language next will fall into a pattern, which is what you define.


This is the first time I have tried to make a site with multiple languages, so what I will write here is what I am doing, but it has not been "tested in production" and maybe there are other problems in this method.

I'm using Gopherjs, Golang, so I just copied what I use and tried to simplify, but it will be necessary to find equivalent functions for Javascript.

O what I have done is simply:

<div data-text="welcome"></div>

Then, when you start the page you get the client language, using window.navigator.language, and there is a dictionary and the list of languages:

var Idiomas = []language.Tag{language.English, language.BrazilianPortuguese}

var Dicionario = texts{
    "welcome": {
       "Welcome",
       "Bem-vindo",
    },
    "another-text": {
        "Another text",
        "Outro texto",
    },
}

Now, to know which content to display, I use the text/language, you should find some other for Javascript. In this way it simply becomes:

var idiomaEscolhido string

// Obtêm o idioma do subdominio, se existir
subdominio := strings.Split(js.Global.Get("location").Get("host").String(), ",")
if len(subdominio) > 1 && subdominio[0] != "meusite" {
    idiomaEscolhido = subdominio[0]
}   

// Obtêm o idioma do navegador, se não há definido até então
if idiomaUsuario = "" {
    idiomaUsuario = js.Global.Get("navigator").Get("language").String()
}

// Encontra o idioma mais próximo
 _, index := language.MatchStrings(language.NewMatcher(AvailableLanguages), lang)

Or index represents 0 for language.English and 1 for language.BrazilianPortuguese. First we use the subdomain language (like en-us.meusite.com), but if not there is a subdomain (like meusite.com) we will use the language of the browser. So when loading the page just do one:

for _, el := range t.QuerySelectorAll("[data-text]") {

    text, ok := Dicionario[el.GetAttribute("data-text")][index]
    if !ok == "" {
        logs.Warn("Não encontramos textos para " + el.GetAttribute("data-text"))
    }

    t.SetText(el, text)
}

The idea of this code is to get all data-text and replace. So if there is data-text="welcome" it should take the text that is on the map of dicionario. So dicionario["welcome"][0] will be English, and dicionario["welcome"][1] will be Portuguese.

This has some limitations, such as date or plural formations. For example, in Brazil, we use DD/MM/AAAA, while in other places it is MM/DD/AAAA. a way to mitigate this is by using an international standard, but this can be strange in some cases.


On the performance side, there is a way to mitigate the impact. Once you have to find all the data-text and then perform the insertion of the text, you can use the HTMLTemplateElement (the <template>) or the HTMLSlotElement (the <slot>). These two elements are not rendered except when started. This indicates that all data-text inside it will not be translated and will not be obtained. So each time you display a template you will have to translate the text contained in it.

This reduces the impact, since only what has been initiated will be translated. So only what the user sees will be translated, it will not waste time translating what the user will not see.


Already on the SEO side, you can perform the same of JS on the server side. The goal here is simple. When the user accesses en-us.site.com the bot will already see the content in English, so all data-text already they will be filled in advance, even if the client does not have Javascript.

For this, it is possible to create, in my case, a http.Handle, in it will execute a code using htmlquery, which uses XPATH. It then creates a file index_en_us.html and index_pt_bt.html, both of which have the content OS data-text already filled in and already previously stored.

When the user accesses en-us.site.com it will be served by index_en_us.html. However, if he clicks on "English", the effects are immediate and you do not have to wait for a request for pt-br.site.com, since translation can also be done on the client.

if you use NodeJS you can do the same thing, maybe even reuse the client code on the server.

When the user accesses the default page, site.com, he will be served with index_en_us.html. However, the content will be translated on the client side, based on the browser language.

You could also read the header of Accept-Language, on the server, and give a content with the best language. However, many CDNs (such as CloudFlare) do not respect Vary. So even if you return a header of Vary: Accept-Language, to indicate that the content is different depending on the Accept-Language, they keep giving the same result for any request. So I preferred to send the default content and the client, in Javascript, translate. The translation on the client side is positive because it is immediate, so the user can switch the language whenever he wants, without having to wait.

 0
Author: Inkeliz, 2018-12-22 13:44:38