janakkapadia / insta-translate
AI-powered translation management for Laravel using laravel/ai. Supports glossary protection, context-aware translations, PHP array files, and stale key pruning.
Package info
github.com/janakkapadia/insta-translate
Language:Blade
pkg:composer/janakkapadia/insta-translate
Requires
- php: ^8.3
- illuminate/support: ^12.0||^13.0
- laravel/ai: ^0.9.0
Requires (Dev)
- larastan/larastan: ^3.9
- laravel/pao: ^1.0
- laravel/pint: ^1.29
- orchestra/testbench: ^10.0||^11.0
- pestphp/pest: ^4.6
- pestphp/pest-plugin-laravel: ^4.1
- pestphp/pest-plugin-type-coverage: ^4.0
- phpstan/extension-installer: ^1.4
This package is auto-updated.
Last update: 2026-07-29 17:46:45 UTC
README
A lightweight Laravel package that leverages AI (via laravel/ai) to automatically translate language strings for your application. It replaces traditional translation management platforms by using AI to directly sync and translate missing keys in your lang/ files.
Features
- Automated Translation: Diffs your base locale (
en.json) against target locales and translates only the missing keys. - Web Dashboard UI: A beautiful, interactive dashboard to visually inspect missing translations, run AI translations in the browser, and review them before saving.
- Add New Languages: Seamlessly add new target languages directly from the Web UI.
- Batched Generation & Rate Limiting: Robustly handles thousands of missing translations by breaking them into automated batches of 100, including smart retry logic and 30-second cooldowns on API rate limits.
- Multiple AI Providers: Use any provider supported by
laravel/ai— Anthropic Claude, Google Gemini, OpenAI, and more. - Glossary Protection: Define brand names, technical terms, and locale-specific overrides that the AI must respect.
- Context-Aware: Pass domain context (e.g., "SaaS billing dashboard") so the AI produces more accurate translations.
- PHP Array Files: Translate both JSON (
lang/en.json) and PHP array (lang/en/auth.php) translation files. - Stale Key Pruning: Automatically detect and remove translation keys that no longer exist in your base language.
- Multiple Variations: Generate 3 translation options per key and interactively choose the best one.
- Forced Full Translation: Option to re-translate all keys entirely.
Installation
This package is installed locally via a path repository. It is already registered in composer.json under:
"repositories": [ { "type": "path", "url": "packages/*" } ]
Configuration
Add the following environment variables to your .env file to configure InstaTranslate:
# Set the default model (e.g., claude-3-5-sonnet-20241022, gemini-1.5-pro) # "claude" and "gemini" are also accepted as shorthands for default models. INSTA_TRANSLATE_MODEL=claude # Path to your language files (defaults to the laravel lang directory) INSTA_TRANSLATE_LANG_PATH=./lang # The base language to translate from (defaults to "en") INSTA_TRANSLATE_DEFAULT_LANGUAGE=en # Add your API Keys (managed automatically by Laravel AI SDK) ANTHROPIC_API_KEY=your_anthropic_api_key_here GEMINI_API_KEY=your_google_gemini_api_key_here
You can optionally publish the configuration file to customize the default model behavior:
php artisan vendor:publish --tag="insta-translate-config"
Usage
Generating Translations
php artisan translation:generate
Options
| Option | Description | Example |
|---|---|---|
--batch= |
Number of keys per API request. Defaults to 50. |
--batch=100 |
--model= |
Override the default model. Accepts shorthand (claude, gemini) or exact versions. |
--model=gemini-1.5-pro |
--lang= |
Target a single locale, creating it if it doesn't exist. | --lang=nl |
--key= |
Translate specific key(s). Can be used multiple times. | --key="Welcome" --key="Goodbye" |
--multiple |
Generate 3 translation variations per key and choose interactively. | --key="foo" --multiple |
--all |
Re-translate all keys, overwriting existing translations. | --all |
--context= |
Provide domain context for more accurate translations. | --context="SaaS billing dashboard" |
--php |
Process PHP array files (lang/en/*.php) instead of JSON. |
--php |
Pruning Stale Keys
Remove translation keys from target locales that no longer exist in the base language file:
# Preview what would be removed (safe) php artisan translation:prune --dry-run # Actually remove stale keys php artisan translation:prune # Prune a specific locale php artisan translation:prune --lang=fr # Prune PHP array files php artisan translation:prune --php --dry-run
Glossary
Create a glossary.json file in your lang/ directory to protect brand names and define locale-specific translations:
{
"never_translate": ["InstaRequest", "Laravel", "Stripe", "API"],
"specific_translations": {
"Dashboard": {
"hi": "डैशबोर्ड",
"fr": "Tableau de bord"
}
}
}
never_translate: Terms that must remain exactly as-is in every language (brand names, technical terms).specific_translations: Per-locale overrides for specific terms. These are injected into the AI prompt and also applied as post-processing replacements.
The glossary path defaults to lang/glossary.json and can be overridden via:
INSTA_TRANSLATE_GLOSSARY_PATH=./lang/glossary.json
Dashboard Web UI
InstaTranslate includes a beautiful, interactive web dashboard where you can visually inspect missing translations, run AI translations in the browser, review them before saving, and even add new languages to your project.
Click on any image to view it in full size.
- Ensure the package service provider is registered (this is automatic in Laravel 11+).
- Visit
/insta-translatein your browser (e.g.https://your-app.test/insta-translate).
If you have custom domains configured in your application (like a wildcard Route::domain() catch-all), you may need to explicitly configure the dashboard's domain in your environment or published config file:
# In your .env file INSTA_TRANSLATE_DOMAIN=your-app.test
Context-Aware UI Translation
When regenerating a specific translation key from the dashboard's slide-over panel, you have two powerful ways to ensure the AI translates the key accurately:
- Automatic Code Context: If you leave the context field blank, InstaTranslate will automatically scan your
resources/views,app,routes, andresources/jsdirectories to find exactly where that key is used in your codebase. It grabs the surrounding lines of code and injects them into the AI prompt so the AI can physically "see" how the text is used (e.g. as a button label, a validation error, etc.). - Manual Context: You can provide a manual context hint (e.g. "Lead as in a sales lead, not the metal") in the Optional Context text box. This manual hint will override the automatic code context.
Dashboard Configuration Options
You can customize the dashboard route and domain by publishing the config file:
php artisan vendor:publish --tag="insta-translate-config"
Then in config/insta-translate.php:
'domain' => env('INSTA_TRANSLATE_DOMAIN', null), 'path' => env('INSTA_TRANSLATE_PATH', 'insta-translate'), 'middleware' => env('INSTA_TRANSLATE_MIDDLEWARE', ['web']),
Authorization
By default, you will only be able to access the dashboard in the local environment. To restrict or allow access in other environments, you can define an authorization callback in your App\Providers\AppServiceProvider.
Use the InstaTranslate::auth method to define logic that determines whether the current request is allowed to access the dashboard:
use JanakKapadia\InstaTranslate\InstaTranslate; public function boot(): void { InstaTranslate::auth(function ($request) { // Return true to allow access, false to deny (403) return app()->environment('local') || in_array($request->user()?->email, [ 'admin@example.com', ]); }); }
How It Works
- The command or dashboard reads the base language file (e.g.,
en.jsonoren/*.php). - It iterates over all target locale files.
- For each locale, it identifies keys that exist in the base file but are missing in the target (unless
--allis passed). - Glossary terms and context are injected into the AI prompt.
- Missing keys are batched and sent to the AI model via
laravel/ai. - Glossary overrides are applied to the AI response.
- Translations are merged, sorted alphabetically, and saved.
Support
If you find InstaTranslate helpful, consider supporting its ongoing development: