Laravel's built-in localization support — translation files plus the app()->setLocale() mechanism — handles most multi-language site requirements without needing a third-party package, as long as the routes and translation files are structured consistently from the start.
Setting up translation files
// lang/en/messages.php
return [
'welcome' => 'Welcome to our site',
'contact_us' => 'Contact Us',
];
// lang/es/messages.php
return [
'welcome' => 'Bienvenido a nuestro sitio',
'contact_us' => 'Contáctenos',
];
Laravel 9 and later use plain lang/{locale}/{file}.php paths at the project root — earlier versions nested this under resources/lang instead.
Using translations in Blade views
{{ __('messages.welcome') }}
{{ __('messages.contact_us') }}
Setting the locale from a route prefix
Route::group(['prefix' => '{locale}', 'middleware' => 'setlocale'], function () {
Route::get('/', [HomeController::class, 'index']);
Route::get('/about', [PageController::class, 'about']);
});
// app/Http/Middleware/SetLocale.php
public function handle($request, Closure $next)
{
$locale = $request->route('locale');
if (in_array($locale, ['en', 'es', 'fr'])) {
app()->setLocale($locale);
}
return $next($request);
}
Validating the locale against an allow-list before calling setLocale() prevents an arbitrary, unsupported value in the URL from silently breaking translation lookups.
A language switcher
@foreach (['en' => 'English', 'es' => 'Español', 'fr' => 'Français'] as $code => $label)
{{ $label }}
@endforeach
Storing a user's preferred locale
// after login, or on locale switch for a logged-in user
$request->user()->update(['locale' => $locale]);
// in middleware, for an authenticated request
if ($request->user()) {
app()->setLocale($request->user()->locale);
}
Persisting the preference means a returning logged-in user gets their chosen language automatically, rather than needing to select it again on every visit.
Translating validation messages and model attribute names
// lang/es/validation.php exists alongside the default en/validation.php automatically
// Laravel picks the active locale's file for built-in validation messages
Laravel ships translated validation.php files for many locales out of the box — validation error messages localize automatically once the locale is set, without any extra code.