PHP 8.1+ Laravel 10+ AI Powered

πŸ“‹ 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
Windows Users: Because Windows does not natively support the 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

Free Tier Limits: The free tier has limits on requests per minute/day. For large projects, consider using smaller chunk sizes or processing in batches to stay within these limits.

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:

  1. 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.
  2. File Selection: Prompts you to choose which translation file groups (e.g., `messages.php`, `auth.php`, JSON file) you wish to process.
  3. Cross-Check & Analysis: Reports exactly which keys are missing in your target languages, showing you what needs to be synchronized.
  4. AI Translation: Sends the missing keys and their source text to Gemini AI for translation, showing a real-time progress bar.
  5. File Generation: Intelligently writes the new translations to the correct language files, merging them with existing content.
Pro Tip: Press the '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.

Security: If you discover a security vulnerability, please email the maintainer directly rather than creating a public issue.