Laravel framework has quite a simple localization function – you can put language translations in resources/lang folder. But it’s not convenient to edit them in the code, so there are many packages that help make this process more effective. Let’s review the most popular ones.

First – how translations work in Laravel

Let’s start with recap of the basics – how you can use translations without any packages.

Basically, four things:

1. Language folders

You create your language folders in resources/lang – for example, resources/lang/en and resources/lang/de.

2. Language files

In each of those folders you create a file or files where you store arrays of translations in key-value mode.
Same file in different language folders should have the same filename.

Example – resources/lang/en/words.php:

return [
    'page_title' => 'QuickAdmin page',
    'page_description' => 'Best page in the world'
];

Example – resources/lang/de/words.php:

return [
    'page_title' => 'QuickAdmin Seite',
    'footer'     => 'Beste Seite der Welt'
];

3. You define current active language, otherwise called ‘locale’

It should be one of your folder names – in this case, ‘en’ or ‘de’.
First, there is a default setting in config/app.php:

'locale' => 'en',

But you can override it by setting the local like this anywhere in your code:

App::setLocale($locale);

Also, you can define the locale according to the routes, like this:

Route::get('welcome/{locale}', function ($locale) {
    App::setLocale($locale);
});

4. Actually using the translations in Controller or View

To view the actual word from the translation file or assign it to some variable, you should call function trans():

trans('words.page_title');

Depending on the locale you have set, the system will return ‘QuickAdmin page’ or ‘QuickAdmin Seite’. The parameter of trans() function is a string that consists of two parts – filename, then dot symbol (.) and then array key that you want to use. In our case – words and page_title.

More about general localization – in the official Laravel documentation.

Now, how can we make it more convenient? Let’s get to the useful packages.

For each of the packages, I will provide URL, author, downloads (according to Packalyst) and the dates of first and last releases. I think it’s really useful, judging about package’s popularity or how well it is maintained.


1. barryvdh/laravel-translation-manager

URL: https://github.com/barryvdh/laravel-translation-manager
Author: Barry vd. Heuvel
First release: June 1, 2014
Last update: December 22, 2016
Downloads: 110 000

This is one of the oldest translation managers, and the only one in this list with a graphical interface. Basically, that’s what you get with this package – an adminpanel where you can visually edit your translations (temporarily saved in the database) and then sync with Laravel files.

Typical workflow:
– Import translations: Read all translation files and save them in the database
– Find all translations in php/twig sources
– Optionally: Listen to missing translation with the custom Translator
– Translate all keys through the webinterface
– Export: Write all translations back to the translation files.

Here’s how it looks visually:

barry-translation-manager

So you can go to translate your constants via URL /translations, which is by default not guarded by any password but you can do it quite easily. Or, alternatively, there are a few Artisan commands:

php artisan translations:import

The import command will search through lang files and load all strings in the database, so you can easily manage them.

php artisan translations:export [group]

The export command will write the contents of the database back to lang php files. This will overwrite existing translations and remove all comments, so make sure to backup your data before using. You can also divide translations by groups, and supply the group name to define which groups you want to publish.

This approach is quite convenient, and it solves quite a big problem – giving the clients a convenient way to edit the translations without any help of the developer, except for publishing it back to the Laravel app.

That said, I would be cautious with such automatic import/export and would make a backup of files before any overwrite, as the author says himself.


2. themsaid/laravel-langman

URL: https://github.com/themsaid/laravel-langman
Author: Mohamed Said (recently became first full-time hire at Laravel)
First release: April 2, 2016
Last update: September 5, 2016
Downloads: 14 000

As I mentioned, the package above was the only one with graphical interface, so now we will review a few managers based on Artisan commands.

I have respect for the author of this package, for several reasons. First – the demo of the package, in the official documentation, is available in GIF format! So you immediately see what you can do with Langman, without installing it or even reading the rest of Readme. How cool is that!

themsaid-langman

For those who cannot see this GIF or prefer text-based information, I will list the Artisan commands this package offers:

  • langman:show users.name – Shows only the translation of the name key in all languages.
  • langman:find ‘log in first’ – You get a table of language lines where any of the values matches the given phrase by close match.
  • langman:sync – will look into all files in resources/views and app and find all translation keys that are not covered in your translation files, after that it appends those keys to the files with a value equal to an empty string.
  • langman:missing – will collect all the keys that are missing in any of the languages or has values equals to an empty string, prompt asking you to give a translation for each, and finally save the given values to the files.
  • langman:trans users.name – set a language key (plain or nested) for a given group.
  • langman:remove users.name – removes that key from all language files.
  • langman:rename users.name full_name – will rename users.name to be users.full_name, the console will output a list of files where the key used to exist.

Notice from the author: commands will update your language files by writing them completely, meaning that any comments or special styling will be removed, so I recommend you backup your files.

So, basically, if you prefer Terminal commands instead of editing PHP files in your IDE, this package is for you.


3. PhiloNL/laravel-translate

