4

I'm currently struggling with the problem of multilingualism in an SPA.

I've come up with several solutions, like building a wrapper for the resources resx files, or saving all labels in the database, but I am wondering if any of you have found some solution which automates these steps.

Are there any practices which are specific for this problem?

Peter R
  • 364
  • 2
  • 11

2 Answers2

2

For a reasonable amount of literals, I suggest to save the resources in the DB or in a .RESX file in the server. When the user logs in or you detect the language that will be used, the literals are requested by the application and saved either in a collection of your translation module or in the LocalStorage of the browser (this could be a good approach for large data). Then this module could have some methods to retrieve the messages, probably passing a key.

Using this solution you could inject this module in the viewmodels that need to show translated literals and acces them through the view:

<p data-bind="text: resourceManager.get('M01')"></a>

For large applications that would require huge localization data to be transfered, maybe some kind of modularity could be applied and only load the resources really needed for each module/section.

I don't think making recurrent requests to the server to get the translated literals is a good practise. SPA's should provide a good user experience and loading the translated literals from the server could be a blocking issue. Text is not like an image, you can render a page without all the images loaded, imagine rendering a page without the text :o

Anyway, I think the best solution would be to keep the server as repository and create a custom JS module that takes care to get data in one or multiple loads and is able to store it somewhere in the client.

margabit
  • 2,924
  • 18
  • 24
1

I've solved my own problem, using a custom binding and i18next.

First, I've implemented i18next for translation of my labels/buttons and other resources.

Secondly, I've added a custom Knockout bindingHandler:

ko.bindingHandlers.i18n = {
    init: function (element, valueAccessor) {        
        var translateKey = valueAccessor();
        ko.utils.setTextContent(element, $.t(translateKey));
    }
};

Finally you can add the following code to your views:

<span data-bind="i18n : 'buttons.cancel'"></span>

This will automatically get the correct resource, and Knockout will handle the bindings.

Hopefully this will help others struggling with the same problem.

Peter R
  • 364
  • 2
  • 11