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.