These days, when we need something, the first instinct is to turn to the web and search for it. The chances are very low that we will open a book or ask a person about what we are looking for. Through the internet we have access to the biggest bank of information and it is at hand to find anything we need. It often happens that the user doesn’t find what he needs in the languages he knows. It’s very unlikely that he will try to get the information from a website in an unknown language and maybe he will just give up. Nowadays, the internet is used by more than 7.7 billion people and in the world there are roughly 7100 languages. They say English is the most used language in the world, but only 25.9% of internet users were native English speakers as of March 2020. Furthermore, if you think that the majority of people speak English - you might be disappointed. To illustrate, only 39% of people in France speak English. The figure is even lower in other countries. In Italy only 35% of people speak English and less than 23% in Spain. You would expect the percentage to be higher in European countries. In China, for instance, only 0.75% are fluent in English. Therefore, a multilingual business website is crucial if you want to find clients from abroad.

Benefits to build a Multilingual Website

A Multilingual Website opens many doors. It increases the traffic by attracting users who speak languages that you provide. It’s not enough to use a language that the user might know, it’s better to have the website in the local language. Research shows that 72.1% of consumers spend most of their time on websites in their own language. 56.2% of consumers said that the ability to obtain information in their native language is more important than the price. Plus, a website in multiple languages is a sign that your company cares about the needs of your potential customers, which builds loyalty and trust. People tend to feel more comfortable with, and place more trust in brands that offer information in their language. Using multiple languages is very important for improving your multilingual SEO. It will increase the chances that the website will be found in search by targeted users. Google Search is available in 123 languages and the majority of people use their native language when they perform their searches. By attracting more users from different regions you will increase your sales and have a more stable business. If something will negatively affect your business in one region, you will be able to evolve in other regions and also have time and money to improve what went wrong. There are a lot of countries where people speak different languages depending on the region. In the United States, for example, English is the official national language, but a large portion of the population speaks Spanish. Depending on what part of Canada you’re in, the people will speak English, French, or both. In Switzerland, people speak German, French or Italian, depending on where they live. Finally, the main benefit why you should start to add more languages to your website is that it’s cheap and you will win a lot from this.

Converting from Monolingual to Multilingual Website

I joined a project from Switzerland as a developer one year ago. Switzerland has four national languages: German, French, Italian and Romansh.

image

The project was started using only German, which is the main speaking language in Switzerland (62.6%). Currently the app is mainly used by people from the pink region. At the beginning we just had a JSON file de.json where we stored all the keys and translations in German.

{
  "GENERAL": {
    "REFRESH": "Aktualisierung",
    "RESET": "Zurücksetzen",
    "SEND": "Senden",
    "CLEAR": "Löschen"
  },
  "AUTHENTICHATION": {
    "LOGIN": "Anmeldung",
    "REGISTER": "Registrieren",
    "LOGOUT": "Ausloggen"
  }
}

It was our job as developers to add/update/remove keys from this file to manage the translation of the website. In order to target more users, we decided to add French, Italian and English. Having a JSON file for each language would make it difficult and time consuming for developers to manage the translation. It would be better to use a dedicated tool where all the translations could be stored and that could be used by more people. In the beginning we thought about creating our own tool, but we came to the conclusion that this will cost us more than using an existing one. After a detailed research on the existing tools for translations we found out that the best option is Squidex.

Why is Squidex the best option?

  • Pricing
    • it is one of the cheapest options
    • you can use it for free if you have less than 20000 API calls per Month and only 2 contributors
    • the 19€ package with 100000 API calls per Month and 10 contributors could be enough if you have a bigger project
  • It can be self hosted by you for free
  • It has a nice support page
    • they have good customer support
    • they are very fast to fix an issue or to add a new functionality based on customers suggestions. Just asking on the forum ‘how can we do that?’ , they said that ‘this is not possible currently’ and implemented this functionality in the same day. Check here how fast they are.
  • Nice design and easy to use
  • Check here other feature comparisons with competitors.

