This Laravel boilerplate now includes comprehensive multi-language support with automated translations.
- Multiple Language Support: English, Spanish, French, and German out of the box
- Automated Translations: Uses MyMemory Translation API (free, no API key required)
- Smart Language Detection:
- Browser language preferences
- User-specific preferences
- Session-based switching
- URL parameter support
- Translation Caching: Improves performance by caching translations for 30 days
- Admin Interface: Filament admin panel integration for managing translations
- Artisan Commands: CLI tools for generating translations
Add the locale column to the users table:
php artisan migrateAdd the language switcher component to your navigation:
<livewire:language-switcher />Use Laravel's built-in translation helpers:
{{ __('messages.welcome') }}
{{ trans('messages.dashboard') }}
@lang('messages.profile')- Navigate to Admin > Settings > Languages
- Click "Generate Translations"
- Select source and target languages
- Click "Generate"
# Translate all languages from English
php artisan translate:generate --source=en
# Translate to a specific language
php artisan translate:generate --source=en --target=es
# Overwrite existing translations
php artisan translate:generate --source=en --force
# Translate a specific file
php artisan translate:generate --source=en --file=messagesEdit config/app.php to add or remove languages:
'supported_locales' => [
'en' => 'English',
'es' => 'Español',
'fr' => 'Français',
'de' => 'Deutsch',
'it' => 'Italiano', // Add more languages
],Set the default application locale:
'locale' => 'en',
'fallback_locale' => 'en',Translation files are stored in the lang/ directory:
lang/
├── en/
│ ├── messages.php
│ └── validation.php
├── es/
│ └── messages.php
├── fr/
│ └── messages.php
└── de/
└── messages.php
Create a new translation file:
<?php
// lang/en/messages.php
return [
'welcome' => 'Welcome',
'dashboard' => 'Dashboard',
'profile' => 'Profile',
// Add more translations...
];<!-- Simple translation -->
<h1>{{ __('messages.welcome') }}</h1>
<!-- Translation with parameters -->
<p>{{ __('messages.greeting', ['name' => $user->name]) }}</p>
<!-- Pluralization -->
<p>{{ trans_choice('messages.items', $count) }}</p>use Illuminate\Support\Facades\App;
public function index()
{
// Get current locale
$locale = App::getLocale();
// Set locale dynamically
App::setLocale('es');
// Use translation
$message = __('messages.welcome');
return view('dashboard', compact('message'));
}public function render()
{
return view('livewire.component', [
'title' => __('messages.dashboard'),
]);
}const translations = {
welcome: "{{ __('messages.welcome') }}",
dashboard: "{{ __('messages.dashboard') }}",
};
console.log(translations.welcome);The TranslationService class provides programmatic access to translations:
use App\Services\TranslationService;
$service = app(TranslationService::class);
// Translate a single text
$translated = $service->translate('Hello', 'es', 'en');
// Translate multiple texts
$translations = $service->translateBatch([
'hello' => 'Hello',
'world' => 'World',
], 'es', 'en');
// Get supported languages
$languages = $service->getSupportedLanguages();
// Check if language is supported
if ($service->isLanguageSupported('es')) {
// Do something
}The middleware is automatically applied to the web middleware group. It:
- Checks for
localequery parameter - Falls back to session value
- Uses authenticated user's preference
- Detects from browser's Accept-Language header
- Uses the default locale
Properties:
$currentLocale: Current application locale$availableLocales: Array of available languages
Methods:
switchLanguage($locale): Switch to a different language
Users can set their preferred language:
// Update user's language preference
$user->update(['locale' => 'es']);
// Get user's language preference
$locale = $user->locale;The middleware automatically uses the authenticated user's preferred language.
You can extend the TranslationService to use a different translation API:
namespace App\Services;
class CustomTranslationService extends TranslationService
{
public function translate(string $text, string $targetLang, string $sourceLang = 'en'): string
{
// Your custom translation logic
return $translatedText;
}
}Register it in a service provider:
$this->app->bind(TranslationService::class, CustomTranslationService::class);Add a route for language switching:
Route::get('/language/{locale}', function ($locale) {
if (in_array($locale, array_keys(config('app.supported_locales')))) {
session(['locale' => $locale]);
if (auth()->check()) {
auth()->user()->update(['locale' => $locale]);
}
}
return redirect()->back();
})->name('language.switch');Run the translation tests:
# Run all tests
php artisan test
# Run translation-specific tests
php artisan test --filter=Translation
php artisan test --filter=Language
php artisan test --filter=SetLocale- Clear cache:
php artisan cache:clear - Clear config:
php artisan config:clear - Clear views:
php artisan view:clear - Verify translation files exist in
lang/{locale}/
The free MyMemory API has rate limits. If you encounter issues:
- Use the
--forceflag sparingly - Add delays between translation batches (already implemented)
- Consider caching translations more aggressively
- For production, consider a paid translation API
If a translation key is missing:
- It will fall back to the key name
- Check your translation files for the key
- Generate translations using the command or admin panel
- Add the key manually to translation files
- Use Translation Keys: Always use descriptive keys like
messages.welcomeinstead of hardcoding text - Organize by Context: Create separate translation files for different sections (auth.php, messages.php, etc.)
- Cache Translations: The system automatically caches API translations
- Test in Different Languages: Always test your application in multiple languages
- Use Pluralization: Use
trans_choice()for strings that need pluralization - Parameter Naming: Use descriptive parameter names in translations:
__('messages.greeting', ['userName' => $name])
- Translation API calls are cached to prevent excessive requests
- User locale preferences are validated against supported locales
- Session-based language switching is CSRF-protected
- No sensitive data is sent to the translation API
- Translations are cached for 30 days
- Browser language detection is efficient
- Minimal database queries for user preferences
- Translation files are compiled by Laravel for optimal performance
Potential improvements for the translation system:
- More Languages: Add support for additional languages
- RTL Support: Add right-to-left language support (Arabic, Hebrew)
- Translation Management UI: Web interface for editing translations
- Import/Export: Bulk import/export of translation files
- Translation Memory: Store and reuse translations across the system
- Professional Translation: Integration with professional translation services
For issues or questions about the multi-language support:
- Check this documentation
- Review the test files for usage examples
- Open an issue on GitHub
- Contact the development team
Version: 1.0.0
Last Updated: February 2026
Maintainer: Liberu Software