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.
Making a Single Translation File
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:
'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)
- 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!