How to translate your Laravel project

Andreas Löw

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 and see the default application screen.

New laravel project

Translating the project

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 class="links">
        <a href="">{{ __('') }}</a>
        <a href="">{{ __('') }}</a>

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

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

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 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:

    return [
        'title' => 'Translation demo',
        'menu' => [
            'documentation' => 'Documentation',
            'news' => 'news'

Refresh the app to see the english translations.

Laravel project translation

Introducing 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.

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:

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.

Activating the translations in Laravel

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) {
    return view('welcome');

This creates separate routes for each language:

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.


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

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


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

Set the translation string for messages.hello to

Language String
de Hallo :name
en Hello :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 string Result
Hello :name Hallo andreas
Hello :Name Hello Andreas


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.

Did you like the tutorial? Please share!