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 Translation Scanner Laravel Package

be-interactive/laravel-translation-scanner

Scan your Laravel app for translation keys used in Blade, PHP, and JavaScript, compare them against your language files, and quickly spot missing or unused translations to keep every locale in sync.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a patch release (5.6.3) on the 5.x line — no breaking changes, no new features announced. If you're already on 5.6.x, composer update be-interactive/laravel-translation-scanner is safe; treat it as a bugfix bump and check the diff link in the release notes if you hit anything odd.

First steps for a fresh install:

  1. Install as a dev dependency — this is a local/CI tool, not runtime code:
    composer require --dev be-interactive/laravel-translation-scanner
    
  2. Run the command once against your default locale to see the shape of the output:
    php artisan translation:scan
    
  3. Read php artisan translation:scan --help before scripting anything. This package has evolved its flags across majors, so confirm the exact option names (--path, --translation-file, --json, --sort, filter flags) against the version you actually installed rather than copying snippets from blog posts.
  4. Check whether a config file is publishable in your version (php artisan vendor:publish and look for a translation-scanner tag). If it exists, commit it — that's where path exclusions and the source translation file live.

The first real use case: point it at your lang/en.json (or lang/en/ directory) and get a list of keys that are used in code but missing from the file and keys that are in the file but never used. That second list is the one that pays for the install — it's dead weight you can usually delete after a quick grep.

Implementation Patterns

Local cleanup loop. Run the scan, take the "unused" list, verify each key with a grep (dynamic keys fool the scanner — see Gotchas), delete in batches, re-run. Do this on a branch, not on main, and let the test suite confirm nothing blows up.

Pre-commit / pre-push guard. Add a Composer script so contributors catch missing keys before review:

"scripts": {
    "translations:check": [
        "@php artisan translation:scan --no-interaction"
    ]
}

Wire it into a Husky hook or a composer check aggregate if you already have one.

CI gate. The most valuable pattern is failing the build when a key is used but missing from the source locale. Use the machine-readable output (--json where available) and parse it in a small script rather than grepping the table output — table formatting is cosmetic and changes between releases. Keep the unused-keys side as a warning, not a failure, otherwise the build breaks every time someone stages a feature in two commits.

Locale workflow. Scan against the source locale only (en typically), then propagate keys to other locales via your existing translation pipeline. Running the scanner per-locale mostly produces noise — a key missing from fr is a translation backlog problem, not a code problem.

Pairing with extraction tooling. If you also use a TMS (Crowdin, Lokalise, Phrase) or laravel-lang/* packs, use this scanner as the source-of-truth check on the app side and let the TMS own the downstream locales. Don't let both tools rewrite the same file.

Cleanup cadence. Schedule the scan as a monthly housekeeping task (a scheduled job that opens a ticket, or just a calendar reminder) rather than something you run ad hoc. Translation files only rot slowly, so a periodic sweep beats a heroic one-off cleanup.

Blade and JS components. The scanner is regex-based over your source paths, so make sure the configured paths actually include resources/views and resources/js if you use __() inside Vue/React components — a default config that only covers app/ will silently under-report usage and mark live keys as unused.

Gotchas and Tips

  • Dynamic and concatenated keys are invisible. __($key), trans('messages.' . $type), and keys built from enums or config values will never be matched. Any key flagged "unused" that comes from a dynamic lookup will look like a deletion candidate — deleting it is a production bug. Always grep before deleting, and consider keeping a documented allowlist for these.
  • Pluralization and nested keys. trans_choice, | plural forms, and dot-notation nesting in PHP array files don't always round-trip cleanly. Spot-check the output on a file with plurals before trusting a bulk cleanup.
  • JSON vs. PHP array files. The matching semantics differ (flat dotted keys vs. nested arrays). If your project mixes both, run the scan separately per translation file and don't assume one run covers everything.
  • Exclude aggressively. vendor/, node_modules/, storage/, bootstrap/cache/, and compiled assets will produce garbage matches and slow the scan down. If you can't configure exclusions in your version, narrow the scanned paths instead.
  • False "missing" keys from framework/vendor usage. Keys referenced only by a package's own views won't appear in your source scan. Don't "fix" these by adding them to your app's translation file unless you actually want to override them.
  • Don't auto-commit the rewritten translation file. If your version offers a fix/write mode, diff the result by hand the first few times — key reordering and formatting churn create noisy diffs that hide real changes.
  • Pin the version in CI. A dev-only tool that rewrites or gates on output shape can break your pipeline on a minor bump. Use a caret constraint but commit composer.lock, and read the changelog on minors — patch releases like 5.6.3 are safe to take automatically.
  • Debugging a surprising result: run the command with -v to see which paths were scanned, then reduce to a single file path to confirm the matcher handles your syntax before assuming a parser bug. Nine times out of ten it's a path or exclusion misconfiguration.
  • Extension points are thin. This is a focused CLI tool; don't expect to plug in a custom parser. If you need AST-accurate detection for dynamic keys, that's a separate tool (or a small custom script) — accept the scanner as a fast heuristic, not a proof.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib