jayesh/laravel-gemini-translator
Interactive Artisan command to scan Laravel projects for translation keys, translate them via Google Gemini AI, and generate language files. Supports Blade/PHP/JS/Vue/TS, concurrency, safe atomic writes, and Laravel Modules integration with skip/refresh modes.
An interactive Artisan command that scans your Laravel project for translation keys, translates them using Google's Gemini AI, and generates the necessary language files with advanced safety and performance features.
--skip-existing), refresh-only (--refresh)nwidart/laravel-modules with consolidation optionspcntl extension (for fork driver on Linux/macOS)tokenizer PHP extension (for proper code parsing)composer require jayesh/laravel-gemini-translator
php artisan vendor:publish --provider="Jayesh\LaravelGeminiTranslator\TranslationServiceProvider"
Add to your .env:
GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
GEMINI_REQUEST_TIMEOUT=600
Get your API key from Google AI Studio.
⚠️ IMPORTANT: If you published the config/gemini.php file from the google-gemini-php/laravel package, make sure the request_timeout is cast to an integer:
// ✅ CORRECT
'request_timeout' => (int) env('GEMINI_REQUEST_TIMEOUT', 600),
// ❌ WRONG - Will cause "Configuration value must be an integer" error
'request_timeout' => env('GEMINI_REQUEST_TIMEOUT', 600),
# Linux/macOS (fastest with configurable concurrency)
php artisan translations:extract-and-generate --driver=fork --concurrency=10
# Windows (stable)
php artisan translations:extract-and-generate --driver=sync
# Preview changes without writing files
php artisan translations:extract-and-generate --dry-run
# Refresh only existing translations (re-translate existing keys only)
php artisan translations:extract-and-generate --refresh
# Add only missing translations (recommended for updates)
php artisan translations:extract-and-generate --skip-existing
For detailed documentation, step-by-step guides, and advanced usage examples, visit our comprehensive documentation:
# Custom languages (English is always used as source)
php artisan translations:extract-and-generate --langs=en,es,fr,de
# Skip existing translations (translate only missing keys)
php artisan translations:extract-and-generate --skip-existing
# Refresh existing translations (re-translate existing keys only)
php artisan translations:extract-and-generate --refresh
# Preview without writing files
php artisan translations:extract-and-generate --dry-run
# Custom chunk size for API requests
php artisan translations:extract-and-generate --chunk-size=50
# Custom concurrency (when using fork driver)
php artisan translations:extract-and-generate --concurrency=20
# Exclude directories
php artisan translations:extract-and-generate --exclude=vendor,node_modules
# Custom target directory
php artisan translations:extract-and-generate --target-dir=custom-lang
# Provide project context for better translations
php artisan translations:extract-and-generate --context="E-commerce platform with payment features"
# Concurrency driver (default, fork, sync)
php artisan translations:extract-and-generate --driver=fork
# Retry settings
php artisan translations:extract-and-generate --max-retries=3 --retry-delay=5
# Custom extensions
php artisan translations:extract-and-generate --extensions=php,blade.php,vue,js,ts,json
# Consolidate module translations
php artisan translations:extract-and-generate --consolidate-modules
# Get help
php artisan help translations:extract-and-generate
--refresh and --skip-existing are mutually exclusive (the command will fail if both are used)--dry-run works with all other options to preview changes--concurrency only affects fork driverlang/
├── en/
│ ├── auth.php
│ ├── pagination.php
│ ├── passwords.php
│ └── validation.php
├── es/
│ ├── auth.php
│ ├── pagination.php
│ ├── passwords.php
│ └── validation.php
├── en.json
├── es.json
└── fr.json
.blade.php.php.vue, .js, .jsx, .ts, .tsx.json__(), trans(), trans_choice(), @lang(), @choice()Lang::get(), Lang::choice(), Lang::has()$t(), i18n.t()v-t, x-text, :v-t, :x-text, v-bind:v-t, v-bind:x-textSupports all quote types: single ('), double ("), and backtick (`).
en-US to en_US)--retry-delay and --max-retries for better rate limit handling--driver=fork --concurrency=N on Linux/macOS for best performance--chunk-size based on API limits (default: 25 keys per request)--concurrency carefully to avoid hitting rate limitsIf you see this error:
Configuration value for key [gemini.request_timeout] must be an integer, string given.
Fix: Edit config/gemini.php and cast the timeout to integer:
'request_timeout' => (int) env('GEMINI_REQUEST_TIMEOUT', 600),
--driver=sync instead of fork for stability--chunk-size to avoid API timeoutsnwidart/laravel-modules is properly configured--dry-run to preview changes without writingtranslation_extraction_log.json for detailed code extractionfailed_translation_keys.json for failed translationsnwidart/laravel-modulesThe MIT License (MIT). Please see License File for more information.
⭐ Star this repo if you find it helpful! | 🐛 Report issues on GitHub | 📖 Read full docs at Here
How can I help you explore Laravel packages today?