mohammadtrabelsi / laravel-translation-sync
Scan your Laravel app (views, Livewire components, services and laravel-modules) for translation keys and sync them across every locale with a single artisan command.
Package info
github.com/Mohammadtrabelsi/laravel-translations-sync
pkg:composer/mohammadtrabelsi/laravel-translation-sync
Requires
- php: ^8.2
- illuminate/console: ^11.0||^12.0||^13.0
- illuminate/support: ^11.0||^12.0||^13.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Scan your entire Laravel application for translation keys and keep every locale in sync with a single artisan command.
It walks your resources/, Livewire component classes and blade views,
app/Services, and every module under a
laravel-modules Modules/ tree,
extracts every key used with __(), trans(), @lang() or trans_choice(),
creates any missing lang/{locale}/*.php files, and adds the missing keys to
every locale so nothing is left untranslated.
Requirements
- PHP
^8.2 - Laravel 11, 12 or 13
Installation
composer require mohammadtrabelsi/laravel-translation-sync
The service provider is auto-discovered, so there is nothing else to register.
Upgrading from a local copy of the command? Delete your own
app/Console/Commands/SyncTranslationKeys.php(or any other command with thetranslations:syncsignature). Laravel runs the app's command instead of the package's, so older behaviour, such as writing flat'group.key' => '[TODO] …'entries next to nested arrays, would keep happening. The package prints a warning when it detects such an override.
Usage
php artisan translations:sync
Options
| Option | Description |
|---|---|
--locales=en,fr,ar |
Comma-separated locales to sync. Defaults to auto-detecting the lang/ sub-directories. |
--base=en |
The reference locale used as the source of truth (default en). |
--dry-run |
Show what would change without writing any files. |
--clean |
Also remove keys from lang files that no longer appear in the code. |
Examples
# Preview the changes without touching any files php artisan translations:sync --dry-run # Sync a specific set of locales, using French as the base php artisan translations:sync --locales=fr,en,ar --base=fr # Sync and prune keys that were deleted from the code php artisan translations:sync --clean
How keys are grouped
Keys are grouped by their file prefix:
__('auth.failed')→lang/{locale}/auth.phpunder thefailedkey.__('Hello world')(a plain string with no group) →lang/{locale}/strings.php.
Further dots nest the key, the same way Laravel resolves it:
__('office.fields.name')→lang/{locale}/office.phpas'fields' => ['name' => …].__('settings.admin.fields.temperature')→lang/{locale}/settings.phpas'admin' => ['fields' => ['temperature' => …]].
Keys that are already translated in nested form are detected and left alone.
Flat dotted entries such as 'fields.name' => '…' (written by older versions)
are folded into the nested array, or dropped when the nested entry already
exists. Partial keys built at runtime, like __('admin.fields.'.$field), are
skipped.
For the base locale a missing key gets a human-friendly placeholder derived from
the key itself (welcome_back → Welcome back). For other locales the missing
value is prefixed with [TODO] and seeded from the base translation so you can
easily find what still needs translating.
License
The MIT License (MIT). See LICENSE.