rivalex/lingua
Database-driven translations for Laravel with a polished Livewire + Flux admin UI. Install and manage languages, edit strings in real time, and sync translations both ways between DB and PHP/JSON files via artisan commands. Supports Laravel 11–13, PHP 8.3+.
Installation:
composer require rivalex/lingua
php artisan lingua:install
This publishes config, runs migrations, and seeds the database with your default language.
First Use Case:
/lingua/languages to manage installed languages.es for Spanish)./lingua/translations to edit translations directly in the database.config/lingua.php (customize default locale, sync behavior, UI settings).php artisan lingua:update-lang to fetch the latest translations from laravel-lang./lingua/languages → Manage installed languages./lingua/translations → Edit translations./lingua/statistics → Track progress.Database-Driven Translations:
Lingua::get('key', 'locale')) to fetch translations from the database.$translation = Lingua::get('auth.login', 'es'); // Returns Spanish translation
php artisan lingua:sync-to-database
Language Management:
php artisan lingua:add fr # Add French
php artisan lingua:remove de # Remove German
php artisan lingua:update-lang
Rich-Text Translations:
config/lingua.php under the editor key.Headless Language Selector:
@linguaSelector Blade component for a zero-CSS dropdown/modal/sidebar selector.config/lingua.php:
'selector' => [
'mode' => 'dropdown', // 'sidebar' | 'modal' | 'dropdown'
'show_flags' => true,
]
Vendor Translations:
vendor/laravel-lang) alongside your app’s translations.lingua:update-lang.Blade Integration:
Use @lingua directive for translations:
<h1>@lingua('auth.welcome')</h1>
Fallback to default locale if missing:
<h1>@lingua('auth.welcome', fallback: true)</h1>
API Responses: Return translations dynamically:
return response()->json([
'message' => Lingua::get('api.success', request()->locale),
]);
Middleware: Force a locale for specific routes:
Route::middleware(['locale' => 'es'])->group(function () {
// Spanish-only routes
});
Testing: Mock translations in tests:
Lingua::shouldReceive('get')->andReturn('Mocked translation');
Default Locale Lock:
config/lingua.php) cannot be removed via the UI or CLI.Sync Conflicts:
lang/ files may be overwritten during sync-to-database.sync-to-local to export database changes to files first.Livewire Caching:
php artisan lingua:clear-cache
RTL Languages:
rtl class in your layout:
<html lang="{{ app()->getLocale() }}" class="{{ app()->isLocaleRTL() ? 'rtl' : '' }}">
Large Translation Sets:
language_lines table (publish migrations first).Missing Translations:
Show missing translations only.Sync Issues:
lang/ directory.php artisan lingua:sync-to-database --verbose for detailed logs.UI Glitches:
?flush=1 to bypass Livewire cache:
/lingua/translations?flush=1.Custom Fields:
language_lines table by publishing migrations:
php artisan vendor:publish --tag="lingua-migrations"
notes column for translator comments:
Schema::table('language_lines', function (Blueprint $table) {
$table->text('notes')->nullable();
});
Custom Validation:
app/Providers/LinguaServiceProvider.php:
public function boot()
{
Lingua::extend('validation', function ($validator, $key, $locale) {
$validator->addRules([
'key' => 'required|max:255',
'value' => 'required|max:65535|custom:no_html_tags',
]);
});
}
Custom UI Components:
php artisan vendor:publish --tag="lingua-views"
resources/views/vendor/lingua/livewire/translations.blade.php to add a custom column.AI Translation Integration:
lingua.translation.updated event to auto-translate via an API:
Lingua::listen('translation.updated', function ($translation) {
if ($translation->locale !== 'en') {
$translated = callToAITranslationAPI($translation);
$translation->value = $translated;
$translation->save();
}
});
Fallback Locale:
config/lingua.php and config/app.php use the same fallback_locale.'fallback_locale' => 'en', // Must match app.fallback_locale
Editor Toolbar:
'editor' => [
'allowed_tags' => ['<strong>', '<em>', '<p>'],
]
Database Drivers:
lang_dir in config/lingua.php points to a writable directory.Bulk Updates:
Translation Groups:
auth, validation) for easier filtering.Localization Testing:
$this->actingAs(User::factory()->create())
->withSession(['locale' => 'fr']);
Deployment Workflow:
php artisan lingua:sync-to-local
git add lang/
git commit -m "Update translations"
Collaboration:
How can I help you explore Laravel packages today?