PHPackages                             relodev/laravel-translatable - 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. relodev/laravel-translatable

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

relodev/laravel-translatable
============================

Lightweight bilingual (FR/EN) translation for Laravel models and views

v2.0.0(1mo ago)681MITPHPPHP ^8.1

Since Apr 11Pushed 1mo agoCompare

[ Source](https://github.com/ReloDev/relodev-laravel-translatable)[ Packagist](https://packagist.org/packages/relodev/laravel-translatable)[ RSS](/packages/relodev-laravel-translatable/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (3)Used By (0)

Laravel Relodev Translatable
============================

[](#laravel-relodev-translatable)

A lightweight Laravel package to handle multilingual Eloquent models, **with no heavy dependencies** and a **fully configurable primary language**.

> **v2.0** — The primary language is no longer hardcoded to `fr`. You define your own base language and all secondary languages, at any point during development.

---

Table of Contents
-----------------

[](#table-of-contents)

- [How it works](#how-it-works)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Active locale detection](#active-locale-detection)
- [Usage](#usage)
- [Adding a language during development](#adding-a-language-during-development)
- [Available model methods](#available-model-methods)
- [Artisan commands](#artisan-commands)
- [Package structure](#package-structure)
- [Changelog](#changelog)

---

How it works
------------

[](#how-it-works)

The package is built on two pillars:

- **Dynamic data** — Suffixed database columns (`name_en`, `name_es`, …) and an Eloquent trait that automatically returns the right value based on the active locale. The primary language uses the **unsuffixed column** (`name`), ensuring full compatibility with your existing code.
- **Views &amp; messages** — Standard Laravel translation files under `lang/{locale}/`, unchanged.

An **automatic middleware** is included to detect and apply the active locale with no extra setup.

### Column naming convention

[](#column-naming-convention)

LocaleTypeDatabase column`fr` (primary)base language`name` (no suffix)`en` (secondary)translation`name_en``es` (secondary)translation`name_es``de` (secondary)translation`name_de`---

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, 12 or 13

---

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

[](#installation)

```
composer require relodev/laravel-translatable
```

The `ServiceProvider` and middleware are auto-registered by Laravel. No manual setup required.

---

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

[](#configuration)

Publish the configuration file:

```
php artisan vendor:publish --tag=translatable-config
```

This creates `config/translatable.php`:

```
return [
    /*
     | Primary language of your project.
     | The unsuffixed column (e.g. `name`) will always hold this language.
     */
    'primary_locale' => env('TRANSLATABLE_PRIMARY', 'fr'),

    /*
     | Secondary languages.
     | Each language listed here will generate a suffixed column (e.g. name_en).
     | You can add more at any point during development.
     */
    'secondary_locales' => ['en'],

    /*
     | Fallback locale used when the active locale has no value.
     | Defaults to primary_locale when set to null.
     */
    'fallback_locale' => null,
];
```

KeyDescription`primary_locale`The native language of your project. The base column (no suffix) holds this language.`secondary_locales`All other supported languages. Each one generates suffixed columns.`fallback_locale`Fallback when the active locale has no value. `null` → falls back to `primary_locale`.### Configuration examples

[](#configuration-examples)

**English-first project with FR and ES translations:**

```
'primary_locale'    => 'en',
'secondary_locales' => ['fr', 'es'],
```

**Trilingual project FR / EN / AR:**

```
'primary_locale'    => 'fr',
'secondary_locales' => ['en', 'ar'],
```

**Via `.env`:**

```
TRANSLATABLE_PRIMARY=en
TRANSLATABLE_FALLBACK=en
```

---

Active locale detection
-----------------------

[](#active-locale-detection)

The included middleware automatically resolves the locale in this order:

```
1. Route segment   → /fr/... or /en/...
2. Session         → set via language switch button
3. Primary locale  → value of primary_locale

```

### Language switch button

[](#language-switch-button)

Add this route to `routes/web.php`:

```
Route::get('/language/{locale}', function ($locale) {
    $all = array_merge(
        [config('translatable.primary_locale')],
        config('translatable.secondary_locales', [])
    );
    if (in_array($locale, $all)) {
        session(['locale' => $locale]);
        app()->setLocale($locale);
    }
    return back();
})->name('lang.switch');
```

In your views:

```
FR
EN
ES
```

---

Usage
-----

[](#usage)

### 1. Generate the initial migration

[](#1-generate-the-initial-migration)

```
php artisan translatable:migration {table} {columns...}
```

**Example** — project with `primary_locale = 'fr'` and `secondary_locales = ['en', 'es']`:

```
php artisan translatable:migration categories name description
```

Generated migration:

```
// `name` column → already exists, holds French (primary)
$table->text('name_en')->nullable();          // English
$table->text('name_es')->nullable();          // Spanish
$table->text('description_en')->nullable();
$table->text('description_es')->nullable();
```

Then:

```
php artisan migrate
```

> **Note:** Primary language columns (e.g. `name`, `description`) are your existing columns. The package does not touch them.

### 2. Set up the model

[](#2-set-up-the-model)

```
