larswiegers/laravel-translations-checker
Find missing Laravel translations fast. Run php artisan translations:check to compare languages and see what keys are missing and where. Supports custom lang directories plus excluding vendor paths, specific languages, and file extensions for cleaner results.
Installation:
composer require --dev larswiegers/laravel-translations-checker
Add the package as a dev dependency to avoid bloating production builds.
First Run: Execute the command in your project root:
php artisan translations:check
This scans the default resources/lang directory for missing translations across all supported languages.
Quick Check: For a one-time sanity check before a release, run:
php artisan translations:check --directory=resources/lang --excludedDirectories=vendor
This excludes vendor-specific translations (common in packages like laravel-ui).
nl/passwords.php) or keys (e.g., nl.passwords.reset).config/translation-checker.php (auto-generated) for customization options.Scenario: Your team adds a new translation key (auth.login.failed) in English but forgets to include it in French (fr/auth.php). Users report seeing raw keys (auth.login.failed) in production.
Solution:
php artisan translations:check
Missing the translation with key: fr.auth.login.failed
resources/lang/fr/auth.php and re-run the check to confirm resolution.Development Phase:
php artisan translations:check --directory=resources/lang/custom
(Useful for custom language directories.)CI/CD Integration:
- name: Check translations
run: php artisan translations:check --excludedDirectories=vendor,storage
php artisan translations:check || exit 1
Exclusion Strategies:
vendor/lang or lang/vendor:
'excluded_directories' => ['vendor/*', 'lang/vendor'],
.php files if using JSON-only translations:
php artisan translations:check --excludedFileExtensions=php
'exclude_languages' => ['en', 'test'],
Custom Directories:
If translations are stored outside resources/lang (e.g., app/translations), specify the directory:
php artisan translations:check --directory=app/translations
Partial Checks: Validate only specific languages during development:
php artisan translations:check --languages=es,fr
Blade Directives:
The checker works with @lang directives and __() helpers. Ensure all dynamic keys (e.g., @lang('auth.login')) are statically defined in translation files.
Dynamic Keys:
For runtime-generated keys (e.g., Lang::get("user.$id")), the checker cannot detect them. Document these cases in your team’s translation guidelines.
JSON vs. PHP: The package supports both formats. Prefer JSON for simpler projects (easier to diff) and PHP for complex nested structures (e.g., arrays).
False Negatives:
Lang::get("key.$id")) are ignored. Solution: Use static keys where possible or document exceptions.resources/lang/fr doesn’t exist), the checker won’t flag nested files (e.g., fr/auth.php). Solution: Ensure all language directories exist, even if empty.Performance:
Configuration Overrides:
php artisan translations:check --directory=custom/path --excludedFileExtensions=php
This ignores config/translation-checker.php for this run.Case Sensitivity:
fr ≠ FR). Solution: Use lowercase consistently.Silent Failures: If the command runs but doesn’t output errors, verify:
resources/lang directory exists.lang folder isn’t excluded (check excluded_directories).Empty Files:
The checker skips empty files. Solution: Add a placeholder (e.g., return [];) to PHP files or {} to JSON files.
Mac Files:
Hidden .DS_Store files (common on macOS) may cause errors. Solution: Exclude them:
php artisan translations:check --excludedFileExtensions=DS_Store
CI Optimization: Cache dependencies to speed up CI runs:
- name: Install Dependencies
run: composer install --optimize-autoloader --no-dev
- name: Run translations check
run: php artisan translations:check
Team Adoption:
package.json scripts for frontend teams:
"scripts": {
"check:translations": "php artisan translations:check"
}
npm install husky --save-dev
npx husky add .husky/pre-commit "php artisan translations:check"
Partial Validation: For large projects, validate incrementally:
# Check only auth-related files
php artisan translations:check --directory=resources/lang --excludedFileExtensions=*.php --languages=es,fr
Custom Output: Redirect output to a file for auditing:
php artisan translations:check > missing_translations.txt
Laravel 11+:
The package supports Laravel’s new lang directory structure (e.g., lang/en/auth.php). No changes needed—it works out of the box.
Custom Validators: Extend the checker by creating a custom command that integrates with the package’s logic. Example:
use LarsWiegers\TranslationChecker\TranslationChecker;
class CustomTranslationChecker extends Command {
protected function handle() {
$checker = new TranslationChecker();
$results = $checker->check($this->option('directory'));
// Add custom logic (e.g., Slack notifications for critical misses)
foreach ($results->missingKeys() as $key) {
if (str_contains($key, 'auth.')) {
$this->error("Critical auth key missing: $key");
}
}
}
}
Database-Backed Translations: The package doesn’t support database-driven translations. Workaround: Use a pre-commit hook to validate JSON/PHP files against a snapshot of DB translations.
Multi-Project Monorepos: For monorepos, specify project-specific directories:
php artisan translations:check --directory=packages/auth/resources/lang
How can I help you explore Laravel packages today?