simonecerruti/laravel-translation-audit
Audit your Laravel translation files from the command line: spot missing keys, unused strings, duplicate entries, and inconsistencies across locales so every language stays complete and in sync. A lightweight PHP dev tool for cleaner, more reliable localization before shipping.
laravel-translation-audit-github-workflow (the old laravel-translation-audit-workflow tag no longer works). The laravel-translation-audit tag publishes config, GitHub workflow, and the new GitLab CI job together; the GitLab job alone is laravel-translation-audit-gitlab-workflow.__('payments.'.$method) resolve through Laravel's translator, so they are checked like static keys.translation:purge-unused on a branch, review the output and diff before committing deletions.unused_ignore_paths is gone and merged into ignore_paths, and published configs that define their own ignore_paths must re-add the Laravel translation defaults or translation:purge-unused will remove framework translation files..gitlab/ci/audit-translations.yml with php artisan vendor:publish --tag="laravel-translation-audit-gitlab-workflow" and include it from .gitlab-ci.yml. It runs translation:audit on pushes to the default branch, merge requests, and web-UI pipelines.AuditType enum (Missing or Unused, or its string value). For example 'database/seeders/**' => AuditType::Missing, 'en' => AuditType::Missing, 'Bye' => AuditType::Missing, or 'Ciao' => ['en', AuditType::Unused].translation:purge-unused keeps them. A file ignored only for the unused audit is still checked for missing translations. Use this to keep runtime-built key sources out of purge while still auditing them.'en' => AuditType::Missing when English keys are the source text; you still get unused-key reporting and purging for that locale.'ipmi' => ['type' => ['help' => ...]], because keys under an array key containing dots cannot be resolved.validation.password and framework-provided keys are no longer reported as missing.translation:purge-unused: unused detection is largely static, so runtime-built keys may need allowlisting, exclusion, or an AuditType-scoped ignore rule.AuditCommand, the TranslationKeyResolver and Result contracts and results, Data\Translation, DisplayFormat/SaveFormat enums, and InvalidConfigException. Everything else is @internal and may change in any release; AuditTranslationsResult::withUnused() and jsonSections() are explicitly internal despite living on a public class.final. Do not plan on extending commands, results, or the service provider — use composition, config, or implement the TranslationKeyResolver / Result contracts instead.unused_ignore_paths no longer exists. If your published config defines its own ignore_paths, you must add the former defaults yourself, mapped to AuditType::Unused, e.g. 'lang/*/validation.php' => AuditType::Unused. Skip this and Laravel's own translation files are reported as unused and deleted by translation:purge-unused.ignore_paths, ignore_locales, and ignore_keys now take per-audit mappings (AuditType case or value), not plain string lists. Audit any custom entries in these arrays during the upgrade.--tag="laravel-translation-audit-workflow" will fail silently-ish — update them to laravel-translation-audit-github-workflow.final classes break any extension points you relied on (custom command subclasses, result subclasses, service provider overrides). Refactor to composition or the resolver/result contracts before upgrading.'ipmi.type' => ['help' => ...] can be reported as missing because the translator cannot resolve it. Restructure as nested arrays.translation:purge-unused may flag dynamically constructed keys as unused. Review removals carefully, or exclude them with an unused-scoped ignore rule.validation.password are valid and should not be chased as missing.How can I help you explore Laravel packages today?