jawabapp / localization
A comprehensive, modern Laravel package for managing multilingual applications with database-driven translations, automatic locale detection, and a beautiful admin interface.
Fund package maintenance!
jawabapp
Installs: 19
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Language:CSS
Requires
- php: ^8.2
- ext-json: *
- ext-mbstring: *
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- illuminate/translation: ^10.0|^11.0|^12.0
Requires (Dev)
- fakerphp/faker: ^1.23
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
This package is auto-updated.
Last update: 2025-09-14 09:39:52 UTC
README
A comprehensive, modern Laravel package for managing multilingual applications with database-driven translations, automatic locale detection, and a beautiful admin interface. Built for Laravel 10+ with full support for the latest language directory structure.
β¨ Features
- π 12+ Languages: Pre-configured support for major world languages
- π― Smart Locale Detection: Browser, URL, session, and cookie-based detection
- π Modern Laravel Compatibility: Laravel 10/11
lang/
directory structure - ποΈ Dual Format Support: Both PHP arrays and JSON translations
- ποΈ Database-Driven Translations: Store translations in database with file fallback
- ποΈ Professional Admin Interface: Beautiful Tailwind CSS interface
- β‘ Performance Optimized: Built-in caching and file-based translations
- π§ Artisan Commands: CLI tools for import/export and management
- π£οΈ SEO Friendly: Automatic hreflang tags and localized URLs
- π± API Support: RESTful API with intelligent locale detection
- π Hot Reloading: Automatic file export on database changes
- π Flexible Loading: Database-first with automatic file fallback
π Requirements
- PHP: 8.2 or higher
- Laravel: 10.0 or higher
- Extensions: mbstring, json
π Quick Installation
1. Install via Composer
composer require jawabapp/localization
2. Publish Configuration
# Publish config file php artisan vendor:publish --tag=localization-config # Publish and run migrations php artisan vendor:publish --tag=localization-migrations php artisan migrate
3. Configure Middleware
For Laravel 11+, add the middleware to your bootstrap/app.php
:
<?php use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withMiddleware(function (Middleware $middleware): void { // Register localization middleware $middleware->alias([ 'localization' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, 'localization.web' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, 'localization.api' => \Jawabapp\Localization\Http\Middleware\Api\Localization::class, ]); }) ->withExceptions(function (Exceptions $exceptions): void { // })->create();
For Laravel 10 and earlier, add the middleware to your app/Http/Kernel.php
:
protected $middlewareGroups = [ 'web' => [ // ... other middleware \Jawabapp\Localization\Http\Middleware\Web\Localization::class, ], 'api' => [ // ... other middleware \Jawabapp\Localization\Http\Middleware\Api\Localization::class, ], ];
4. Setup Route Prefixes
Update your App\Providers\RouteServiceProvider.php
:
use Jawabapp\Localization\Libraries\Localization; public function boot(): void { // Web routes with locale prefix Route::prefix(Localization::routePrefix()) ->middleware('web') ->group(base_path('routes/web.php')); }
5. Access the Admin Interface
Visit /localization
in your browser to manage translations!
ποΈ Database-Driven Translations
The package automatically uses database-driven translations with file fallback. This means:
- β Primary: Translations are loaded from the database first
- β Fallback: If database is unavailable, files are used automatically
- β Performance: Results are cached for optimal performance
- β Flexibility: You can disable database translations if needed
Configuration
Control database translations in config/localization.php
:
'database_translations' => [ 'enabled' => true, // Enable database translations 'fallback_to_files' => true, // Fallback to file translations if database fails ],
How It Works
- Translation Request: When you call
__('messages.welcome')
ortrans('auth.failed')
- Database Check: Package checks the database for the translation first
- File Fallback: If not found in database, loads from
lang/
files - Caching: Results are cached to avoid repeated database queries
- Admin Interface: Manage all translations through the web interface at
/localization
Automatic Setup
The database translation system is automatically configured when you install the package:
- π§ Auto-Discovery: Laravel automatically registers the
TranslationServiceProvider
- π Seamless Integration: Replaces Laravel's default translator with our enhanced version
- π No Code Changes: Your existing
__()
andtrans()
calls work unchanged - π‘οΈ Safe Fallback: If database fails, translations load from files automatically
Disabling Database Translations
To use only file-based translations, set in your config:
'database_translations' => [ 'enabled' => false, // Disable database translations - use files only ],
βοΈ Configuration
The main configuration file is published to config/localization.php
:
<?php return [ // Supported locales 'supported_locales' => ['en', 'ar', 'es', 'fr', 'de'], // Locale detection 'detect_browser_locale' => true, 'store_in_session' => true, 'store_in_cookie' => true, // URL configuration 'url' => [ 'hide_default' => true, // Hide default locale in URLs 'force_locale_in_url' => false, ], // Cache settings 'cache' => [ 'enabled' => true, 'duration' => 60 * 24, // 24 hours ], // Translation groups 'translation_groups' => [ 'auth', 'validation', 'general', 'messages' ], ];
Available Locales
The package comes pre-configured with these locales:
Code | Language | Native Name |
---|---|---|
en |
English | English |
ar |
Arabic | Ψ§ΩΨΉΨ±Ψ¨ΩΨ© |
es |
Spanish | EspaΓ±ol |
fr |
French | FranΓ§ais |
de |
German | Deutsch |
it |
Italian | Italiano |
pt |
Portuguese | PortuguΓͺs |
ru |
Russian | Π ΡΡΡΠΊΠΈΠΉ |
zh |
Chinese | δΈζ |
ja |
Japanese | ζ₯ζ¬θͺ |
ko |
Korean | νκ΅μ΄ |
tr |
Turkish | TΓΌrkΓ§e |
π Usage Guide
Basic Translation Management
Use Laravel's built-in translation functions:
// In controllers or views echo __('messages.welcome'); echo trans('auth.failed'); echo trans_choice('messages.items', 5); // With parameters echo __('messages.hello', ['name' => 'John']);
Dynamic Locale Switching
use Jawabapp\Localization\Libraries\Localization; // Set locale programmatically Localization::setLocale('fr'); // Get current locale $locale = app()->getLocale(); // Get all supported locales $locales = Localization::getSupportedLocales(); // Get locale native name $name = Localization::getLocaleName('ar'); // Returns: Ψ§ΩΨΉΨ±Ψ¨ΩΨ©
Working with Localized Routes
Create routes that automatically work with all locales:
Route::localized(function ($locale) { Route::get('/', [HomeController::class, 'index'])->name('home'); Route::get('/about', [AboutController::class, 'index'])->name('about'); Route::get('/products', [ProductController::class, 'index'])->name('products'); });
Generate localized URLs:
// Current locale URL $url = route('products'); // Specific locale URL $url = Route::localizedUrl('products', 'fr'); // Get all locale URLs for hreflang tags $alternateUrls = Localization::getAlternateUrls();
Model Integration
For models with translatable fields, use the _key
suffix:
class Post extends Model { protected $fillable = ['title_key', 'content_key', 'slug']; // Accessors for translated content public function getTitleAttribute() { return $this->title_key ? __($this->title_key) : ''; } public function getContentAttribute() { return $this->content_key ? __($this->content_key) : ''; } } // Usage $post = Post::create([ 'title_key' => 'My Blog Post Title', 'content_key' => 'This is the blog post content...', 'slug' => 'my-blog-post' ]);
ποΈ Admin Interface
Access the admin interface at /localization
to:
Translation Management
- β View all translations by language and group
- β Add, edit, and delete translations
- β Search and filter translations
- β Bulk operations (delete, export)
- β Visual translation status indicators
Import/Export Tools
- β Export translations to PHP/JSON files
- β Import from existing language files
- β Sync translations between locales
- β Translation statistics and completion rates
Features
- π± Responsive Design: Works perfectly on mobile and desktop
- π¨ Modern UI: Beautiful Tailwind CSS interface
- β‘ Real-time Updates: Live search and filtering
- π Batch Operations: Handle multiple translations at once
π§ Artisan Commands
The package includes powerful CLI commands:
Export Translations
# Export all translations php artisan localization:export # Export specific locale php artisan localization:export --locale=fr # Export specific group php artisan localization:export --locale=en --group=auth # Export only JSON format php artisan localization:export --format=json
Import Translations
# Import all translations from files php artisan localization:import # Import specific locale php artisan localization:import --locale=fr # Overwrite existing translations php artisan localization:import --overwrite
Sync Between Locales
# Sync missing translations from English to French php artisan localization:sync --from=en --to=fr --missing-only # Copy all translations (overwrite existing) php artisan localization:sync --from=en --to=de --overwrite
Cache Management
# Clear translation cache php artisan localization:clear-cache # Clear cache for specific locale php artisan localization:clear-cache --locale=fr
π API Usage
The package provides full API support with intelligent locale detection:
Request Headers
# Custom headers curl -H "X-Localization: fr" /api/endpoint curl -H "X-Locale: es" /api/endpoint # Standard Accept-Language header curl -H "Accept-Language: fr,en;q=0.8" /api/endpoint
Query Parameters
curl /api/endpoint?locale=fr
Response Headers
The API middleware automatically adds:
Content-Language: fr
header to responses- Proper locale detection from multiple sources
ποΈ File Structure
The package supports Laravel's modern language directory structure:
lang/
βββ en/
β βββ auth.php
β βββ validation.php
β βββ messages.php
βββ fr/
β βββ auth.php
β βββ validation.php
βββ ar/
β βββ messages.php
βββ en.json
βββ fr.json
βββ ar.json
File Types
- PHP Files (
lang/{locale}/group.php
): Structured translations with nested arrays - JSON Files (
lang/{locale}.json
): Simple key-value translations
π SEO Features
Automatic Hreflang Tags
Add to your layout:
@foreach(Localization::getAlternateUrls() as $locale => $url) <link rel="alternate" hreflang="{{ $locale }}" href="{{ $url }}" /> @endforeach
Localized URLs
// Generates: /en/products or /products (if default) Route::get('/products', [ProductController::class, 'index'])->name('products');
β‘ Performance Optimization
Caching
Translations are automatically cached:
// Cache keys: // localization.{locale} - All translations for locale // localization.{locale}.{group} - Specific group translations
Static File Export
Export to static files for optimal performance:
php artisan localization:export
Static files load faster than database queries and are automatically cached by Laravel.
π§ Advanced Configuration
Custom Database Connection
'database' => [ 'connection' => 'translations_db', 'table' => 'app_translations', ],
Custom Translation Groups
'translation_groups' => [ 'auth', 'validation', 'emails', 'custom_module', 'product_catalog' ],
Middleware Configuration
'routes' => [ 'enabled' => true, 'prefix' => 'admin/localization', // Custom admin path 'middleware' => ['web', 'auth', 'admin'], ],
π Examples
Complete Laravel Application Setup
- Install and Configure:
composer require jawabapp/localization php artisan vendor:publish --tag=localization-config php artisan migrate
- Create Localized Routes:
// routes/web.php Route::localized(function ($locale) { Route::get('/', function () { return view('welcome'); })->name('home'); Route::get('/products', function () { return view('products.index'); })->name('products'); Route::get('/contact', function () { return view('contact'); })->name('contact'); });
- Add Language Switcher:
<!-- resources/views/layouts/app.blade.php --> <div class="language-switcher"> @foreach(Localization::getSupportedLocales() as $locale) <a href="{{ Route::localizedUrl(Route::currentRouteName(), $locale) }}" class="{{ app()->getLocale() === $locale ? 'active' : '' }}"> {{ Localization::getLocaleName($locale) }} </a> @endforeach </div>
- Use Translations in Views:
<!-- resources/views/welcome.blade.php --> <h1>{{ __('messages.welcome') }}</h1> <p>{{ __('messages.description', ['app' => config('app.name')]) }}</p>
API Integration
// app/Http/Controllers/Api/ProductController.php class ProductController extends Controller { public function index(Request $request) { // Locale is automatically set by middleware $locale = app()->getLocale(); $products = Product::select([ 'id', 'name_key', 'description_key', 'price' ])->get()->map(function ($product) { return [ 'id' => $product->id, 'name' => __($product->name_key), 'description' => __($product->description_key), 'price' => $product->price, ]; }); return response()->json($products); } }
π Troubleshooting
Common Issues
1. Translations not loading
# Clear cache and regenerate
php artisan localization:clear-cache
php artisan localization:export
2. Middleware not working (Laravel 11)
// Ensure middleware is registered in bootstrap/app.php $middleware->alias([ 'localization' => \Jawabapp\Localization\Http\Middleware\Web\Localization::class, ]);
2b. Middleware not working (Laravel 10 and earlier)
// Ensure middleware is registered in Kernel.php \Jawabapp\Localization\Http\Middleware\Web\Localization::class,
3. Routes not found
// Make sure RouteServiceProvider is configured Route::prefix(Localization::routePrefix()) ->middleware('web') ->group(base_path('routes/web.php'));
4. Admin interface 404
# Check if routes are enabled 'routes' => ['enabled' => true]
5. "Call to a member function total() on array" error
# This error occurs when the layout expects paginated data but receives an array # The fix is included in the updated controller - no action needed for users
6. "Class Jawabapp\Localization\Libraries\Localization not found" error
# This error occurs when trying to update translations # The fix is included in the updated controller - no action needed for users
7. Export functionality not working
# If Artisan commands don't work from web interface, try from command line: php artisan localization:export # The web interface now includes direct export functionality as fallback
8. "SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: translations.key"
# This occurs when translation key parsing fails # Ensure your translations have proper namespace, group, and key structure # The updated controller handles this automatically
Debug Mode
Enable debug logging:
'fallback' => [ 'log_missing' => env('APP_DEBUG', false), ],
Performance Issues
# Enable caching php artisan config:cache # Export translations to static files php artisan localization:export
π Upgrading from v1.x
The package uses a new database schema:
- Backup translations:
php artisan localization:export
- Run migration:
php artisan migrate
- Verify data:
The migration automatically converts
language_code
βlocale
and extracts groups from keys.
π€ Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
Development Setup
# Clone repository git clone https://github.com/jawabapp/localization cd localization # Install dependencies composer install npm install # Run tests composer test
π Security
If you discover security vulnerabilities, please email i.qanah@gmail.com instead of using the issue tracker.
π License
This package is open-sourced software licensed under the MIT license.
π¨βπ» Credits
- Ibraheem Qanah - Creator & Maintainer
- All Contributors - Thank you!
π Support
- β Star this repo if it helped you!
- π Report bugs
- π‘ Request features
- π Documentation
Made with β€οΈ for the Laravel community
Documentation β’ Report Bug β’ Request Feature