Laravel Missing Translations: Find &amp; Clean JSON Keys | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Laravel Missing Translations: Automatically Find, Add &amp; Clean JSON Translation Keys        On this page       1. [  🚀 Get the Package ](#get-the-package)
2. [  What Is Laravel Missing Translations? ](#what-is-laravel-missing-translations)
3. [  Why This Package Exists ](#why-this-package-exists)
4. [  Installation ](#installation)
5. [  Basic Usage ](#basic-usage)
6. [  Using the Default Application Locale ](#using-the-default-application-locale)
7. [  Preview Missing Translations Without Writing Files ](#preview-missing-translations-without-writing-files)
8. [  Scan All Existing Locale Files ](#scan-all-existing-locale-files)
9. [  Remove Unused Translation Keys ](#remove-unused-translation-keys)
10. [  JSON Output for CI Pipelines ](#json-output-for-ci-pipelines)
11. [  Example GitHub Actions Workflow ](#example-github-actions-workflow)
12. [  Supported Translation Calls ](#supported-translation-calls)
13. [  Filament Support ](#filament-support)
14. [  Filament Field Example ](#filament-field-example)
15. [  Filament Table Column Example ](#filament-table-column-example)
16. [  Filament Action Example ](#filament-action-example)
17. [  Detecting Structural Filament Components ](#detecting-structural-filament-components)
18. [  Auto-Generated Filament Labels ](#auto-generated-filament-labels)
19. [  Avoiding Double Counting ](#avoiding-double-counting)
20. [  Configuration ](#configuration)
21. [  Customizing Scan Paths ](#customizing-scan-paths)
22. [  Excluding Paths ](#excluding-paths)
23. [  Excluding Dot Keys ](#excluding-dot-keys)
24. [  Ignoring Package Translation Keys ](#ignoring-package-translation-keys)
25. [  Excluding Keys by Pattern ](#excluding-keys-by-pattern)
26. [  Sorting Keys ](#sorting-keys)
27. [  JSON Encoding Flags ](#json-encoding-flags)
28. [  Real Example ](#real-example)
29. [  Suggested Workflow ](#suggested-workflow)
30. [  When Should You Use This Package? ](#when-should-you-use-this-package)
31. [  What This Package Is Not ](#what-this-package-is-not)
32. [  Best Practices ](#best-practices)
33. [  1. Use Dry Run Before Writing ](#1-use-dry-run-before-writing)
34. [  2. Commit Translation Changes Separately ](#2-commit-translation-changes-separately)
35. [  3. Avoid Dynamic Translation Keys When Possible ](#3-avoid-dynamic-translation-keys-when-possible)
36. [  4. Use JSON Files for User-Facing Strings ](#4-use-json-files-for-user-facing-strings)
37. [  5. Review Unused Keys Carefully ](#5-review-unused-keys-carefully)
38. [  Why Filament Developers Will Like It ](#why-filament-developers-will-like-it)
39. [  How It Works Internally ](#how-it-works-internally)
40. [  Example Before and After ](#example-before-and-after)
41. [  Final Thoughts ](#final-thoughts)

  ![Laravel Missing Translations: Automatically Find, Add & Clean JSON Translation Keys](https://cdn.msaied.com/213/01KV7VNFKGBRCWKM0HM5CVWVCY.png)

 [  Laravel ](https://msaied.com/articles?category=laravel) [  Composer Pacakge ](https://msaied.com/articles?category=composer-pacakge) [  Filament ](https://msaied.com/articles?category=filament) 

 Laravel Missing Translations: Automatically Find, Add &amp; Clean JSON Translation Keys 
=========================================================================================

     16 Jun 2026      8 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  41 sections  

1. [  01   🚀 Get the Package  ](#get-the-package)
2. [  02   What Is Laravel Missing Translations?  ](#what-is-laravel-missing-translations)
3. [  03   Why This Package Exists  ](#why-this-package-exists)
4. [  04   Installation  ](#installation)
5. [  05   Basic Usage  ](#basic-usage)
6. [  06   Using the Default Application Locale  ](#using-the-default-application-locale)
7. [  07   Preview Missing Translations Without Writing Files  ](#preview-missing-translations-without-writing-files)
8. [  08   Scan All Existing Locale Files  ](#scan-all-existing-locale-files)
9. [  09   Remove Unused Translation Keys  ](#remove-unused-translation-keys)
10. [  10   JSON Output for CI Pipelines  ](#json-output-for-ci-pipelines)
11. [  11   Example GitHub Actions Workflow  ](#example-github-actions-workflow)
12. [  12   Supported Translation Calls  ](#supported-translation-calls)
13. [  13   Filament Support  ](#filament-support)
14. [  14   Filament Field Example  ](#filament-field-example)
15. [  15   Filament Table Column Example  ](#filament-table-column-example)
16. [  16   Filament Action Example  ](#filament-action-example)
17. [  17   Detecting Structural Filament Components  ](#detecting-structural-filament-components)
18. [  18   Auto-Generated Filament Labels  ](#auto-generated-filament-labels)
19. [  19   Avoiding Double Counting  ](#avoiding-double-counting)
20. [  20   Configuration  ](#configuration)
21. [  21   Customizing Scan Paths  ](#customizing-scan-paths)
22. [  22   Excluding Paths  ](#excluding-paths)
23. [  23   Excluding Dot Keys  ](#excluding-dot-keys)
24. [  24   Ignoring Package Translation Keys  ](#ignoring-package-translation-keys)
25. [  25   Excluding Keys by Pattern  ](#excluding-keys-by-pattern)
26. [  26   Sorting Keys  ](#sorting-keys)
27. [  27   JSON Encoding Flags  ](#json-encoding-flags)
28. [  28   Real Example  ](#real-example)
29. [  29   Suggested Workflow  ](#suggested-workflow)
30. [  30   When Should You Use This Package?  ](#when-should-you-use-this-package)
31. [  31   What This Package Is Not  ](#what-this-package-is-not)
32. [  32   Best Practices  ](#best-practices)
33. [  33   1. Use Dry Run Before Writing  ](#1-use-dry-run-before-writing)
34. [  34   2. Commit Translation Changes Separately  ](#2-commit-translation-changes-separately)
35. [  35   3. Avoid Dynamic Translation Keys When Possible  ](#3-avoid-dynamic-translation-keys-when-possible)
36. [  36   4. Use JSON Files for User-Facing Strings  ](#4-use-json-files-for-user-facing-strings)
37. [  37   5. Review Unused Keys Carefully  ](#5-review-unused-keys-carefully)
38. [  38   Why Filament Developers Will Like It  ](#why-filament-developers-will-like-it)
39. [  39   How It Works Internally  ](#how-it-works-internally)
40. [  40   Example Before and After  ](#example-before-and-after)
41. [  41   Final Thoughts  ](#final-thoughts)

       ![](https://cdn.msaied.com/xem4bYb57mM5X1cUyfeqhxyHCJnwKxE5w7lWegEh.png)

🚀 Get the Package
-----------------

**GitHub Repository:**
👉 **[EG-Mohamed/laravel-missing-translations](https://github.com/EG-Mohamed/laravel-missing-translations)**

Install with Composer:

```bash
composer require eg-mohamed/laravel-missing-translations --dev

```

Managing translations in Laravel projects can become painful as the application grows.

At the beginning, it feels simple:

```php
__('Save')
__('Cancel')
__('Dashboard')

```

But after weeks or months of development, translation strings start spreading across controllers, Blade views, Livewire components, Filament resources, table columns, actions, forms, and custom pages.

Sooner or later, you face the same problem:

> Some text exists in the code, but the translation key does not exist in your JSON language file.

That means untranslated labels, missing UI text, inconsistent language files, and manual cleanup work before every release.

[`eg-mohamed/laravel-missing-translations`](https://github.com/EG-Mohamed/laravel-missing-translations) solves this problem by scanning your Laravel project, detecting translation strings, and appending missing keys automatically to your JSON locale files.

---

What Is Laravel Missing Translations?
-------------------------------------

Laravel Missing Translations is a Laravel development tool that scans your project files for translation function calls and user-facing Filament labels, then compares the detected keys against your JSON language files.

For example, if your code contains:

```php
__('Create Account')

```

But your `lang/en.json` file does not contain:

```json
{
    "Create Account": ""
}

```

The package can automatically append it.

Instead of manually searching your codebase for missing translation strings, you can run one Artisan command and let the package detect them for you.

---

Why This Package Exists
-----------------------

Laravel already provides a clean translation system, but large projects often face a few practical issues.

You may add a new button:

```php
__('Export Report')

```

Then forget to add it to `lang/en.json`.

You may update a Filament resource:

```php
TextInput::make('email')
    ->label('Email Address')
    ->placeholder('Enter your email');

```

But those plain strings may not exist in your translation file.

You may remove old UI text from the application, but the old keys stay forever in your JSON file.

Over time, this creates messy translation files with:

- Missing keys
- Unused keys
- Duplicated manual work
- Untranslated UI labels
- Hard-to-review localization changes
- Poor release confidence in multilingual projects

This package helps make translation maintenance part of your normal development workflow.

---

Installation
------------

Install the package as a development dependency:

```bash
composer require eg-mohamed/laravel-missing-translations --dev

```

This is usually best installed with `--dev` because the package is mainly used during development, review, or CI checks.

Then publish the configuration file:

```bash
php artisan vendor:publish --tag="missing-translations-config"

```

This will publish the config file:

```php
config/laravel-missing-translations.php

```

---

Basic Usage
-----------

To scan your project and append missing keys to `lang/en.json`, run:

```bash
php artisan missing-translations en

```

The package will scan the configured paths, detect translation keys, compare them with the existing JSON locale file, and append any missing keys with an empty value.

Example result:

```json
{
    "Dashboard": "Dashboard",
    "Create Account": "",
    "Export Report": ""
}

```

Existing translations are not overwritten.

That is important because the package is designed to safely add missing keys without destroying existing work.

---

Using the Default Application Locale
------------------------------------

If you do not pass a locale, the command falls back to your Laravel application locale:

```bash
php artisan missing-translations

```

Internally, this uses:

```php
config('app.locale')

```

So if your application locale is `en`, the package will target:

```bash
lang/en.json

```

---

Preview Missing Translations Without Writing Files
--------------------------------------------------

Before modifying your language files, you can preview the missing keys using `--dry-run`:

```bash
php artisan missing-translations en --dry-run

```

This shows the missing keys without changing your files.

This is useful when you want to review the output first.

Example output:

```text
Keys scanned: 42 | Existing: 38 | Missing: 4
Dry run mode: no changes written.

```

A dry run is a good habit before running the command on a large project or before committing translation changes.

---

Scan All Existing Locale Files
------------------------------

If your project has multiple JSON locale files, you can scan all of them at once:

```bash
php artisan missing-translations --all

```

For example, if your project has:

```text
lang/en.json
lang/ar.json
lang/fr.json

```

The package can process all of them in one command.

This is helpful for multilingual applications where every supported locale should contain the same translation keys.

---

Remove Unused Translation Keys
------------------------------

Translation files often become polluted with old keys that are no longer used anywhere in the project.

You can remove unused keys with:

```bash
php artisan missing-translations en --remove-unused

```

This finds keys that exist in `lang/en.json` but are no longer referenced in the scanned files.

For safer review, combine it with `--dry-run`:

```bash
php artisan missing-translations en --remove-unused --dry-run

```

This lets you preview unused keys before actually removing them.

This is especially useful before major releases, UI rewrites, or after removing old features.

---

JSON Output for CI Pipelines
----------------------------

The package also supports JSON output:

```bash
php artisan missing-translations en --json

```

Example output:

```json
{
    "locale": "en",
    "existing_count": 38,
    "missing_count": 4,
    "missing_keys": [
        "New Key One",
        "New Key Two"
    ]
}

```

When used with `--remove-unused`, the output can also include unused keys:

```json
{
    "locale": "en",
    "existing_count": 38,
    "missing_count": 4,
    "missing_keys": [
        "New Key One"
    ],
    "unused_count": 2,
    "unused_keys": [
        "Old Key",
        "Stale Key"
    ]
}

```

This makes it easier to use the package in CI pipelines.

For example, you can fail a build if missing translations are detected.

---

Example GitHub Actions Workflow
-------------------------------

You can run the command during CI to detect missing translation keys before code is merged.

```yaml
name: Check Missing Translations

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  translations:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'

      - name: Install dependencies
        run: composer install --no-interaction --prefer-dist

      - name: Check missing translations
        run: php artisan missing-translations en --dry-run --json

```

Depending on your workflow, you can parse the JSON output and fail the pipeline if missing keys are found.

---

Supported Translation Calls
---------------------------

The package can detect common Laravel translation usage, including:

```php
__('Dashboard');

```

```php
trans('Dashboard');

```

```php
trans_choice('One user|Many users', $count);

```

```php
Lang::get('Dashboard');

```

```php
Lang::has('Dashboard');

```

```php
Lang::choice('One user|Many users', $count);

```

It also supports Blade translation directives:

```php
@lang('Dashboard')

```

```php
@choice('One user|Many users', $count)

```

This covers most normal Laravel translation usage across controllers, Blade views, components, services, and application classes.

---

Filament Support
----------------

One of the strongest features of this package is Filament support.

In many Filament projects, user-facing text is not always wrapped in `__()`.

For example:

```php
TextInput::make('email')
    ->label('Email Address')
    ->placeholder('Enter your email')
    ->helperText('Never shared');

```

These are real UI strings, but they are easy to miss when managing translation files manually.

Laravel Missing Translations can detect these strings automatically when Filament scanning is enabled.

---

Filament Field Example
----------------------

```php
use Filament\Forms\Components\TextInput;

TextInput::make('email')
    ->label('Email Address')
    ->placeholder('Enter your email')
    ->helperText('Never shared');

```

The package can detect:

```text
Email Address
Enter your email
Never shared

```

Then it can append them to your JSON locale file:

```json
{
    "Email Address": "",
    "Enter your email": "",
    "Never shared": ""
}

```

---

Filament Table Column Example
-----------------------------

```php
use Filament\Tables\Columns\TextColumn;

TextColumn::make('status')
    ->label('Current Status')
    ->tooltip('Last updated today');

```

Detected strings:

```text
Current Status
Last updated today

```

This is useful because table columns often contain labels, tooltips, descriptions, badges, and action text that should be translatable.

---

Filament Action Example
-----------------------

```php
use Filament\Actions\Action;

Action::make('approve')
    ->label('Approve')
    ->modalHeading('Confirm Approval')
    ->modalDescription('Are you sure you want to approve this item?')
    ->modalSubmitActionLabel('Yes, approve');

```

Detected strings:

```text
Approve
Confirm Approval
Are you sure you want to approve this item?
Yes, approve

```

This makes the package helpful for admin panels, dashboards, CRMs, SaaS back offices, and internal systems built with Filament.

---

Detecting Structural Filament Components
----------------------------------------

The package can also detect display labels from structural Filament components like:

```php
Section::make('Personal Information');

```

```php
Tab::make('Account Settings');

```

```php
Fieldset::make('Billing Details');

```

Detected strings:

```text
Personal Information
Account Settings
Billing Details

```

The package is careful not to treat normal field names as labels.

For example:

```php
TextInput::make('email');

```

This should not be treated as a translation string.

But this should be:

```php
Section::make('User Details');

```

Because it looks like a user-facing label.

---

Auto-Generated Filament Labels
------------------------------

Filament can automatically generate labels from field names.

For example:

```php
TextColumn::make('scheduled_time');

```

Filament may display it as:

```text
Scheduled time

```

The package can capture this generated label too.

Another example:

```php
TextInput::make('firstName');

```

Detected label:

```text
First name

```

This is a small but important feature because many Filament resources rely on auto-generated labels instead of explicit `->label()` calls.

---

Avoiding Double Counting
------------------------

If you already wrap a Filament label with Laravel’s translation helper, the package does not need to count it twice.

Example:

```php
TextInput::make('email')
    ->label(__('Email Address'));

```

In this case, the key is detected by the normal `__()` scanner.

The Filament scanner should not add another duplicate entry for the same string.

---

Configuration
-------------

After publishing the config file, you can customize how the scanner behaves.

Example:

```php
