our-edu / laravel-translation-client
Laravel client package for consuming centralized translation service
Installs: 52
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/our-edu/laravel-translation-client
Requires
- php: ^8.1|^8.2|^8.3
- illuminate/cache: ^10.0|^11.0
- illuminate/http: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- illuminate/translation: ^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2026-01-12 22:25:59 UTC
README
A Laravel package for consuming centralized translation services. This package replaces Laravel's file-based translation loader with an API-based loader that fetches translations from a remote translation service.
Features
- API-based translations - Fetch translations from a centralized service
- Write translations - Push translations back to the service
- Multi-level caching - Memory, Laravel cache, and service-side caching
- Automatic updates - Translations update without redeployment
- Multi-tenant support - Per-tenant translation isolation
- Zero code changes - Works with existing
trans()and__()calls - High performance - Sub-millisecond translation lookups
- Graceful degradation - Falls back to stale cache on API failures
- Import from files - Migrate existing Laravel translations
Requirements
- PHP 8.1 or higher
- Laravel 10.x or 11.x
Installation
1. Install via Composer
composer require ouredu/laravel-translation-client
2. Publish Configuration
php artisan vendor:publish --provider="OurEdu\TranslationClient\TranslationServiceProvider"
This will create config/translation-client.php.
3. Configure Environment
Add the following to your .env file:
TRANSLATION_SERVICE_URL=https://your-translation-service.com TRANSLATION_PRELOAD=true TRANSLATION_CLIENT=backend
4. Configure Available Locales
In config/translation-client.php, add:
'available_locales' => ['en', 'ar', 'fr'],
Configuration
All configuration options are in config/translation-client.php:
return [ // Translation service base URL 'service_url' => env('TRANSLATION_SERVICE_URL', 'http://localhost'), // Preload translations on boot (recommended for production) 'preload' => env('TRANSLATION_PRELOAD', true), // Cache TTL in seconds 'manifest_ttl' => env('TRANSLATION_MANIFEST_TTL', 300), // 5 minutes 'bundle_ttl' => env('TRANSLATION_BUNDLE_TTL', 3600), // 1 hour // Client type: backend, frontend, mobile 'client' => env('TRANSLATION_CLIENT', 'backend'), // HTTP timeout in seconds 'http_timeout' => env('TRANSLATION_HTTP_TIMEOUT', 10), // Use stale cache on API failure 'fallback_on_error' => env('TRANSLATION_FALLBACK_ON_ERROR', true), // Cache store (null = default) 'cache_store' => env('TRANSLATION_CACHE_STORE'), // Logging 'logging' => [ 'enabled' => env('TRANSLATION_LOGGING', false), 'channel' => env('TRANSLATION_LOG_CHANNEL', 'stack'), ], /* |-------------------------------------------------------------------------- | Available Locales |-------------------------------------------------------------------------- | | The list of available locales to sync translations for | */ 'available_locales' => [ 'ar', 'en', ], ];
Usage
Basic Usage
Once installed, use Laravel's translation functions as normal:
// In controllers __('messages.welcome') trans('validation.required') // With replacements trans('messages.hello', ['name' => 'Ahmed'])
Commands
Sync Translations
Manually fetch and cache translations:
# Sync all locales php artisan translations:sync # Sync specific locale php artisan translations:sync --locale=ar # Force refresh (clear cache first) php artisan translations:sync --force
Clear Cache
Clear translation caches:
# Clear all translation caches php artisan translations:clear-cache # Clear specific locale php artisan translations:clear-cache --locale=ar
Import Translations
Import translations from Laravel lang files to the service:
# Import all locales php artisan translations:import # Import specific locale php artisan translations:import --locale=ar # Import from custom path php artisan translations:import --path=/path/to/lang
Scheduled Sync
Add to app/Console/Kernel.php to sync translations hourly:
protected function schedule(Schedule $schedule): void { $schedule->command('translations:sync')->hourly(); }
Middleware for Locale Detection
Add to app/Http/Kernel.php:
protected $middlewareGroups = [ 'web' => [ // ... \OurEdu\TranslationClient\Middleware\SetLocaleFromRequest::class, ], ];
This middleware detects locale from:
- Query parameter (
?locale=ar) - Header (
X-Locale: ar) - Accept-Language header
- Authenticated user preference
Using the Facade
Reading Translations
use OurEdu\TranslationClient\Facades\Translation; // Check version $manifest = Translation::checkVersion('ar'); // Returns: ['version' => 42, 'etag' => '...', 'updated_at' => '...'] // Fetch specific groups $translations = Translation::fetchBundle('ar', ['messages', 'validation']); // Load all translations $all = Translation::loadTranslations('ar'); // Clear cache Translation::clearCache('ar');
Writing Translations
// Push single translation Translation::pushTranslation( locale: 'ar', group: 'messages', key: 'welcome', value: 'مرحبا' ); // Push multiple translations Translation::pushTranslations([ [ 'locale' => 'ar', 'group' => 'messages', 'key' => 'hello', 'value' => 'مرحباً', 'client' => 'backend', ], ]); // Import from Laravel lang files Translation::importFromFiles('ar', lang_path());
Programmatic Access
use OurEdu\TranslationClient\Services\TranslationClient; class MyService { public function __construct( private TranslationClient $translationClient ) {} public function getTranslations() { return $this->translationClient->fetchBundle('ar', ['messages']); } }
How It Works
Architecture
Laravel App → trans() → ApiTranslationLoader → TranslationClient → Translation Service API
↓
Memory Cache (in-memory)
↓
Laravel Cache (Redis/File)
↓
Translation Service (Redis + DB)
Caching Strategy
- Memory Cache: Loaded translations stored in PHP memory
- Laravel Cache: Persistent cache with configurable TTL
- Version Checking: Manifest API checked every 5 minutes
- Automatic Invalidation: Cache refreshed when version changes
Performance
- Cached Translation: ~1-5ms (from memory)
- Laravel Cache Hit: ~5-10ms
- API Call (first time): ~50-200ms
- Manifest Check: ~10-50ms
Multi-Tenant Support
For multi-tenant applications:
// Set tenant dynamically based on request config(['translation-client.tenant_uuid' => $currentTenant->uuid]); // Or extend the TranslationClient class MultiTenantTranslationClient extends TranslationClient { public function __construct() { parent::__construct(); $this->tenantUuid = auth()->user()?->tenant_uuid; } }
Error Handling
The package handles errors gracefully:
- API Unavailable: Uses stale cache if available
- Network Timeout: Falls back to cached data
- Invalid Response: Logs error and returns empty array
- Missing Translations: Falls back to key name (Laravel default)
Enable logging for debugging:
TRANSLATION_LOGGING=true TRANSLATION_LOG_CHANNEL=stack
Testing
When testing, you may want to disable API calls:
// In tests/TestCase.php protected function setUp(): void { parent::setUp(); // Mock the translation client $this->mock(TranslationClient::class, function ($mock) { $mock->shouldReceive('loadTranslations') ->andReturn(['messages.welcome' => 'Welcome']); }); }
Troubleshooting
Translations not loading
- Check service URL is correct:
php artisan config:cache - Verify API is accessible:
curl https://your-service.com/translation/manifest?locale=en - Enable logging:
TRANSLATION_LOGGING=true - Check logs:
tail -f storage/logs/laravel.log
Cache not clearing
php artisan cache:clear php artisan translations:clear-cache php artisan config:cache
Performance issues
- Ensure
TRANSLATION_PRELOAD=truein production - Use Redis for caching instead of file cache
- Increase cache TTL if translations rarely change
License
This package is open-sourced software licensed under the MIT license.
Support
For issues and questions, please use the GitHub issue tracker.