…or anything, really

One issue you will face if you need to make a multi-lingual site is how to keep your translations organized for both your back-end framework and your javascript components. I’m going to demonstrate the basic technique for this, using Laravel and Vue.js for my example.

What is this?

You should know right off the bat that the technique I’m showing is completely framework — and even language — agnostic. The idea behind it would work just as well for a .Net app fronted with Ember.js, for example.

I’m writing this at two levels, so you are free to read according to what you need to get out of this. If you are simply looking for a solution for your Laravel and Vue app, go ahead and look at the code boxes. If you read the paragraph above about .Net and are scratching your chin, we’ll explain a little deeper what we are actually doing in addition to working with the code libraries themselves.

Overview of the Process

First let’s look at what we are building, and why. The goal here is to have a single source of translation strings that can be used in our back-end language view files (Laravel blades) and also our front-end framework components (Vue). While it might feel easier to just have php files for one and a json file for the other, keeping the translations up to date is going to be much simpler if we go with a single source. However, the two languages can’t really talk to each other directly, so we need to build a bridge of sorts between them.

This means we need the following components:

Our .php files that keep our translations in a set of key-value pairs (aka, arrays) A service that will convert those files into something Vue can read A service to read that converted output and make it possible to import into the Vue component Some additional standard Vue code to make it easy to actually work with and display

The Backend Translation Files

The first bit comes with our Laravel framework — Localization or “lang” files, as they are commonly referred to. https://laravel.com/docs/5.5/localization . I won’t spend very much time on this as it’s already quite simple and well-documented above or in numerous tutorials. I would recommend making a “components” directory inside each language directory (ie, /resources/en/components ) for reasons you’ll see next.

The php files are convenient for staying integrated with the rest of our system, and perhaps using a third-party api for maintaining the translations themselves, but they are php files and have to be converted to something that is javascript-readable for the Vue components. There are different options for this: if you have a very small site you may find it simpler to create a Vue prop and pass a subset of values in to the appropriate pages, in the same way you would with other initialization data. That will get messy to handle very quickly, however.

Making a Single Translation File

The option we are going to use is to convert them all to a single javascript file we can later import into Vue. There are many good libraries out there for this; if you are working with Laravel, you might like Laravel-JS-Localization which works with all versions of Laravel. This is only converting the php to a js file, so it still doesn’t matter if we are going with Vue or Angular or anything else on the front end. Likewise, if you are not using Laravel you want to find (or make) an equivalent library to do this conversion (ex. a “CakePHP-JS-Localization” that would understand CakePHP’s system of translation files).

Configuration for this library is very simple, but I’ll just mention a couple of things I found when I set this up. The file config/localization-js.php has two configurations available; messages holds which files you want included in this translation file, so only list the php lang files for your Vue components. path is where that file will be made, so you’ll want to put it in your assets if you are using gulp or something. I might also call it something more clear than “translations” or “messages” to not get it confused with your other code. I used:

/*

* The default path to use for the generated javascript.

*/

'path' => resource_path('assets/js/vue-translations.js'),

To run this we’ll use the command ‘artisan lang:js — quiet — no-lib’ (those are normal commandline arguments with hyphens; Medium has decided not to let me type the way I want to today)

Each time that you add or change translations in the components subdirectory you’ll need to recompile this, because it is the vue-translations.js file that is actually being read into Vue, so this needs to be recreated. Depending how often you do this, you may want to add that command into your asset compiler (gulp, mix, whatever). It is very quick and won’t add much time to your builds.

Bringing it into Vue.js

If you look inside the vue-translations.js file what you’ll see is a big json dump of all the en/components/*.php files it read. So we next we need some sort of parser that can read that json and pick out the single translation we are after. To this we’ll use https://github.com/rmariuzzo/lang.js , which was actually written first and then the bridge to Laravel and other frameworks was built.

So, once again to be plain what we are doing — vue-translations.js is a standard format that Lang.js can understand and read from. It doesn’t matter how we get our translations into that format, just that we do so in order for Lang.js to use its own functions to read it. That’s why I said it doesn’t matter what framework or even programming language you start from. (You could write it all out by hand if you are masochistic enough).

Now we are on to step 3 — importing the Lang.js library into our own front-end code (in this case, Vue). The library itself has a simple api and uses lang.get('greetings.hello') style functions, but we want to import it into Vue for easy use in our components.

Looking at our main.js file (or whatever you call your “global” file for all the components to work from), we can create a custom filter like below:

Lang.js itself has a lot of nice functionality for doing things like pluralization you might want to look over in the docs, but this will suffice for our needs.

Finally — let’s put this on our page!

Add to the Vue.js Components

Our basic filter in Vue will work like this:

Notice the syntax for what will be, in Laravel, a file named “Faqs.php” in a subdirectory called “components” inside of “en” or any other language group. “question” is the original array key. The string ‘components/Faqs.question’ is piped into the trans filter with no arguments in this case and trans() will tell Lang.js to go find this key in vue-translations.js.

That’s the whole process. It seems a little complex at first, but to review what we are doing:

Create normal lang files in Laravel (ex. /en/components/Faq.php) Convert that to a single javascript file (vue-translations.js) Use Lang.js to read that json and pick out the key:value we need Create a Vue.js filter to easily use Lang.js functions in our components

So in the end we are left with a single source of translations we can import into any third-party service for translations.

Hope that helps!