Laravel
The package neiderruiz/translate-projects-laravel extracts the texts from __(), trans() and @lang() into lang/<base locale>.json, translates them and writes lang/en.json, lang/pt_BR.json, etc., which Laravel uses directly.
Requirements
- PHP 8.1 or higher and Laravel 10, 11, 12 or 13.
- A Translate Projects project and an API token. See Getting started.
1. Install the package
composer require neiderruiz/translate-projects-laravel
php artisan vendor:publish --tag=translate-config # Optional
2. Configure the .env
TRANSLATE_PROJECTS_API_KEY=tu_token
APP_LOCALE=es
TRANSLATE_PROJECTS_TARGET_LANGUAGES=en,pt-BR,fr
Key in config/translate-projects.php | Environment variable | Default |
|---|---|---|
api_key | TRANSLATE_PROJECTS_API_KEY | — |
api_url | TRANSLATE_PROJECTS_API_URL | https://api.translateprojects.dev |
default_locale | TRANSLATE_PROJECTS_DEFAULT_LOCALE or APP_LOCALE | en |
target_languages | TRANSLATE_PROJECTS_TARGET_LANGUAGES (comma-separated) | es,fr,de,it |
scan_paths | — | app, resources, routes |
default_locale must match the project's default language in Translate Projects. Codes can be written as pt-BR, pt_BR or pt-br: the package uses pt-BR with the API and pt_BR in the file name, as Laravel expects. If you use php artisan config:cache, run php artisan config:clear after changing the .env.
3. Mark your texts
Route::get('/', fn () => __('Bienvenido a mi aplicación'));
<h1>{{ __('Hola mundo') }}</h1>
<p>{{ __('Bienvenido, :name', ['name' => $user->name]) }}</p>
<p>@lang('Este texto también se traduce')</p>
4. Extract and translate
php artisan translate:scan # Extracts the texts to lang/es.json
php artisan translate # Translates to all target languages
php artisan translate pt-BR # Only one language
php artisan translate --force # Translates even if there are no changes
translate:scanlooks for__('...'),trans('...'),trans_choice('...')and@lang('...')with a literal text. It adds the new texts tolang/<base locale>.jsonand keeps the ones that were already there. It skips group keys (such asauth.failed) and package keys (pkg::file.key).translateuploads the texts only if they changed, waits for the backend and writeslang/<locale>.json. It keeps the entries that were already in that file, for example translations made by hand.
Files it generates
lang/
├── es.json ← base locale (generated by translate:scan)
├── en.json
├── pt_BR.json
├── fr.json
└── .translate-projects.json ← cache
Cache and --force
lang/.translate-projects.json stores which version each language has: a second run without changes makes a single request and translates nothing. Use --force to translate again even if there are no changes. More details in Cache and errors.
Common errors
The command never leaves a file half-written or deletes it.
TRANSLATE_PROJECTS_API_KEYis missing: it fails without making any requests. If you useconfig:cache, runconfig:clear.No se encontró o no es válido lang/es.json: you haven't extracted the texts yet: runphp artisan translate:scan.El idioma de origen no es el predeterminadoorEl idioma de destino no está activo en tu proyecto: check the project's default language or activate that language in the panel.- Invalid token or 4xx error: shows the code and the API message and does not touch the files.
- Error 429, 5xx or network error: retries 3 times; if it still fails, leaves that language as it was and continues with the others.
- Missing AI key (
MISSING_API_KEY): writes what was received, reports how many texts are missing and retries them on the next run. - Placeholders: if the AI changes a
:placeholder, that translation is discarded and Laravel shows the original text.
Limitations
- Only JSON files are translated (texts used as keys). Group files
lang/<locale>/*.phpare not uploaded. - Dynamic keys such as
__($variable)are not detected.
🚀 Automate your translations for free
Translate Projects is free. You create your project, connect your AI provider's key, and only pay them what you spend.
- No plans or credit card required: All features are available from day one.
- Use your own AI: Claude, OpenAI, DeepSeek, or Gemini. Your key is stored encrypted.
- Shared translation network: If a text has already been translated, you receive it instantly without spending your key.
- Admin panel: Review and edit all your translations from one place.
We're here to help
If you have any questions, need help, or want to contribute, don't hesitate to contact me. I'm available to support you with whatever you need.
- Website: neiderruiz.com
- GitHub: @neiderruiz
- Twitter: @neiderruiz
- YouTube: Neider Ruiz
Support the Project
If this project has been helpful to you, I invite you to buy me a coffee. Your support helps me keep improving and creating valuable content. Thanks for being here! ☕