URL: https://github.com/PhiloNL/laravel-translate
Author: Philo Hermans
First release: January 5, 2014
Last update: August 5, 2016
Downloads: 17 000

Another package with useful Artisan commands. This one by Philo Hermans has these commands:

php artisan translate:add [group] [line]

This command will prompt you for translations for all the languages you have, and then will write those into lang files. Also will show you a Blade syntax so you could copy-paste into your views immediately – quite convenient.

philonl-add

php artisan translate:remove [group] [line]

The opposite command – to remove translations.

php artisan translate:cleanup

The clean up command will search your files for language strings which are no longer used.
Foreach line that was not found, you will get a confirmation if you want to delete the line in question. In case you you don’t want to confirm each line, you can add the –silent parameter.

philonl-cleanup

So it’s a similar package to the above one, just with less functionality.


4. potsky/laravel-localization-helpers

URL: https://github.com/potsky/laravel-localization-helpers
Author: Raphael Barbate
First release: June 10, 2014
Last update: November 10, 2016
Downloads: 26 000

This is an interesting and a simple one. It’s a set of three Artisan commands which check for missing translations and generate lang files for you:

  • localization:find – Display all files where the argument is used as a lemma
  • localization:missing – Parse all translations in app directory and build all lang files
  • localization:clear – Remove lang backup files

So it doesn’t actually help you in translating, but finds missing pieces for you, which is still solving a part of the problem.


5. dimsav/laravel-translatable

URL: https://github.com/dimsav/laravel-translatable
Author: Dimitrios Savvopoulos
First release: February 11, 2014
Last update: December 22, 2016
Downloads: 204 000

Ok, we’ve covered the translation of constants from lang files. What if we want translatable Models, like multi-language product catalog or a blog. Here’s one of the biggest package in this list – in terms of downloads: 204k is really impressive, comparing that Laravel framework has 4 million.

Basically, this package works like this:

  • For every model you create additional database table with name [model]_translations and model [Model]Translation
  • Your main model should use Trait of the package and has a property $translatedAttributes
  • Then you can get translations with a code like this:
$greece = Country::where('code', 'gr')->first();
echo $greece->translate('en')->name; // Greece

Also you can fill in the translations like this:

$greece->translate('en')->name = 'abc';
$greece->save();

Now, if you want to do something custom like searching for specific string in specific language, or order by translation value, you need to write Eloquent queries, like this one:

Country::join('country_translations as t', 't.country_id', '=', 'countries.id')
    ->where('locale', 'en')
    ->groupBy('countries.id')
    ->orderBy('t.name', 'desc')
    ->with('translations')
    ->get();

There are more useful methods available, like translateOrDefault(), hasTranslation(), scopes like translatedIn() etc. To be honest, this package would deserve a separate review, so we will leave it for you to read the whole Readme file.

All in all, I’m not surprised this package is so popular. It even has its tutorial on the official Laravel blog Laravel News and two packages created additionally by the community:


6. spatie / laravel-translation-loader

URL: https://github.com/spatie/laravel-translation-loader/
Author: Spatie and Freek van der Herten
First release: October 5, 2016
Last update: January 2, 2017
Downloads: 830

A newcomer package, but since it’s created by company Spatie, who created around 100 Laravel packages with quality – I back it up by adding it to the list.

There is a short tutorial about this package, written by the author on his popular blog, but I will summarize it for you.

Basically, all the package does is storing the translations in the database and using LanguageLine model to manage them.

So if you want to store all your resources/lang contents in the database, you should create line-by-line, like this:

use Spatie\TranslationLoader\LanguageLine;

LanguageLine::create([
   'group' => 'validation',
   'key' => 'required',
   'text' => ['en' => 'This is a required field', 'nl' => 'Dit is een verplicht veld'],
]);

And then, whenever you call trans(‘validation.required’); – the package will check, if there is a value in the database, if not – then will load the translation from resources/lang/[locale]/validation.php file, as usual.

Also, the package allows you to create your own storing methods and extend the functionality.


7. Waavi / translation

URL: https://github.com/Waavi/translation
Author: Waavi web development studio
First release: November 25, 2013
Last update: November 14, 2016
Downloads: 13 000

This package does quite a lot – it has a set of functions. To be honest, it is quite hard to read the documentation and understand it all at once. But let’s break it down.

Translations source

This package allows you to load translation from the regular Laravel localization files (in /resources/lang), from the database, from cache or in a mix of the previous for development. You may configure the desired mode of operation through the translator.php config file and/or the TRANSLATION_SOURCE environment variable.

If you choose database method, you would have to run package migrations and then command php artisan translator:load to load the files into the database.

Also, it allows to store translations in cache and load from there – for this you would use constants like TRANSLATION_CACHE_ENABLED, TRANSLATION_CACHE_TIMEOUT and TRANSLATION_CACHE_SUFFIX.

Translation repository

Package has its own Repository class \Waavi\Translation\Repositories\LanguageRepository to manage the translations.

