PHPackages                             theupriser/laravel-unique-translation - 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. [Database &amp; ORM](/categories/database)
4. /
5. theupriser/laravel-unique-translation

ActiveLibrary[Database &amp; ORM](/categories/database)

theupriser/laravel-unique-translation
=====================================

Check if a translated value in a JSON column is unique in the database.

4.2(2y ago)04MITPHPPHP ^7.2|^8.0

Since Mar 11Pushed 2y agoCompare

[ Source](https://github.com/theupriser/laravel-unique-translation)[ Packagist](https://packagist.org/packages/theupriser/laravel-unique-translation)[ Fund](https://paypal.me/ivanvermeyen)[ Fund](https://ko-fi.com/ivanvermeyen)[ RSS](/packages/theupriser-laravel-unique-translation/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (3)Versions (3)Used By (0)

Laravel Unique Translation
==========================

[](#laravel-unique-translation)

IMPORTANT: March 2022
---------------------

[](#important-march-2022)

[![Support Ukraine](https://raw.githubusercontent.com/hampusborgos/country-flags/main/png100px/ua.png)](https://github.com/hampusborgos/country-flags/blob/main/png100px/ua.png)

It's horrible to see what is happening now in Ukraine, as Russian army is [bombarding houses, hospitals and kindergartens](https://twitter.com/DavidCornDC/status/1501620037785997316).

Please [check out supportukrainenow.org](https://supportukrainenow.org/) for the ways how you can help people there. Spread the word.

And if you are from Russia and you are against this war, please express your protest in some way. I know you can get punished for this, but you are one of the hopes of those innocent people.

---

[![GitHub release](https://camo.githubusercontent.com/11e9e235a666e1bb25be9c19cebf182e978f4fb9587d9d608fd07f1e756162c7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f636f64657a65726f2d62652f6c61726176656c2d756e697175652d7472616e736c6174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/codezero-be/laravel-unique-translation/releases)[![Laravel](https://camo.githubusercontent.com/f1c0bc3ecc3de5400058ae5c9dc25d93ae4542c26d742ce22bb9a5ff76f9087f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31302d7265643f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://laravel.com)[![License](https://camo.githubusercontent.com/0063019d85dd12a0cda6dec2fbfdad19acf300603f0b889fcfccffccf93d1053/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f636f64657a65726f2f6c61726176656c2d756e697175652d7472616e736c6174696f6e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/1156f322a4765f28cbd41a429d90c6136e0e544c3c7cdc1d1d404e015d50b3d6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f636f64657a65726f2d62652f6c61726176656c2d756e697175652d7472616e736c6174696f6e2f72756e2d74657374732e796d6c3f7374796c653d666c61742d737175617265266c6f676f3d676974687562266c6f676f436f6c6f723d7768697465266c6162656c3d7465737473)](https://github.com/codezero-be/laravel-unique-translation/actions)[![Code Coverage](https://camo.githubusercontent.com/cbf66a4f3fc0948b0b29184b3c487a05cd0ae7c7b3d61f1d175617697428f028/68747470733a2f2f696d672e736869656c64732e696f2f636f646163792f636f7665726167652f62623566383736666231613934616130613432366664333161323635366535622f6d61737465723f7374796c653d666c61742d737175617265)](https://app.codacy.com/gh/codezero-be/laravel-unique-translation)[![Code Quality](https://camo.githubusercontent.com/317eb1eed45e952b61e46b105bdbc0883af1c64cf517db5980bec9744678caff/68747470733a2f2f696d672e736869656c64732e696f2f636f646163792f67726164652f62623566383736666231613934616130613432366664333161323635366535622f6d61737465723f7374796c653d666c61742d737175617265)](https://app.codacy.com/gh/codezero-be/laravel-unique-translation)[![Total Downloads](https://camo.githubusercontent.com/07852a271ded20f778743fd7732fe3d77a13709cb7955d425b16a26b5f28c725/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636f64657a65726f2f6c61726176656c2d756e697175652d7472616e736c6174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/codezero/laravel-unique-translation)

[![ko-fi](https://camo.githubusercontent.com/1fedf764fa06114b797ee53e7506df10880abed6766f854202d758df1707969d/68747470733a2f2f7777772e6b6f2d66692e636f6d2f696d672f676974687562627574746f6e5f736d2e737667)](https://ko-fi.com/R6R3UQ8V)

#### Check if a translated value in a JSON column is unique in the database.

[](#check-if-a-translated-value-in-a-json-column-is-unique-in-the-database)

Imagine you want store a `slug` for a `Post` model in different languages.

The amazing [`spatie/laravel-translatable`](https://github.com/spatie/laravel-translatable) package makes this a cinch!

But then you want to make sure each translation is unique for its language.

That's where this package comes in to play.

This package also supports [`spatie/nova-translatable`](https://github.com/spatie/nova-translatable/) in case you are using [Laravel Nova](https://nova.laravel.com/) and [`filamentphp/spatie-laravel-translatable-plugin`](https://github.com/filamentphp/spatie-laravel-translatable-plugin) in case you are using [Filament](https://filamentphp.com/).

✅ Requirements
--------------

[](#-requirements)

- PHP ^7.2 or PHP ^8.0
- MySQL &gt;= 5.7
- [Laravel](https://laravel.com/) &gt;= 6
- [spatie/laravel-translatable](https://github.com/spatie/laravel-translatable) ^4.4|^5.0
- [spatie/nova-translatable](https://github.com/spatie/nova-translatable/) ^3.0
- [filamentphp/spatie-laravel-translatable-plugin](https://github.com/filamentphp/spatie-laravel-translatable-plugin) ^3.0

📦 Installation
--------------

[](#-installation)

Require the package via Composer:

```
composer require codezero/laravel-unique-translation

```

Laravel will automatically register the [ServiceProvider](https://github.com/codezero-be/laravel-unique-translation/blob/master/src/UniqueTranslationServiceProvider.php).

🛠 Usage
-------

[](#-usage)

For the following examples, I will use a `slug` in a `posts` table as the subject of our validation.

### ☑️ Validate a Single Translation

[](#️-validate-a-single-translation)

Your form can submit a single slug:

```

```

We can then check if it is unique **in the current locale**:

```
$attributes = request()->validate([
    'slug' => 'required|unique_translation:posts',
]);
```

You could also use the Rule instance:

```
use CodeZero\UniqueTranslation\UniqueTranslationRule;

$attributes = request()->validate([
    'slug' => ['required', UniqueTranslationRule::for('posts')],
]);
```

### ☑️ Validate an Array of Translations

[](#️-validate-an-array-of-translations)

Your form can also submit an array of slugs.

```

```

We need to validate the entire array in this case. Mind the `slug.*` key.

```
$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
    // or...
    'slug.*' => UniqueTranslationRule::for('posts'),
]);
```

### ☑️ Specify a Column

[](#️-specify-a-column)

Maybe your form field has a name of `post_slug` and your database field `slug`:

```
$attributes = request()->validate([
    'post_slug.*' => 'unique_translation:posts,slug',
    // or...
    'post_slug.*' => UniqueTranslationRule::for('posts', 'slug'),
]);
```

### ☑️ Specify a Database Connection

[](#️-specify-a-database-connection)

If you are using multiple database connections, you can specify which one to use by prepending it to the table name, separated by a dot:

```
$attributes = request()->validate([
    'slug.*' => 'unique_translation:db_connection.posts',
    // or...
    'slug.*' => UniqueTranslationRule::for('db_connection.posts'),
]);
```

### ☑️ Ignore a Record with ID

[](#️-ignore-a-record-with-id)

If you're updating a record, you may want to ignore the post itself from the unique check.

```
$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,{$post->id}",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->ignore($post->id),
]);
```

### ☑️ Ignore Records with a Specific Column and Value

[](#️-ignore-records-with-a-specific-column-and-value)

If your ID column has a different name, or you just want to use another column:

```
$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts,slug,ignore_value,ignore_column',
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->ignore('ignore_value', 'ignore_column'),
]);
```

### ☑️ Use Additional Where Clauses

[](#️-use-additional-where-clauses)

You can add 4 types of where clauses to the rule.

#### `where`

[](#where)

```
$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,value",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->where('column', 'value'),
]);
```

#### `whereNot`

[](#wherenot)

```
$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,!value",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNot('column', 'value'),
]);
```

#### `whereNull`

[](#wherenull)

```
$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,NULL",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNull('column'),
]);
```

#### `whereNotNull`

[](#wherenotnull)

```
$attributes = request()->validate([
    'slug.*' => "unique_translation:posts,slug,null,null,column,NOT_NULL",
    // or...
    'slug.*' => UniqueTranslationRule::for('posts')->whereNotNull('column'),
]);
```

### ☑️ Laravel Nova

[](#️-laravel-nova)

If you are using [Laravel Nova](https://nova.laravel.com/) in combination with [`spatie/nova-translatable`](https://github.com/spatie/nova-translatable/), then you can add the validation rule like this:

```
Text::make(__('Slug'), 'slug')
  ->creationRules('unique_translation:posts,slug')
  ->updateRules('unique_translation:posts,slug,{{resourceId}}');
```

### ☑️ Filament

[](#️-filament)

If you are using [Filament](https://filamentphp.com/) in combination with [`filamentphp/spatie-laravel-translatable-plugin`](https://github.com/filamentphp/spatie-laravel-translatable-plugin), then you can add the validation rule like this:

```
TextInput::make('slug')
  ->title(__('Slug'))
  ->rules([
    UniqueTranslationRule::for('posts', 'slug')
  ])
```

```
TextInput::make('slug')
  ->title(__('Slug'))
  ->rules([
    fn (Get $get) => UniqueTranslationRule::for('posts', 'slug')->ignore($get('id'))
  ])
```

🖥 Example
---------

[](#-example)

Your existing `slug` column (JSON) in a `posts` table:

```
{
  "en":"not-abc",
  "nl":"abc"
}
```

Your form input to create a new record:

```

```

Your validation logic:

```
$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
]);
```

The result is that `slug[en]` is valid, since the only `en` value in the database is `not-abc`.

And `slug[nl]` would fail, because there already is a `nl` value of `abc`.

⚠️ Error Messages
-----------------

[](#️-error-messages)

You can pass your own error messages as normal.

When validating a single form field:

```

```

```
$attributes = request()->validate([
    'slug' => 'unique_translation:posts',
], [
    'slug.unique_translation' => 'Your custom :attribute error.',
]);
```

In your view you can then get the error with `$errors->first('slug')`.

Or when validation an array:

```

```

```
$attributes = request()->validate([
    'slug.*' => 'unique_translation:posts',
], [
    'slug.*.unique_translation' => 'Your custom :attribute error.',
]);
```

In your view you can then get the error with `$errors->first('slug.en')` (`en` being your array key).

🚧 Testing
---------

[](#-testing)

```
vendor/bin/phpunit

```

☕️ Credits
----------

[](#️-credits)

- [Ivan Vermeyen](https://byterider.io)
- [All contributors](../../contributors)

🔓 Security
----------

[](#-security)

If you discover any security related issues, please [e-mail me](mailto:ivan@codezero.be) instead of using the issue tracker.

📑 Changelog
-----------

[](#-changelog)

A complete list of all notable changes to this package can be found on the [releases page](https://github.com/codezero-be/laravel-unique-translation/releases).

📜 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](https://github.com/codezero-be/laravel-unique-translation/blob/master/LICENSE.md) for more information.

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 91% 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

Unknown

Total

1

Last Release

792d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/16fd65986cc1d73583eb6e7b995587aaa172b9ebfedbca90c6f20a0a873e6913?d=identicon)[theupriser](/maintainers/theupriser)

---

Top Contributors

[![ivanvermeyen](https://avatars.githubusercontent.com/u/3598622?v=4)](https://github.com/ivanvermeyen "ivanvermeyen (91 commits)")[![theupriser](https://avatars.githubusercontent.com/u/5661837?v=4)](https://github.com/theupriser "theupriser (2 commits)")[![EcoinTest](https://avatars.githubusercontent.com/u/153815470?v=4)](https://github.com/EcoinTest "EcoinTest (2 commits)")[![bkintanar](https://avatars.githubusercontent.com/u/685928?v=4)](https://github.com/bkintanar "bkintanar (1 commits)")[![ctf0](https://avatars.githubusercontent.com/u/7388088?v=4)](https://github.com/ctf0 "ctf0 (1 commits)")[![Okipa](https://avatars.githubusercontent.com/u/5328934?v=4)](https://github.com/Okipa "Okipa (1 commits)")[![Tahiaji](https://avatars.githubusercontent.com/u/2605542?v=4)](https://github.com/Tahiaji "Tahiaji (1 commits)")[![dvandal](https://avatars.githubusercontent.com/u/36455367?v=4)](https://github.com/dvandal "dvandal (1 commits)")

---

Tags

phpjsonlaravelvalidatorvalidationlanguagedatabasetranslationmysqlruleunique

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/theupriser-laravel-unique-translation/health.svg)

```
[![Health](https://phpackages.com/badges/theupriser-laravel-unique-translation/health.svg)](https://phpackages.com/packages/theupriser-laravel-unique-translation)
```

###  Alternatives

[codezero/laravel-unique-translation

Check if a translated value in a JSON column is unique in the database.

186965.1k7](/packages/codezero-laravel-unique-translation)[astrotomic/laravel-translatable

A Laravel package for multilingual models

1.4k7.7M114](/packages/astrotomic-laravel-translatable)[awssat/laravel-sync-migration

Laravel tool helps to sync migrations without refreshing the database

10923.2k](/packages/awssat-laravel-sync-migration)[tomatophp/filament-translations

Manage your translation with DB and cache, you can scan your languages tags like trans(), \_\_(), and get the string inside and translate them use UI.

6230.1k3](/packages/tomatophp-filament-translations)[moharrum/laravel-adminer

Adminer database management tool for your Laravel application.

451.0k](/packages/moharrum-laravel-adminer)

PHPackages © 2026

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