Reader Stacks

How to Create a Multi-Language Website in Laravel

Laravel's built-in localization files plus a locale-prefixed route group cover most multi-language sites without needing a third-party package.

How to Create a Multi-Language Website in Laravel

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.