With this repository you would be able to find and update the translations, search for available locales and even query the percentage of locale translations finished.

Model attribute translation

This package is also suitable for model translations – you just need to add array property $translatableAttributes to your model, and within migration add fields with suffix _translation. Though, to be honest, I don’t understand how the package stores different languages values in the same database table, but I guess if you play with this package, you will find out.

URL localization

Finally, you may use Waavi\Translation\Middleware\TranslationMiddleware to make sure all of your urls are properly localized. The TranslationMiddleware will only redirect GET requests that do not have a locale in them.

So there you go – a lot of functionality in one package, right?


8. mcamara / laravel-localization

URL: https://github.com/mcamara/laravel-localization
Author: Marc Cámara
First release: January 19, 2014
Last update: December 31, 2016
Downloads: 246 000

The biggest amount of downloads in this list – you can call this package a champion. Basically, it takes care of multi-language routing, URLs and Middleware.

Here’s how your routes/web.php file should look:

    Route::group(['prefix' => LaravelLocalization::setLocale()], function()
    {
        /** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/
        Route::get('/', function()
        {
            return View::make('hello');
        });

        Route::get('test',function(){
            return View::make('test');
        });
    });

    /** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/

Once this route group is added to the routes file, a user can access all locales added into supportedLocales, which is set in configuration.

Also, you can use Middleware to redirect all “non-localized” routes to the corresponding “localized”:

    Route::group(
    [
        'prefix' => LaravelLocalization::setLocale(),
        'middleware' => [ 'localeSessionRedirect', 'localizationRedirect' ]
    ],
// ...

The coolest feature of the package, in my opinion, is Translated Routes – for example, you want to have URL /en/article/5 for English language, and /de/artikel/5 for German language. I mean, different slugs here. It’s possible with this package!

    Route::get(LaravelLocalization::transRoute('routes.view'),function($id){
          return View::make('view',['id'=>$id]);
    });

Finally, there’s a big set of helpers and functions like getLocalizedURL(), getURLFromRouteNameTranslated() and others. So you can call the helpers directly from your views to form the correct links or redirect to the intended page.

So this is a really nice package overall – no wonder it’s so popular.


9. nikaia/translation-sheet

URL: https://github.com/nikaia/translation-sheet
Author: Nassif Bourguig
First release: September 4, 2016
Last update: October 13, 2016
Downloads: 265

A new package with a brilliant idea – a different approach to manage translations. The package uses… Google Sheets! Basically, developers export all the constants to Google Sheets, then translators/clients do their job, and then developers import the words back into the system. Convenient!

Workflow looks like this:

  • You create Google application via Developer Console, create a Google Sheet and put the credentials and Sheet ID into Laravel config file
  • And then you run Artisan commands: translation_sheet:setup + translation_sheet:prepare + translation_sheet:push will publish translations to the sheet
  • Then translation_sheet:lock locks the sheet from further changes
  • And then translation_sheet:pull will pull it back into Laravel project

There are also a few more helping Artisan commands, but in general it’s that simple.


10. xinax/laravel-gettext

URL: https://github.com/xinax/laravel-gettext
Author: Nicolás Daniel Palumbo
First release: October 9, 2014
Last update: December 13, 2016
Downloads: 53 000

The last package on the list (oh wait, there are a few bonuses, read on!) is designed to work with GNU gettext and Poedit.

First thing you do after installing this package is configuring your supported locales in config file, and hten running php artisan gettext:create command, which generates the directory structure and translation files for the first time – in resources/lang/i18n.

Then you can use translations like this:

echo __('Translated string');  // Reminds of WordPress, doesn't it?

Example view in Blade file:

{{ __('Translated string') }}

Also, there are additional Gettext functions – like this one for plural:

{{ _n('Translated string', 'Translated plural string', $n) }}

You can edit your translations with Poedit – just use the files from here:
resources/lang/i18n/[locale]/LC_MESSAGES/[domain].po

Finally, package provides methods to get/set active locales, change settings folders in config files and handling the routes – you can read it all in the official Readme file.

All in all, I would recommend this package if you’re familiar with Gettext and Poedit – then you don’t need to change your workflow too much.


Bonus: JavaScript packages

While searching for packages, I’ve stumbled upon two interesting ones related to JavaScript. Won’t review them here, but they perform pretty much the same thing – loading your translations into JavaScript code. Here are the links:


Conclusion: Is there the best package?

The packages may be divided into categories, so let’s start with Translation Managers. There’s no winner here – every package in the list has some different approach to translations or various use-cases, you just pick the one suitable for your workflow: whether you like to translate things via Web, Artisan, Google Sheets or Poedit.

Next, multi-language Models. The clear leader in this space is definitely Laravel Translatable, backed up by 200k+ downloads.

Finally, the best (by far) package for handling routes and middlewares for multi-language project is Laravel Localization, also trusted by more than 200k users.

Are there any packages I’ve missed? Or maybe you have some comments about any of the ones mentioned in the list?