How to Build a Multi-Language (Localization) Application in Laravel

Building an application that supports more than one language is an increasingly common need, especially for applications aimed at users from various countries. Laravel has a built-...

How to Build a Multi-Language (Localization) Application in Laravel

Building an application that supports more than one language is an increasingly common need, especially for applications aimed at users from various countries. Laravel has a built-in Localization feature that makes it easy to manage text translations without having to change code in many places. In this tutorial, we'll build an application that can switch between Indonesian and English.

The Translation File Structure

Laravel stores translation files in the lang/ folder. Since Laravel 9, this folder is in the project root. If it doesn't exist, create it with:

php artisan lang:publish

The folder structure we'll create:

lang/
├── en/
│   ├── messages.php
│   └── auth.php
└── id/
    ├── messages.php
    └── auth.php

Creating PHP Translation Files

Create the file lang/en/messages.php:

<?php

return [
    'welcome'       => 'Welcome to :app!',
    'greeting'      => 'Hello, :name!',
    'nav' => [
        'home'      => 'Home',
        'about'     => 'About',
        'contact'   => 'Contact',
        'products'  => 'Products',
    ],
    'product' => [
        'title'     => 'Product List',
        'not_found' => 'No products found.',
        'count'     => '{0} No products|{1} One product|[2,*] :count products',
    ],
];

Create the file lang/id/messages.php:

<?php

return [
    'welcome'       => 'Selamat datang di :app!',
    'greeting'      => 'Halo, :name!',
    'nav' => [
        'home'      => 'Beranda',
        'about'     => 'Tentang Kami',
        'contact'   => 'Kontak',
        'products'  => 'Produk',
    ],
    'product' => [
        'title'     => 'Daftar Produk',
        'not_found' => 'Tidak ada produk ditemukan.',
        'count'     => '{0} Tidak ada produk|{1} Satu produk|[2,*] :count produk',
    ],
];

Using Translations in Blade

Use the __() helper or the @lang directive to display translated text:

<!-- Simple translation -->
<h1>{{ __('messages.welcome', ['app' => config('app.name')]) }}</h1>

<!-- With a name parameter -->
<p>{{ __('messages.greeting', ['name' => auth()->user()->name]) }}</p>

<!-- Access a nested array -->
<nav>
    <a href="/">{{ __('messages.nav.home') }}</a>
    <a href="/products">{{ __('messages.nav.products') }}</a>
</nav>

<!-- Pluralization -->
<p>{{ trans_choice('messages.product.count', $count, ['count' => $count]) }}</p>

JSON Format for Simple Translations

Laravel also supports JSON files for simpler translations — great for long sentences:

// lang/id.json
{
    "Login": "Masuk",
    "Register": "Daftar",
    "Forgot your password?": "Lupa kata sandi?",
    "Remember me": "Ingat saya",
    "Email Address": "Alamat Email",
    "Password": "Kata Sandi"
}
// Usage in Blade (key = the English text)
{{ __('Login') }}
{{ __('Forgot your password?') }}

Setting the Application Locale

The default locale is configured in config/app.php:

'locale'          => env('APP_LOCALE', 'id'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),

To change the locale dynamically at runtime:

use Illuminate\Support\Facades\App;

// Set the locale
App::setLocale('en');

// Check the current locale
App::getLocale(); // 'en'

// Check whether a specific locale is active
App::isLocale('id'); // true/false

Building a Language Switcher

Create a route and controller to change the language:

// routes/web.php
Route::get('/lang/{locale}', function ($locale) {
    if (! in_array($locale, ['en', 'id'])) {
        abort(400, 'Locale not supported.');
    }
    session(['locale' => $locale]);
    return redirect()->back();
})->name('lang.switch');

Create middleware to apply the locale from the session:

php artisan make:middleware SetLocale
<?php
// app/Http/Middleware/SetLocale.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class SetLocale
{
    public function handle(Request $request, Closure $next)
    {
        $locale = session('locale', config('app.locale'));
        App::setLocale($locale);

        return $next($request);
    }
}

Register the middleware in bootstrap/app.php (Laravel 11) or app/Http/Kernel.php (Laravel 10):

// bootstrap/app.php (Laravel 11)
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \App\Http\Middleware\SetLocale::class,
    ]);
})

Add switcher buttons in Blade:

<div>
    <a href="{{ route('lang.switch', 'id') }}"
       class="{{ app()->getLocale() === 'id' ? 'font-bold' : '' }}">
        ID
    </a>
    |
    <a href="{{ route('lang.switch', 'en') }}"
       class="{{ app()->getLocale() === 'en' ? 'font-bold' : '' }}">
        EN
    </a>
</div>

Conclusion

Laravel's Localization feature makes multi-language implementation very structured. PHP files for complex translation groups, JSON files for simple translations, and middleware for managing the locale per session — Laravel provides it all. With this pattern, adding a new language is just a matter of creating a translation folder and files without changing a single line of logic code.

localization laravel multi bahasa laravel laravel translation laravel lang bahasa indonesia laravel language switcher laravel
Read Also

Here are some related articles that might help expand your knowledge:

Share this article
Back to Blog
🚀 Partner Recommendation

Need Premium Source Code & Business Apps?

Access Laravel applications, POS systems, School Management, Clinic Software, ERP solutions, and ready-to-use premium source code at GudangCode.

GudangCode
  • ✔ Premium Source Code
  • ✔ Ready-to-Use Systems
  • ✔ Lifetime Updates
  • ✔ Lifetime Membership
  • ✔ Daily App Updates
Join Membership →