π Overview
The Laravel Gemini AI Translation Synchronization Tool is a powerful Artisan command that revolutionizes the localization workflow for Laravel applications. It moves beyond simple extraction by discovering translation keys from all possible sourcesβyour code, existing language files, and the Laravel framework itselfβand then intelligently synchronizes them across all your target languages using AI.
Full Synchronization
Discovers keys from your code, all existing language files, and framework defaults to create a complete picture, ensuring no translation is left behind.
Context-Aware AI
Leverages Google's Gemini AI and an optional --context
flag
to provide high-quality, domain-specific translations.
High Performance
Features a fork
driver for Linux/macOS enabling
lightning-fast parallel processing, and a stable sync
driver for Windows compatibility.
Interactive & Incremental
An interactive interface lets you choose which files to process, while the --skip-existing
flag allows for efficient synchronization and
updates.
π Installation
Step 1: Install via Composer
For Linux, macOS, or WSL users:
composer require jayesh/laravel-gemini-translator
pcntl
extension required for the high-performance 'fork' driver, you
must use the following command to ignore it during installation:
composer require jayesh/laravel-gemini-translator --ignore-platform-reqs=ext-pcntl
Step 2: Publish Configuration
php artisan gemini:install
This creates the config/gemini.php
file.
Step 3: Add API Key
Add your Gemini API key to your .env
file. You can get a key from
the Google AI Studio.
GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
βοΈ Configuration
Environment Variables
Add these variables to your .env
file:
GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
GEMINI_REQUEST_TIMEOUT=600
Getting Your API Key
1. Visit Google AI Studio
2. Sign in with your Google account
3. Create a new API key
4. Copy and paste it into your .env
file
Configuration File
The config/gemini.php
file allows you to customize:
- AI model selection (e.g., Gemini 2.5 Flash-Lite)
- Request timeout settings
- Default language preferences
- Retry logic parameters
π― Usage
Basic Command
Simply run the command to start the interactive process.
php artisan translations:extract-and-generate
Platform-Specific Recommendations
For the best experience, specify a driver based on your operating system.
# Linux/macOS/WSL (fastest performance)
php artisan translations:extract-and-generate --driver=fork
# Windows (maximum stability)
php artisan translations:extract-and-generate --driver=sync
Incremental Updates & Synchronization
To add new translations without overwriting existing ones, use the --skip-existing
flag. This is the core of the synchronization
feature, perfect for ongoing projects.
# Find all missing keys in Spanish and German and translate them
php artisan translations:extract-and-generate --skip-existing --langs=es,de
The Interactive Process
The command guides you through a seamless workflow:
- Key Discovery: Gathers a complete list of translation keys from all sources: your project code, all existing language files (e.g., `en/`, `fr/`), and Laravel's built-in translations.
- File Selection: Prompts you to choose which translation file groups (e.g., `messages.php`, `auth.php`, JSON file) you wish to process.
- Cross-Check & Analysis: Reports exactly which keys are missing in your target languages, showing you what needs to be synchronized.
- AI Translation: Sends the missing keys and their source text to Gemini AI for translation, showing a real-time progress bar.
- File Generation: Intelligently writes the new translations to the correct language files, merging them with existing content.
q
' key at any time during
translation to gracefully stop the process. All completed translations up to that point will be
saved.
π‘ Context-Aware Translations
Providing project-specific context is one of the most powerful features for achieving high-quality, accurate translations. It helps Gemini resolve ambiguity for words that have different meanings in different domains.
The Problem of Ambiguity
Without context, an AI might misinterpret terms. For example:
Term | General Meaning | Domain-Specific Meaning |
---|---|---|
Position | A physical location | A financial holding (Finance) |
Security | Safety or protection | A tradable financial asset (Finance) |
Cloud | A white puff in the sky | Cloud computing infrastructure (Tech) |
Container | A box or receptacle | A Docker container (Tech) |
The Solution: The --context
Flag
Use the optional --context
flag to guide the AI, ensuring it uses
the correct terminology for your project's domain.
Example: Financial Application
Imagine you are translating for a stock trading platform.
# Without context, translations may be generic or wrong.
php artisan translations:extract-and-generate --langs=ar
# With correct context, translations are precise.
php artisan translations:extract-and-generate --langs=ar \
--context="A SaaS platform for financial trading of stocks. Terms like 'position' and 'security' refer to financial concepts."
Best Practices for Writing Context
- Be Specific: Mention the industry (e.g., "Healthcare", "Legal", "E-commerce").
- Define Ambiguous Terms: Explicitly state what key terms mean in your domain.
- Describe the Tone: Mention the target audience (e.g., "for professional lawyers," "for young children," "formal and corporate").
π§ Command Options
Option | Description |
---|---|
--langs |
Comma-separated language codes to translate to (e.g., es,fr,de ). |
--driver |
Concurrency driver: fork (fast, for Linux/macOS) or
sync (stable, for Windows).
|
--skip-existing |
A flag to only find and translate keys that are missing from target language files, preserving existing translations. |
--context |
Provide a project-specific description to Gemini for more accurate, domain-aware translations. |
--chunk-size |
Number of keys to send to the AI in a single request. Default: 100. |
--source |
The root directory of the application to scan for keys. Default: ".". |
--target-dir |
Root directory for the final Laravel translation files. Default: "lang". |
--exclude |
Comma-separated directories to exclude from the scan. |
--extensions |
Comma-separated file extensions to search within. |
--max-retries |
Maximum number of retries for a failed API call. Default: 5. |
--retry-delay |
Base delay in seconds between retries (uses exponential backoff). Default: 3. |
π‘ Usage Examples
Basic Translation (Overwrite Mode)
# Translate to Spanish, French, and German, overwriting existing files
php artisan translations:extract-and-generate --langs=es,fr,de
High-Performance Synchronization
# Use fork driver with smaller chunks to find and fill only missing keys
php artisan translations:extract-and-generate --driver=fork --chunk-size=50 --skip-existing
Selective Code Scan
# Only scan Blade files for new keys, but still cross-reference all existing lang files
php artisan translations:extract-and-generate \
--extensions=blade.php \
--skip-existing
Context-Aware Synchronization
# Provide context while updating translations for a healthcare app
php artisan translations:extract-and-generate \
--skip-existing \
--langs=es,fr \
--context="A patient management system for hospitals. 'Discharge' means patient release, 'case' means patient case."
π Advanced Usage
Example Output
Fork Driver Output (Linux/macOS)
β
Key discovery complete! Found 235 unique keys from all sources combined.
β Which translation files would you like to process? βββββββββ
β messages.php
β auth.php
β Root JSON file
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Press the 'q' key at any time to gracefully stop the process.
β‘ Using 'fork' driver for high-performance concurrency.
π Total keys needing translation: 156
π¦ Total chunks to process: 2
π 156/156 [============================] 100% -- β
Chunk 2/2 - SUCCESS (156 keys) β±οΈ 18s
ββ πΎ Phase 3: Writing Language Files ββββββββββββββββββββββββββββββ
β
Updated: lang/es.json (110 total keys)
β
Updated: lang/es/messages.php (125 total keys)
β
Updated: lang/fr.json (110 total keys)
β
Updated: lang/fr/messages.php (125 total keys)
Sync Driver Output (Windows)
β
Key discovery complete! Found 222 unique keys from all sources combined.
β Which translation files would you like to process? ββββββββββββββββ
β Root JSON file
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Running in synchronous mode - this will be slower but more stable!
Processing file: __JSON__
-> Processing keys 1-100 of 222... β Done
-> Processing keys 101-200 of 222... β Done
-> Processing keys 201-222 of 222... β Done
ββ πΎ Phase 3: Writing Language Files ββββββββββββββββββββββββββββββββββββββββ
β
Wrote: lang/es.json (222 total keys)
β
Wrote: lang/fr.json (222 total keys)
Supported Functions & Patterns
The scanner is pre-configured to find keys used in the most common Laravel and JavaScript localization functions.
Pattern | Example | Typical Context |
---|---|---|
__() , trans() , @lang() |
__('messages.welcome') |
PHP & Blade |
trans_choice() , @choice() |
trans_choice('messages.apples', 5) |
PHP & Blade (Pluralization) |
$t() , i18n.t() |
$t('user.profile') |
Vue.js, JavaScript (i18n Libraries) |
v-t , x-text |
<span v-t="'buttons.submit'"> |
Vue.js & Alpine.js Directives |
Logging & Debugging
For transparency and debugging, the command creates two log files in your project root:
translation_extraction_log.json
: A detailed log of every unique key found in your *code* and the file paths where it was located.failed_translation_keys.json
: A list of any keys that failed to be translated by the AI, so you can easily retry them.
π§ Troubleshooting
Error / Issue | Common Cause | Solution |
---|---|---|
"Invalid API key" | The GEMINI_API_KEY in your .env file is incorrect or missing. |
Verify the key is correct and has no extra spaces. Run php artisan config:cache after changes. |
"Quota exceeded" or "Rate limit" errors | The free tier API limit has been reached. | Lower the chunk size with --chunk-size=25 and/or
wait a few minutes before retrying. |
"Call to undefined function pcntl_fork()" | You are trying to use --driver=fork on an
environment without the pcntl PHP extension (like
standard Windows). |
Use the stable driver: --driver=sync . |
Script hangs or runs very slowly | Processing a very large number of keys with the sync driver. |
Be patient, as sync mode is sequential. For large projects, use the fork driver on Linux/macOS/WSL if possible. |
"Invalid JSON response from Gemini" | A rare API issue where the response is not valid JSON, or a network interruption. | The built-in retry logic usually handles this. If it persists, try reducing the
--chunk-size .
|
β Frequently Asked Questions
Q: Can I use this with existing translation files?
A: Yes, and that's its biggest strength! The tool is designed to work with existing
projects. It reads all your current language files to build a complete list of every key your
application knows about. When you run it with --skip-existing
, it
will only translate what's missing, perfectly synchronizing your language files while preserving all
your existing work.
Q: How accurate are the AI translations?
A: Gemini AI provides high-quality translations, but we always recommend a final
review before deploying to production, especially for critical user-facing content or nuanced
language. Using the --context
flag dramatically improves accuracy
for domain-specific projects.
Q: What happens if the translation fails?
A: The command has built-in retry logic with exponential backoff. If a key
consistently fails, it is logged in failed_translation_keys.json
in your project root,
so you can review and handle it manually.
Q: Is this suitable for production applications?
A: Absolutely. It's a powerful developer tool to accelerate the localization workflow. By using it in your development environment and committing the generated/updated language files to your repository, you can safely deploy them to production after a quick review.
π Contributing & Support
How to Contribute
- Report bugs and request features via GitHub Issues.
- Submit pull requests for improvements.
- Star the repository if you find it useful.
Support
If you encounter issues, please check the troubleshooting section first. If the problem persists, create a new issue on GitHub with detailed information, including your OS, PHP version, and the exact command used.