- How do I install be-interactive/laravel-translation-scanner in a Laravel app?
- Install it as a dev dependency with composer require --dev be-interactive/laravel-translation-scanner. Laravel auto-discovers the service provider, the config file is optionally publishable, and a single Artisan scan command produces your first report. There are no migrations, no credentials, and no schema changes, so a working report on a mid-size app is typically under an hour. Pin an exact version in composer.json rather than a caret range given the sparse changelog.
- Does it support Laravel 11 and 12 where the lang directory moved to the project root?
- Laravel 11 moved lang/ from resources/lang/ to the project root, and path configuration is the most common place a scanner silently diverges from the framework. Verify the configured path explicitly on Laravel 11 or 12 before trusting a report, because a wrong path yields an empty catalog and a deceptively clean scan. Confirm the supported PHP and Laravel version matrix against your app's constraints before adopting, since a mismatch here is a hard stop.
- How does the scanner handle dynamic translation keys like __('errors.'.$code)?
- Static scanning cannot resolve keys composed at runtime, so expect false positives for patterns like __('errors.'.$code) and treat the output as a heuristic lint rather than ground truth. Keys built dynamically or resolved from third-party packages can also be missed entirely as false negatives. Teams that over-trust a green scan risk shipping untranslated strings, so review findings rather than gating blindly on the first run.
- Can it check trans_choice, @lang, and JSON translation files?
- The scanner targets the common translation call sites including __(), @lang, trans(), and trans_choice(), but pluralization variants and JSON catalogs each have different shapes that assumptions can get wrong. Nested PHP arrays, JSON files, and plural forms are exactly the areas to confirm against a representative repository before you gate CI on the results. Put the question to the maintainer or resolve it in a short spike on your own codebase.
- Does the scanner write to my language files, or is there a dry-run mode?
- The package can produce a report and optionally mutate files under lang/ or resources/lang/, so confirm on your pinned version whether any command writes by default or requires an explicit flag. Start report-only in CI and inspect the diff of any command that can modify catalogs. Keeping the app under version control makes any file mutation fully reviewable and reversible.
- How do I integrate the translation scanner into a CI pipeline without blocking builds?
- Run it first as an informational, non-blocking job to baseline existing debt, scoping paths to exclude vendor and generated code. Once the report is trusted, ratchet to a threshold and make the job blocking. Also check for duplicate CI minutes if another i18n linter already covers unused-key detection, and ensure production builds using composer install --no-dev never reference the tool.
- Should this package go in require-dev, and does it affect production?
- Yes, it is developer tooling rather than runtime infrastructure, so it belongs in require-dev and should stay out of production images. It ships Artisan commands plus a report and has no database, queue, or external service dependency, so there is no production service provider surface area to worry about. Removing the single Composer dependency fully reverses the install.
- Does it detect vendor namespaced keys such as package::file.key?
- Namespaced keys resolve through package catalogs rather than your app's lang files, which makes them a frequent source of false positives or missed entries depending on how the scanner treats them. Test against a repository that actually uses package translations, or ask the maintainer directly. This is worth verifying before you treat unused-key findings as actionable.
- How is this different from a translation management system or other i18n linters?
- It is a lint rule that reconciles static key usage against file-based catalogs, not a translation management system, so treat it as a shift-left quality gate alongside Pint, PHPStan, and Pest. If your app resolves translations at runtime from a database, headless CMS, or third-party TMS, the scanner's source of truth is not your source of truth and the fit is poor. Overlap with existing unused-key checks is possible, so decide deliberately whether to run both.
- Is it safe to upgrade to v5.6.3 when the changelog is empty?
- Version 5.6.3 is published with only a compare-link changelog, so the actual diff is unverified even though a patch bump implies no intended breaking change. Parser fixes and config default changes both land in patch releases and both alter scan output, so pin an exact version and read the diff before bumping. Re-evaluate deliberately on each release rather than accepting a caret range.