tunahan-genc / laravel-lang-harvest
Scan Laravel projects for static translation strings and sync them to JSON and PHP language files.
Package info
github.com/Tunahangncc/laravel-lang-harvest
pkg:composer/tunahan-genc/laravel-lang-harvest
Requires
- php: ^8.3
- illuminate/support: ^12.0||^13.0
- nikic/php-parser: ^5.8
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
README
Laravel Lang Harvest
Scan Laravel projects for static translation strings and sync them to JSON and PHP language files.
Installation
You can install the package via Composer:
composer require tunahan-genc/laravel-lang-harvest
You may publish all of the package's resources at once:
php artisan vendor:publish --tag="laravel-lang-harvest"
Or, you may publish each resource individually:
Publishing the Configuration File
php artisan vendor:publish --tag="laravel-lang-harvest-config"
Usage
After publishing the config, adjust config/laravel-lang-harvest.php to match your project (scan paths, excluded directories, locale, placeholder format), then run:
php artisan lang:harvest
This scans the configured paths for __(), trans(), trans_choice(), @lang(), @choice(), and Lang::get() calls, and adds any missing keys to your lang/{locale}/{group}.php and lang/{locale}.json files. Existing values are never overwritten — only missing keys are added.
Dotted keys vs. plain text
__('arac.lastik-gecmisi')→ written tolang/en/arac.phpas'lastik-gecmisi' => '[arac.lastik-gecmisi]'__('profile.edit.title')→ written tolang/en/profile.phpas a nested array:'edit' => ['title' => '[profile.edit.title]']__('Welcome to our site!')→ written tolang/en.jsonas"Welcome to our site!": "Welcome to our site!"
Only strings matching word(.word)+ (letters, numbers, underscores, and hyphens joined by dots) are treated as dotted/group keys; everything else is treated as plain text for the JSON file.
Options
# Preview what would be added, without writing any files php artisan lang:harvest --dry-run # Same as --dry-run, but exits with a non-zero status if anything is # missing or needs manual review (useful in CI) php artisan lang:harvest --check
Dynamic calls (e.g. trans($key), __("prefix.{$suffix}")) are always skipped and reported separately — they are never guessed at.
A ternary with two static branches (e.g. __($isEdit ? 'Edit Post' : 'Create New Post')) is a special case: since every possible outcome is known ahead of time, both branches are harvested. If any branch of a ternary is itself dynamic, the whole call is skipped and reported instead — no partial harvesting.
Configuration
return [ // Falls back to config('app.locale') when null 'locale' => env('LANG_HARVEST_LOCALE'), // Relative to the application's base path (absolute paths also work) 'paths' => ['app', 'resources/views'], 'exclude' => ['vendor', 'node_modules', 'storage', 'bootstrap/cache', 'tests'], // %s is replaced with the full dotted key 'placeholder' => '[%s]', ];
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Thank you for considering contributing to Laravel Lang Harvest! Please review our contributing guide to get started.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
Laravel Lang Harvest is open-sourced software licensed under the MIT license.