How switch to use Squidex instead of a JSON file for translation?

  • Go to this page and sign up for free

  • Create the schema, that defines the structure of your content

    • Go to the schema page and create a new one. Choose multiple contents in order to be able to have more content based on this schema

      image

    • You should create the fields for this schema. We need a field for the Key.

      image

    • It should be unique, so let’s edit it.

      image

    • Create the second field Translation where you willl store the translation content. It’s important to mark it as localizable.

      image

    • In order to use this schema you should publish it.

      image

  • Add languages that you need for you app

    By default the English language is there.

    • Add language that you need, we added the German

      image

    • German being the most used in Switzerland, we set it as the master one to be a fallback if there are no translations in other languages

      image

    • Add other languages that you need. Currently we removed the English and added French(Switzerland)

      image

  • Add the content

    • Go to the content based on translation schema that we created. You can select the fields that you want to see in the content table

      image

    • Let’s add a new item

      image

      Complete the Key and Translations for all used languages. You should define the master one manually and can use a button to Autotranslate from master language all languages. It’s nice that Squidex can help us with this, but anyway I recommend that you should have a native speaker that will check all the translations. You can save it as Published or Draft status. Also there is Archived status, but let’s discuss about each one a bit later.

    • Previously having a big JSON file for all translations we had to move the content to Squidex. It would have taken a very long time to add each item manually. Fortunately, Squidex provides an API and you are able to add the content programmatically. You can check more about the API docs on this link https://cloud.squidex.io/api/content/[APP_NAME]/docs. We created an endpoint that accept a JSON file and will add all the items in Squidex.

      • Firstly, in order to be able to access Squidex API you should do the Authentication

        image

      • You must send this token to the Authorization header when making requests to the API

         Authorization: Bearer <token>
        
      • Going through all the items from JSON file you should do a POST to https://cloud.squidex.io/api/content/[APP_NAME]/[SCHEMA_NAME]/ using the authorization and by passing a body with the Key and Translations

        {
          "Key": {
            "iv": "string"
          },
          "Translation": {
            "de-CH": "string",
            "fr-CH": "string"
          }
        }
        
      • Yeeey, all the items were moved in Squidex. So easy and fast .

  • Receiving the content

    Squidex provides an endpoint to get the content items https://cloud.squidex.io/api/content/[APP_NAME]/[SCHEMA_NAME]/. Regretfully, we can get only 200 items per request, but it provides us some query options

    • $top: The $top query option requests the number of items in the queried collection to be included in the result. The default value is 20 and the maximum allowed value is 200.
    • $skip: The $skip query option requests the number of items in the queried collection that are to be skipped and not included in the result. Use it together with $top to read all your data, page by page.
    • $search: The $search query option allows clients to request entities matching a free-text search expression. We add the data of all fields for all languages to a single field in the database and use this combined field to implement the full text search.
    • $filter: The $filter query option allows clients to filter a collection of resources that are addressed by a request URL.
    • $orderby: The $orderby query option allows clients to request resources in a particular order.

    You can read more about queries here. In order to get all the items you can do several calls one after the other to take 200 items per request. To be sure that you will not lose items by doing more requests, you should order them by the Key adding this query option $orderby=data/Key/iv . To know how many request you should do to receive all the items, you will get the total items from the first request.

    {
        "total": 2008,
        "items": [],
        "statuses": [],
        "_links": {}
    }
    

    After that you can do a for by incrementing the $skip with 200 for each request. You can extract the Key and Translation from items -> data .

    {
        "total": 2008,
        "items": [
            {
                "id": "0307a2a9-00c4-45a6-8aa4-45bd4b724284",
                "data": {
                    "Key": {
                        "iv": "GENERAL.REFRESH"
                    },
                    "Translation": {
                        "de-CH": "Aktualisierung",
                        "fr-CH": "Mise à jour"
                    }
                }
            }
        ],
        "statuses": [],
        "_links": {}
    }
    

    In order to retrieve the key easier, you can set the X-Flatten header to true

    {
        "total": 2008,
        "items": [
            {
                "id": "0307a2a9-00c4-45a6-8aa4-45bd4b724284",
               	"data": {
                    "Key": "GENERAL.REFRESH",
                    "Translation": {
                        "de-CH": "Aktualisierung",
                        "fr-CH": "Mise à jour"
                    }
                }
            }
        ],
        "statuses": [],
        "_links": {}
    }
    

    We created an endpoint that will give us the translation content based on the language. Considering that we should do more request to get all the items it can take some seconds. In order for the user not to wait until the translation is loaded, we are using Redis to cache the content. Also, we created an endpoint to invalidate the cache after we did some changes on our content in Squidex. This will increase the loaded speed and reduce number of API calls to Squidex.

    Great, we can retrieve the translation and use it in our web framework.

  • How to use the same content for all the Environments of your app?

    We only have one content and we want to use it on all the environments(locally, staging, production). So, if one developer is working on updating/improving an existing functionality. In this case, it is very possible that translation keys can be modified, removed or added. How can the developer touch the Squidex content in order to test the new functionality locally, without affecting the production? There are 3 statuses that an item can have: Published, Draft and Archived. Using the statuses we can isolate the production environment. There is a specific header X-Unpublished for getting the translation items. We set it to false for production and Squidex will return only the items that are Published. For other environments we set it to true and we will get all the items. Hmm, but how this can help us? Besides the current status of the item, we can create a new status.

    • You want to update the translation for a published item that is already used in production

      In order to not affect the production you can create a new status Draft for that item and update the translation

      image

      image

      image

      On production we will get the previous version Aktualisierung that is Published and on other environments we will get the new Draft version Aktualisierung updated .

    • You want to remove an item that is used in production, but it is not needed based on the new functionality.

      You can create a new status Archived and anyway you will receive the previous value on Production

      image

      image

    After you deploy the new functionality on Production you should also publish the Draft version and delete the Archived items. In order to know which items should be Published/Removed based on the functionality that is released, we decided to add a new filed to our schema TicketID. When we want to update an existing published item, we should add the the TickedId. After releasing to production we can filter the items based on ids of the tickets we deployed, and can Publish or Remove them.

    image

    Having a native speaker that is responsible for each language, he/she should update the translation for items that the master translation was updated. He/she can filter items that have a new status Draft, because this means that the master translation was changed.

    image

Conclusion

I highly recommend you to use Squidex. We had a good experience with this tool by converting our app from monolingual to multilingual. If something is not clear or you have some problems using it, just post your question on the support page or ask me. Have fun using Squidex.

Written by:
Dumitru.png
Dumitru Casap

Demystifying the empire to avoid the devils