Laravel translation tutorial: How to translate your web app

Andreas Löw
Laravel translation tutorial: How to translate your web app

This tutorial is here to get you started with Laravel translations. It covers all information you need for a quick start:

  • Preparing your web app for translations
  • Creating & managing translation files
  • Displaying translations in code and Blade templates
  • Pluralization and parameters in translated texts
  • Creating localized routes
  • Best practices for translation files

The tutorial starts with a new, clean project to show the different topics. But you can of course use your existing project instead.

Setup your Laravel project

I assume that you already have basic knowledge about Laravel. Please take a look at the laravel documentation if you need help to get started.

Use these commands to start a new empty demo project for this tutorial:

laravel new laravel-translation-demo
cd laravel-translation-demo
cp .env.example .env
php artisan key:generate

php artisan serve

Now visit http://127.0.0.1:8000 and see the default application screen.

New laravel project

Translating Blade Template files with __()

Open resources/views/welcome.blade.php and scroll to the bottom of the file.

Replace the content block with the following lines:

<div class="content">
    <div class="title m-b-md">
        {{ __('welcome.title') }}
    </div>

    <div class="links">
        <a href="https://laravel.com/docs">{{ __('welcome.menu.documentation') }}</a>
        <a href="https://laravel-news.com">{{ __('welcome.menu.news') }}</a>
    </div>
</div>  

__() is the translation function. It takes a translation ID and optional parameters and replaces them with translated strings.

Translating strings within your code

You can also access the function within your php code — for example:

echo __('messages.welcome');

If no translation is found, the message ID is used instead:

Translations with default text

Laravel translation files and message IDs

The translation ID is a string that can be freely defined in your project. Dots separate different parts of the ID — allowing you to structure the translations.

The substring before the first dot is the filename in which the translation is located.

Laravel looks for translations in the resources/lang/<languagecode>/<filename>.phpfile.

E.g. the english translation for welcome.menu.documentation is retrieved from the file resources/lang/en/welcome.php.

Using multiple dots allows you to structure the translations within a file.

Create the resources/lang/en/welcome.php file and paste the following content in it:

<?php
return [
    'title' => 'Translation demo',
    'menu' => [
        'documentation' => 'Documentation',
        'news' => 'news'
    ]
];

Refresh the app to see the english translations.

The loader for Laravel php files is quite restrictive. It only allows one single return statement with an array of translations. No variable definition or other code is permitted. Comments in the file are ignored but not written back on save.

Laravel project translation

Maintaining translation files with BabelEdit

Maintaining these files for you as a developer is easy — but it's hard to exchange data with a translator. Most translation agencies are quite unhappy if you give them .php files for editing... several of them won't even accept the files at all.

This is why we've created a specialized editor to help you with this: BabelEdit.

  • Work with multiple translation files and languages at once
  • Simple UI with good usability
  • Easy exchange with translators: Export and import translations for Excel, Google Spread Sheets and other formats translators accept
  • Add comments and directions for the translators
  • Approval process for translations

To get started with BabelEdit download it from here: Download BabelEdit

Click the Laravel button to create a Laravel project:

Laravel project translation

In the next screen click Scan and select the resources/lang directory. BabelEdit searches the directory for translations and asks you to confirm the languages. Click Ok if you are happy with the selection.

Adding the current laravel project for translation

After opening the project you should see a screen with your translations:

  • The left tree containing the translation IDs
  • The right part with the translations
Editing the current language of your laravel project

Adding a new language and translating the messages

Adding a new language is easy:

Adding a new language to your laravel project
  1. Click the Languages button
  2. Click Add
  3. In the file dialog click New folder
  4. Name the folder de and click ok
  5. Set the language (German should be pre-selected)

Back on the main screen you should now see text fields for the new language.

Translating your messages

Click Save Project. BabelEdit asks you for the file name of its project file. Name it laravel-demo.babel and store it in your project folder. The babel file stores the project configuration.

Save also writes the new php files for the German translation.

Adding a route to switch between languages

The current locale has to be set before the view is rendered. This can be done using App::setLocale($locale). A good location for this is in the routes/web.php:

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

This creates separate routes for each language:

  • http://127.0.0.1:8000/en for the English version
  • http://127.0.0.1:8000/de for the German version

The localized routes are good for public pages that can be indexed from search engines. E.g. google will find an English version and a German version of the page.

You can also store the current language in a cookie, user preferences or use the browser's language settings if you don't want to create separate routes. I'd not recommend doing this for public pages because it might now work well for SEO. It should be fine for pages that can only accessed for logged-in users.

Default and fallback language

The default language of the app is set in config/app.php as locale. The default is en.

You can also set the fallback_locale — it's the language that is used if the requested translation is not found. Default is en.

Parameters

You can add parameters to the translation strings with the following code:

echo __('messages.hello', ['name' => 'Andreas']);

or

<h1>{{ __('messages.hello', ['name' => 'Andreas']); }}</h1>

Set the translation string for messages.hello to

LanguageString
deHallo :name
enHello :name

You can also make the first character of the placeholder uppercase or the whole string uppercase: For the value 'andreas' you'll get the following messages

Translation stringResult
Hello :nameHallo andreas
Hello :NameHello Andreas
Hello :NAMEHello ANDREAS

Pluralization

Pluralization allows you to select different strings depending on parameters. Use the trans_choice() instead of __t() when selecting the translation.

The method takes 3 parameters:

  1. translation id
  2. a number that's used for the selection
  3. the parameters
{{ trans_choice('welcome.likes', 1, ['user_count' => 1]) }}

Add a |-character to separate the singluar and plural form in your translation:

:user_count user likes this.|:user_count users like this.

You can even create more fine-grained translations by providing ranges at the start of the string:

{0} Nobody likes this|[1,19] Some users like this|[20,*] Many users like this

Using Translation Strings As Keys

Laravel also offers the option to use JSON files (which can be edited with BabelEdit, too) with substrings.

I don't recommend using these because these files can't be structured and become a mess when your project grows.

Another disadvantage is that if you change the main language, you'll also have to update all translation files with the new string.

The JSON files also lack context. It might be that you have to translate the same string differently for a label and a title because of the amount of space that is available for the title is does not suffice. You can't do that with the JSON file.