loading...

I18N in Vue Components for ASP.NET MVC apps

keco39 profile image Kevin Cocquyt Originally published at Medium on ・4 min read

I18N (internationalization) may not a big deal when you need to write English-only apps but in my bilingual country, leaving that aspect out is never an option. As I’m working with Vue a lot lately, I tried to create my first form with translated labels.

The technology used is ASP.NET MVC so no Webpack and no use of plug-ins and this is what I found 100% of the time when searching for ‘Vue + i18n’: the usage of a plug-in.

After reading the source code for that plug-in on GitHub, I created something I could use for my MVC projects. What came back a lot, in the different articles I found about it, was the use of a filter to show translations for a given label and that’s what I went with and will describe in the second part of this blog-post.

You may remember my first blog-post describing the creation of a Vue-component. If not, you may want to read that one first: https://medium.com/@kevin_cocquyt/vue-components-in-an-asp-net-mvc-app-e9eb0004c054

Step 1 — Creating a component

I created a component containing a title, a table element with header-elements and one row with data. As the header labels need to be translated, a default value is used followed by a filter in which the right translation for a given label is retrieved. That filter is then specified within the component itself and within that function, a list of translations is searched for the label that was passed as a parameter and, when found, the value-property for that list-item is returned, otherwise, the passed value (the value before the pipe-symbol) is returned. I need to pass the ‘ml’-list (more on that later) for each call to the filter as filters do not allow the usage of data-properties within them (meaning ‘this.ml’ only returns a null instead of the actual value, ‘ml’ stands for multilang in my case).

I could have named my component ‘vue-table-component’, which would be more appropriate but I’m too lazy to change my screenshots (and it’s 11PM already) :)

using a filter to find the right translation, defaulting to the initial value

Step 2 — Registering the component

Registering is necessary for two things: the first is making sure you can use the component in your HTML and second, you need to be able to refer to that component to be able to pass in the translations.

registration of the component

Step 3 — Passing in the translations

As the component was registered and assigned to a variable (can be let, or even const instead of var), you can now refer to the data-properties of that component.

The ‘main’ div is registered as the element in which the component will be loaded. ‘vue-form-component’ is the name of the created component. ‘title’ is a data-property and ref is the ‘reference name’ that can be used within your JavaScript or TypeScript (main.js is the file that contains the creation and registration).

At the bottom, an array of objects is assigned to the ‘ml’-property with two properties per object, each one appropriately named but you can name them in any way you like, as long as you then change the filter-function accordingly.

passing a list of translations

These look like fixed values of course but, for example, in my professional projects, I use an MVC HTML-extension like @Html.Translation(“number”) meaning the right translation will be retrieved from our database (using the set language) so one or your added objects could then look like:

{ name: “label.number”, value: “@Html.Translation(“number”)” }

Make sure the strings that come back from your database are encoded as they will be used within scripting (single/double quotes).

After passing the translations to the referenced property, the multilang-labels are known within your component and searchable via the filter-function.

Result

In the rendered HTML, only the second and third labels were translated whilst the first label, as there was no translation in the ‘ml’-list for it, only displays its default value (the string before the pipe-symbol).

HTML rendering

And that’s it.

Thanks to the writers of the plug-in and the ones of the articles I found to push me in the right direction, and thanks to myself for coming up with a passable solution, so I can sleep again at night (yes, these types of things keep me up!)

Thanks for reading!

PS: This is A solution, so I guess not THE solution, so if there are better ones for this scenario, please share yours in the comment section.

EDIT: Internet Explorer can be a real pain for web developers. It's at it again as it doesn't support the array.find() method. For that, inject the pollyfill script (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) somewhere in your JS and you're good to go. Or use lodash (https://lodash.com).

EDIT 2: As I’m still learning the in’s & out’s of Vue, I learned about global filters and thought it was awesome. For that, I tried to implement this for my translations and it worked like a charm! What I did is creating a new file called ‘component-filters.ts’ with the following code:

/js/component-filters.ts

And add that script-file to the bundle:

bundling

Then just remove the ‘translation’ filter from the component and everything keeps on working.

Discussion

pic
Editor guide