mohammadtrabelsi/laravel-translation-sync
| Install | |
|---|---|
composer require mohammadtrabelsi/laravel-translation-sync |
|
| Latest Version: | 1.2.2 |
| PHP: | ^8.2 |
| Laravel: | 11 · 12 · 13 |
| License: | MIT |
| Last Updated: | Nov 2, 2026 |
| Links: | GitHub · Packagist |
Laravel Translation Sync
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.
Related Packages
Laravel package to sync translations with SmartPMS Translation Manager
Minimal i18n for Laravel Inertia — share PHP and JSON translations with t() and...
Bridge Laravel JSON translations with React apps built on Inertia.js
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| 1.2.2 | ^8.2 | ^11.0|| | MIT | |
| 1.2.1 | ^8.2 | ^11.0|| | MIT | |
| 1.2.0 | ^8.2 | ^11.0|| | MIT | |
| v1.1.0 | ^8.2 | ^11.0|| | MIT | |
| 1.0.0 | ^8.2 | ^11.0|| | MIT |