Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Find Missing Translations Laravel Package

diglabby/laravel-find-missing-translations

A Laravel artisan command that scans your app for translation keys and reports any missing from your language files, so you can keep every locale complete and catch untranslated strings before they ship.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install as a dev dependency: composer require --dev diglabby/laravel-find-missing-translations. There is no service provider config to publish for the basic use case — package discovery registers the artisan command for you.
  • After installing, run php artisan list and look for the package's command (it is registered under the translations namespace, e.g. translations:missing). That confirms discovery worked before you start tuning anything.
  • First real use case: run it for your primary locale only, e.g. php artisan translations:missing --locale=en. This gives you the smallest useful signal — keys referenced in code (via __(), trans(), @lang) that do not exist in lang/en.
  • Look at the output before touching config. The default report tells you which keys are missing; add --verbose on the second run to get the per-file detail (which file declared the locale, which key is absent). On 1.8.1 the verbose line now names the file that declares a locale, which is the fastest way to understand why the tool thinks a locale exists.
  • If the output is empty on a project you know has gaps, your lang path is probably not where the package expects it (root lang/ in Laravel 9+ vs resources/lang/ in older apps). Check that first, before assuming a bug.

Implementation Patterns

  • Per-locale loop in CI. The command is naturally scoped by --locale. Wrap it in a small shell step so each locale produces its own report:
    for locale in en de fr; do
      php artisan translations:missing --locale=$locale || exit 1
    done
    
    This keeps failures attributable — a red build tells you which locale regressed, not just that something did.
  • Gate on the exit code, fall back to grep. If the command returns non-zero when keys are missing, use it directly as a CI gate. If it always exits 0 in your version, pipe through grep -q on a known header and fail the step yourself. Verify the exit code once, then codify it — don't assume.
  • Narrow the scope while refactoring. When you are actively moving translations around, run the command against a single translation file/group rather than the whole app, so the report stays short enough to act on in one sitting.
  • Pair with a write-side tool. This package finds gaps; it does not create keys. A common workflow is: run missing-translations to get the list, then use a key-sorting/filling tool (or a small script) to add the keys to lang/en, then re-run to confirm zero output.
  • New-locale onboarding. Before announcing a new locale, run the command for it and diff the result against your en baseline. Because 1.8.1 treats a locale as declared if it exists as either a lang/<locale>/ directory or a lang/<locale>.json file, a JSON-only locale (common for JS-side strings) is now correctly recognised — so a "missing locale" report for a JSON-only locale is a real finding, not a false alarm.
  • Keep it dev-only. Do not promote this to a production dependency; it belongs in require-dev alongside PHPUnit/Pint, and it should never run on a request path.

Gotchas and Tips

  • Dynamic keys are invisible. __($key), trans("messages.{$type}"), and keys built from config are not resolvable statically. The command will not report them as missing, and it will not report them as present either. Do not read a clean report as proof of full coverage.
  • Locale declaration is now format-agnostic (1.8.1). A locale counts as declared whether it ships as a directory (lang/de/) or a single JSON file (lang/de.json). If you were on 1.8.0 and saw a JSON-only locale skipped or wrongly reported, re-run after upgrading — the results for those locales will change. This is a behaviour fix, not a new flag, so no config change is needed.
  • Verbose output now names the declaring file. When two sources could plausibly declare the same locale (e.g. both lang/de/ and lang/de.json exist), the verbose line tells you which one the tool used. Use this whenever the report contradicts what you see on disk.
  • Path resolution is the #1 source of "it found nothing". Laravel 9+ moved the lang directory from resources/lang to the project root lang/. If the package's configured paths don't match your layout, you get a silent, clean report. Sanity-check by temporarily adding a deliberately missing key to a Blade view and confirming it shows up.
  • Vendor translations pollute the picture. Translations shipped inside vendor/ packages are not yours to fix. Make sure the scan is limited to your application's lang directory and your own source paths, or you will chase keys you cannot resolve.
  • Nested arrays vs dot notation. lang/en/messages.php returning ['auth' => ['failed' => '...']] is keyed as messages.auth.failed. If your code uses a different separator or a flat file with literal dots in the key, the lookup will disagree with the tool. When a key is reported missing but you can see it, this mismatch is almost always the cause.
  • Pluralisation and trans_choice. Strings selected via trans_choice have pipe-delimited variants; confirm they are recognised by your version before treating a report as authoritative for those keys.
  • Debugging order: (1) php artisan list confirms the command is registered, (2) run with --verbose to see the resolved lang paths and declaring files, (3) -vvv if the command supports Symfony verbosity for the underlying scan, (4) only then suspect the package. Nearly every surprising result traces back to path config or dynamic keys.
  • Extension points are thin by design. This is a reporting command, not a translation-management system — expect to integrate at the shell/CI level (exit codes, output parsing) rather than through Laravel events or custom drivers. If you need programmatic access, prefer shelling out and parsing over reaching into package internals, which are not covered by a stability promise across minor releases.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console