Documentation Index
Fetch the complete documentation index at: https://kawax.biz/llms.txt
Use this file to discover all available pages before exploring further.
What is localization?
Laravel’s localization system lets you store translation strings for each language your application supports and retrieve them through a single helper function. When you call __('messages.welcome'), Laravel looks up the string in the active locale’s file and returns the translated version.
There are two ways to organize translation strings:
| Approach | Structure | Best for |
|---|
| Short keys (PHP files) | lang/en/messages.php | Structured, grouped strings; overriding built-in Laravel messages |
| String keys (JSON files) | lang/en.json | Large apps where English text serves as the default key |
Publishing language files
New Laravel apps don’t include the lang directory by default. Run this command to create it and publish Laravel’s built-in translations:
Configuring the locale
Default locale
Set the application’s default language in config/app.php, typically via .env:
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
The fallback locale is used whenever a string is missing from the active locale’s files.
Changing locale at runtime
Use the App facade to switch locale for the current request — useful in middleware:
use Illuminate\Support\Facades\App;
Route::get('/greeting/{locale}', function (string $locale) {
if (! in_array($locale, ['en', 'es', 'fr'])) {
abort(400);
}
App::setLocale($locale);
return view('greeting');
});
Checking the current locale
$locale = App::currentLocale(); // e.g. 'en'
if (App::isLocale('es')) {
// Spanish is active
}
Defining translation strings
Create one file per feature group inside a locale directory:
lang/
├── en/
│ └── messages.php
└── es/
└── messages.php
<?php
// lang/en/messages.php
return [
'welcome' => 'Welcome to our application!',
'goodbye' => 'See you later!',
];
<?php
// lang/es/messages.php
return [
'welcome' => '¡Bienvenido a nuestra aplicación!',
'goodbye' => '¡Hasta luego!',
];
Use underscores for regional locale directory names: en_GB for British English, fr_FR for French — not en-gb or fr-fr. Laravel follows the POSIX locale convention for directory names.
Use the English text as the key. Each other language gets a JSON file at the lang/ root:
lang/
├── en.json
└── es.json
{
"Welcome to our application!": "¡Bienvenido a nuestra aplicación!",
"Log out": "Cerrar sesión",
"Dashboard": "Panel de control"
}
When no JSON file exists for a locale, or when a key is missing, Laravel returns the key string as-is — which doubles as the English fallback automatically.
The JSON approach works well for UI labels where you write English directly in Blade templates. You don’t have to invent key names, and the English app is ready without any translation file.
Retrieving translation strings
The __() helper
// PHP file format — file.key
echo __('messages.welcome');
// Welcome to our application!
// JSON format — pass the English string
echo __('Log out');
// Cerrar sesión (when locale is 'es')
// Missing key — the key itself is returned
echo __('messages.does_not_exist');
// messages.does_not_exist
In Blade templates
{{-- PHP file format --}}
<h1>{{ __('messages.welcome') }}</h1>
{{-- JSON format --}}
<button>{{ __('Log out') }}</button>
Placeholders
Define dynamic parts with a :name prefix:
// lang/en/messages.php
return [
'greeting' => 'Hello, :name!',
'uppercase' => 'Hello, :NAME!', // placeholder uppercased → value uppercased
'titlecase' => 'Hello, :Name!', // placeholder title-cased → value title-cased
];
Pass replacement values as the second argument:
echo __('messages.greeting', ['name' => 'Alice']);
// Hello, Alice!
echo __('messages.uppercase', ['name' => 'alice']);
// Hello, ALICE!
In Blade:
<p>{{ __('messages.greeting', ['name' => $user->name]) }}</p>
Pluralization
Different languages handle pluralization differently. Laravel’s trans_choice() function selects the right form based on a count.
Simple singular / plural
Separate the two forms with |:
// lang/en/messages.php
return [
'apples' => 'There is one apple|There are many apples',
];
echo trans_choice('messages.apples', 1); // There is one apple
echo trans_choice('messages.apples', 5); // There are many apples
Use {n} for exact values and [min,max] for ranges (* means infinity):
'items' => '{0} No items|{1} One item|[2,*] :count items',
echo trans_choice('messages.items', 0); // No items
echo trans_choice('messages.items', 1); // One item
echo trans_choice('messages.items', 12); // 12 items
Placeholders in plural strings
:count is always available as the passed count:
'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago',
echo trans_choice('messages.minutes_ago', 5, ['value' => 5]);
// 5 minutes ago
Setting up locale switching
Here’s a complete pattern for letting users switch language and persist it in the session:
Create a SetLocale middleware
php artisan make:middleware SetLocale
Implement the middleware
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
{
private array $supported = ['en', 'es', 'fr'];
public function handle(Request $request, Closure $next): Response
{
$locale = $request->session()->get('locale', config('app.locale'));
if (in_array($locale, $this->supported)) {
App::setLocale($locale);
}
return $next($request);
}
}
Register the middleware
In bootstrap/app.php:use App\Http\Middleware\SetLocale;
->withMiddleware(function (Middleware $middleware) {
$middleware->append(SetLocale::class);
})
Add a locale-switching route
// routes/web.php
Route::post('/locale/{locale}', function (string $locale) {
if (! in_array($locale, ['en', 'es', 'fr'])) {
abort(400);
}
session(['locale' => $locale]);
return back();
})->name('locale.switch');
Add switcher buttons in Blade
<form method="POST" action="{{ route('locale.switch', 'en') }}">
@csrf
<button type="submit">English</button>
</form>
<form method="POST" action="{{ route('locale.switch', 'es') }}">
@csrf
<button type="submit">Español</button>
</form>
Overriding package translations
When a third-party package ships its own language files, override individual strings by placing a file in lang/vendor/{package}/{locale}/:
lang/
└── vendor/
└── acme-billing/
└── en/
└── invoices.php
// lang/vendor/acme-billing/en/invoices.php
return [
'paid' => 'Invoice paid', // overrides the package's string
// Keys not listed here fall through to the package's file
];
Function reference
| Function / method | Purpose |
|---|
__('key') | Retrieve a translation string |
trans('key') | Alias for __() |
trans_choice('key', $n) | Pluralization-aware retrieval |
App::setLocale('es') | Set locale for the current request |
App::currentLocale() | Get the active locale |
App::isLocale('es') | Test the active locale |
App::getLocale() | Alias for currentLocale() |