PHPackages                             kanekescom/laravel-lingo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. kanekescom/laravel-lingo

ActiveLibrary[Localization &amp; i18n](/categories/localization)

kanekescom/laravel-lingo
========================

Laravel package to manage, sync, and analyze JSON translation files

v1.0.7(4mo ago)1881↓14.3%11MITPHPPHP ^8.3CI passing

Since Jan 6Pushed 2mo agoCompare

[ Source](https://github.com/kanekescom/laravel-lingo)[ Packagist](https://packagist.org/packages/kanekescom/laravel-lingo)[ Docs](https://github.com/kanekescom/laravel-lingo)[ Fund](https://s.id/hadibmac)[ GitHub Sponsors](https://github.com/sponsors/achmadhadikurnia)[ RSS](/packages/kanekescom-laravel-lingo/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (8)Dependencies (26)Versions (13)Used By (1)

Laravel Lingo
=============

[](#laravel-lingo)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e7dffbd923e11a3392877f241793ee4ac85099df7589053e4c97b248001dc4b5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b616e656b6573636f6d2f6c61726176656c2d6c696e676f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kanekescom/laravel-lingo)[![GitHub Tests Action Status](https://camo.githubusercontent.com/88aff4db3bf7c4d86aaa88a44b37d2e7066e16a10168a3c0c10fcf0dd37c5e25/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6b616e656b6573636f6d2f6c61726176656c2d6c696e676f2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/kanekescom/laravel-lingo/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/1c52e0485e4e557d4b564631612eb974c0ac3694e91ef288151a34d0f9453f16/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6b616e656b6573636f6d2f6c61726176656c2d6c696e676f2f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/kanekescom/laravel-lingo/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/9e43f081c38c4bb8ce81216197dcf608bbbd652401c5bc7727d21858901c808f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b616e656b6573636f6d2f6c61726176656c2d6c696e676f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/kanekescom/laravel-lingo)

Laravel package to manage, sync, and analyze JSON translation files.

Features
--------

[](#features)

- 🔍 **Scan** for translation keys in your codebase
- 📊 **Statistics** on translation progress
- 🔄 **Sync** translations with source files
- 🧹 **Clean** and sort translation files
- 🔧 **Artisan commands** for CLI management

---

How It Works
------------

[](#how-it-works)

### Key Concepts

[](#key-concepts)

#### Translation File Format

[](#translation-file-format)

Lingo works with Laravel's **JSON translation files** (not PHP array files). These files are located at `lang/{locale}.json`:

```
{
    "Hello": "Halo",
    "Welcome": "Selamat Datang",
    "Save": "Save"
}
```

#### Translation Status Detection

[](#translation-status-detection)

Lingo determines whether an item is translated or not by **comparing the key and value**:

- ✅ **Translated** → key ≠ value (e.g., `"Hello": "Halo"`)
- ⚠️ **Untranslated** → key = value (e.g., `"Save": "Save"`)
- 🗑️ **Empty** → value is empty string (e.g., `"Hello": ""`)

#### Duplicate Detection

[](#duplicate-detection)

Since PHP automatically overwrites duplicate keys during `json_decode()`, Lingo uses **regex on raw JSON content** to detect duplicates before parsing:

```
// Find all "key": patterns in raw JSON
preg_match_all('/"([^"]+)"\s*:/', $jsonContent, $matches);
```

### How Source Scanning Works

[](#how-source-scanning-works)

The `lingo:sync` command and `sync()` method work by scanning your source code to find translation keys. The scanning process uses **4 regex patterns** to detect Laravel translation function calls:

PatternDetected Examples`__('...')``__('Hello')`, `__("Welcome")``trans('...')``trans('Save')`, `trans("Cancel")``@lang('...')``@lang('Submit')` (Blade directive)`Lang::get('...')``Lang::get('Delete')`Scanning process:

1. **Resolve path** → Relative paths are resolved via `base_path()`, absolute paths are used directly if they exist
2. **Recursive scan** → For directories, all `.php` files are scanned recursively using `RecursiveIteratorIterator`
3. **Extract keys** → Each file's content is matched against the 4 regex patterns above
4. **Deduplicate** → All found keys are deduplicated using `array_unique()`

### Sync Workflow

[](#sync-workflow)

`lingo:sync` is the most powerful command. Here's how it works:

```
Source Files (*.php)              Translation File (lang/id.json)
┌─────────────────┐              ┌─────────────────────────┐
│ __('Hello')      │              │ "Hello": "Halo"         │
│ __('Welcome')    │  ──scan──▶   │ "Goodbye": "Selamat..."│
│ __('New Key')    │              │                         │
└─────────────────┘              └─────────────────────────┘
         │                                    │
         ▼                                    ▼
   Found keys:                         Existing keys:
   [Hello, Welcome, New Key]           [Hello, Goodbye]
         │                                    │
         └──────────────┬─────────────────────┘
                        ▼
              ┌─── Compare ───┐
              │               │
         Missing keys    Unused keys
         [New Key]       [Goodbye]
              │               │
              ▼               ▼
   Add "New Key":"New Key"   Remove "Goodbye"
              │               │
              └───────┬───────┘
                      ▼
            Final: lang/id.json
     ┌─────────────────────────┐
     │ "Hello": "Halo"         │
     │ "New Key": "New Key"    │
     │ "Welcome": "Welcome"    │
     └─────────────────────────┘

```

**Steps:**

1. **Scan** all given paths (default: `resources/views`)
2. **Collect** all translation keys found in source code
3. **Compare** with existing keys in the JSON file
4. **Add** missing keys (value = key, so they are easily identified as untranslated)
5. **Remove** keys that are no longer used in source code
6. **Save** the updated JSON file (sorted alphabetically)

### File Path Resolution

[](#file-path-resolution)

All commands accept either a **locale code** or a **direct file path**:

```
php artisan lingo:check id           # → Searches: lang/id.json, resources/lang/id.json
php artisan lingo:check lang/id.json # → Used directly as file path
```

File search order:

1. `base_path("lang/{locale}.json")`
2. `lang_path("{locale}.json")`
3. `resource_path("lang/{locale}.json")`

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

[](#installation)

```
composer require kanekescom/laravel-lingo
```

Usage
-----

[](#usage)

### Artisan Commands

[](#artisan-commands)

All commands accept an optional `locale` argument. If omitted, defaults to `config('app.locale')`.

```
# Check for issues (duplicates, untranslated)
php artisan lingo:check                   # Uses app locale
php artisan lingo:check id                # Specify locale

# Clean translation file (remove duplicates, empty, sort)
php artisan lingo:clean                   # Uses app locale
php artisan lingo:clean id                # Specify locale
php artisan lingo:clean id --keep-empty   # Keep empty values

# Show translation statistics
php artisan lingo:stats                   # Uses app locale
php artisan lingo:stats id --detailed     # With samples

# Sort keys alphabetically
php artisan lingo:sort                    # Uses app locale
php artisan lingo:sort id --desc          # Z-A order

# Sync with source files (find __(), trans(), @lang() calls)
php artisan lingo:sync                              # Scan resources/views (default)
php artisan lingo:sync id --path=resources/views    # Single path
php artisan lingo:sync id --path=resources/views --path=app/Filament  # Multiple paths
php artisan lingo:sync id --path=app/Http/Controllers/HomeController.php  # Single file
php artisan lingo:sync id --add                     # Only add missing keys
php artisan lingo:sync id --remove                  # Only remove unused keys
php artisan lingo:sync id --dry-run                 # Preview changes
```

> **Note:** All paths are relative to your application root. Both files and directories are supported.

### Programmatic Usage

[](#programmatic-usage)

```
use Kanekescom\Lingo\Facades\Lingo;

// Load by locale and manipulate
Lingo::locale('id')->sortKeys()->save();
Lingo::locale('id')->clean()->save();

// Sync with source files
Lingo::locale('id')->sync()->save();                                    // Default: resources/views
Lingo::locale('id')->sync('app/Filament')->save();                      // Single folder
Lingo::locale('id')->sync(['resources/views', 'app/Filament'])->save(); // Multiple paths
Lingo::locale('id')->sync('app/Http/Controllers/HomeController.php')->save(); // Single file

// Get data
$stats = Lingo::locale('id')->stats();
$untranslated = Lingo::locale('id')->onlyUntranslated()->get();

// Create from array (overwrites file)
lingo(['Hello' => 'Halo'], 'id')->save();

// Using helper with sync (cleaner syntax)
lingo()->sync(['resources/views', 'app/Filament'])->to('id')->save();

// Merge with existing translations
Lingo::locale('id')->merge(['Hello' => 'Halo'])->save();

// Without locale - fallback to app()->getLocale()
lingo(['Hello' => 'Halo'])->save();
```

### Available Methods

[](#available-methods)

#### Entry Points

[](#entry-points)

MethodDescription`Lingo::locale('id')`Load by locale → `lang/id.json``Lingo::fromFile($path)`Load from custom file path`Lingo::make($arr, $locale)`Create from array with optional locale`lingo($arr, 'id')`Helper: create from array with locale#### Chainable Methods

[](#chainable-methods)

MethodDescription`to($locale)`Set target locale for save()`sync($paths)`Sync with source files (accepts string, array, or null for default views). Supports files and directories.`sortKeys($asc)`Sort keys alphabetically (default: A-Z)`clean()`Remove empty values and sort keys`merge($arr)`Merge with another array`add($keys)`Add keys if not present`remove($keys)`Keep only keys in list`removeEmpty()`Remove empty values`onlyUntranslated()`Filter to untranslated items`onlyTranslated()`Filter to translated items`transform($fn)`Transform translations with callback`tap($fn)`Inspect translations without modifying#### Output Methods

[](#output-methods)

MethodDescription`save($path)`Save to file (path optional)`toJson()`Export as JSON string`get()`Get translations array`toArray()`Alias for get()`stats()`Get translation statistics`count()`Get number of translations`isEmpty()`Check if translations empty`isNotEmpty()`Check if translations not emptyTesting
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Achmad Hadi Kurnia](https://github.com/achmadhadikurnia)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance83

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Recently: every ~14 days

Total

8

Last Release

122d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/61120fbce750b7e0faa02a57002c4f0a0b378efc26b1b1f3bc19257f29e22fbe?d=identicon)[kanekescom](/maintainers/kanekescom)

---

Top Contributors

[![achmadhadikurnia](https://avatars.githubusercontent.com/u/4408971?v=4)](https://github.com/achmadhadikurnia "achmadhadikurnia (52 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")[![kanekesreal](https://avatars.githubusercontent.com/u/18681642?v=4)](https://github.com/kanekesreal "kanekesreal (1 commits)")

---

Tags

laravelkanekeskanekescomlaravel-lingo

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/kanekescom-laravel-lingo/health.svg)

```
[![Health](https://phpackages.com/badges/kanekescom-laravel-lingo/health.svg)](https://phpackages.com/packages/kanekescom-laravel-lingo)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k102.4M1.4k](/packages/spatie-laravel-permission)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M47](/packages/spatie-laravel-pdf)[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k11.2M100](/packages/dedoc-scramble)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.8k3](/packages/defstudio-telegraph)[spatie/laravel-passkeys

Use passkeys in your Laravel app

471890.7k39](/packages/spatie-laravel-passkeys)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.6k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
