artryazanov/artisan-translator
Artisan Translator streamlines Laravel localization: extracts raw text from Blade templates into translation keys, translates with Google Gemini in batches, preserves HTML/placeholders, and cleans unused language keys. Supports Laravel 11/12, PHP 8.2+.
Installation
composer require artryazanov/artisan-translator
Publish the config file:
php artisan vendor:publish --provider="ArtisanTranslator\ArtisanTranslatorServiceProvider" --tag="config"
Configuration
Edit config/artisan-translator.php to set:
google_api_key (for Gemini AI translation)source_language (default: en)target_languages (e.g., ['fr', 'es'])blade_paths (directories to scan for Blade templates)First Use Case Extract and translate strings from Blade files:
php artisan artisan-translator:extract
php artisan artisan-translator:translate
This generates/update resources/lang/{locale}/messages.php with translated keys.
CI/CD Pipeline
Add to phpunit.xml or GitHub Actions:
<phpunit>
<listeners>
<listener class="ArtisanTranslator\Tests\TranslationListener" file="vendor/artisan-translator/src/Tests/TranslationListener.php"/>
</listeners>
</phpunit>
Run before merging to enforce translation updates:
php artisan artisan-translator:check
On-Demand Translation
Use the translate command interactively:
php artisan artisan-translator:translate --key="validation.required" --locale="fr"
Blade Template Hooks
Add @translate directives in Blade:
<p>@translate('welcome.message')</p>
The package auto-detects these during extraction.
Dynamic Language Switching
Override target_languages in runtime config:
config(['artisan-translator.target_languages' => ['de']]);
config(['artisan-translator.cache_translations' => true]);
php artisan view:clear
home.welcome vs home.welcome.title). Use nested arrays:
'home' => [
'welcome' => [
'title' => 'Bonjour',
],
],
php artisan artisan-translator:extract --dry-run
php artisan artisan-translator:translate --verbose
ArtisanTranslator\Extractor\ExtractorInterface for non-Blade files (e.g., JS):
class CustomExtractor implements ExtractorInterface {
public function extract($file) { /* ... */ }
}
config(['artisan-translator.translator' => \App\Services\CustomTranslator::class]);
translation.generated events:
event(new TranslationGenerated($key, $locale, $translation));
config(['artisan-translator.ignore_paths' => ['vendor/*', 'tests/*']]);
How can I help you explore Laravel packages today?