Translation of static website content into 4 languages

Asked

Viewed 2,314 times

13

What tool have you used to release the option of translating content from a static HTML site to another language? Some jquery plugin, some api? What is the best practice currently aiming at performance?

Would it be ideal to use something that captures the user’s IP and upload a page already translated in the language to that country?

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

2 answers

1

You can do all translation via Gulp, it has interesting i18n modules https://www.npmjs.com/package/gulp-static-i18n

You need a module in Gulp that reads your text or html elements with a data/class attribute and that this module plays everything on a json or file. mo(very used for translation)

And another task to build the translations, duplicate the htmls and swap the texts, so you could upload everything on a static server type S3 of Amazon, which has low cost and so you do not need a server/backend to translate text, is scalable and fast.

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

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

0

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

<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 make searchers already show the content in the right language, in most cases.

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


This is the first time I try to make a site with multiple languages, so what I’m going to write here is what I’m doing, but it wasn’t "tested in production" and maybe there are other problems in this method.

I am 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.

What I’ve done is simply:

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

Then, when starting the page, the client’s language is obtained, using the 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 what content to display, I use the text/language, you should find someone else for Javascript. That 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)

The index represents 0 for language.English and 1 for language.BrazilianPortuguese. First we use the Domain language (such as en-us.meusite.com), but if there is no Ubdomain (such as meusite.com) we will use the browser language. So when loading the page just do a:

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 the data-text and replace. So, if there is data-text="welcome" he must pick up the text that is on the map of dicionario. So the dicionario["welcome"][0] will be the English, and the dicionario["welcome"][1] will be the Portuguese.

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


On the performance side, there is how 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 within it will not be translated and will not be obtained. So each time you display a template will have to translate the text contained in it.

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


In the SEO part, 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 will already be completed in advance, even if the client does not have Javascript.

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

When the user accesses en-us.site.com he will be served by index_en_us.html. However, if you click on "English", the effects will be immediate and you will not need to wait for a request for the pt-br.site.com, since the 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 the 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 content with the best language. However, many Cdns (such as Cloudflare) do not respect the Vary. So even if you return a header from Vary: Accept-Language, to indicate that the content is another depending on the Accept-Language, they continue to give the same result for any request. Therefore, I preferred to send the default content and the client, in Javascript, translate. The client-side translation is positive because it is immediate, so the user can switch the language whenever they want, without having to wait.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.